Если у вас много файлов в проекте,их не нужно перекомпилировать все ,если изменения сделаны в одном.
В следующем примере показано,что цель pgm зависит от a.o и b.o , а те в свою очередь зависят от
a.c и b.c :
pgm: a.o b.o
cc -Aa a.o b.o -o pgm
a.o: incl.h a.c
cc -Aa -c a.c
b.o: incl.h b.c
cc -Aa -c b.c
Следующий пример для программы dtree . Вначале создаются несколько переменных .
DEFS = -Aa -DSYSV
CFLAGS = $(DEFS) -O
LDFLAGS =
LIBS = -lmalloc -lXm -lXt -lX11 -lm
BINDIR = /usr/local/bin/X11
MANDIR = /usr/local/man/man1
OBJECTS_A = dtree.o Arc.o Graph.o #using XmGraph
ARCH_FILES = dtree.1 dtree.c Makefile Dtree Tree.h TreeP.h \
dtree-i.h Tree.c Arc.c Arc.h ArcP.h Graph.c Graph.h GraphP.h
dtree: $(OBJECTS_A)
$(CC) -o dtree $(LDFLAGS) $(OBJECTS_A) $(LIBS)
Arc.o: Arc.c
$(CC) -c $(CFLAGS) Arc.c
Graph.o: Graph.c
$(CC) -c $(CFLAGS) Graph.c
dtree.o: dtree.c
$(CC) -o dtree.o -c $(CFLAGS) -DTREE dtree.c
install: dtree dtree.1
cp dtree $(BINDIR)
cp dtree.1 $(MANDIR)
clean:
rm -f dtree *.o core tags a.out
Linked Lists
#include < stdio.h>
typedef struct _list_item {
int val;
struct _list_item *next;
} list_item;
/* prototypes */
list_item *add_list_item(list_item *entry, int value);
void print_list_items(void);
list_item *head=NULL;
list_item *tail=NULL;
main(int argc, char *argv[])
{
tail=add_list_item(tail,5);
tail=add_list_item(tail,7);
tail=add_list_item(tail,2);
print_list_items();
}
list_item *add_list_item(list_item *entry, int value)
{
list_item *new_list_item;
new_list_item=(list_item*)malloc(sizeof(list_item));
if (entry==NULL){
head=new_list_item;
printf("First list_item in list\n");
}
else {
entry->next = new_list_item;
printf("Adding %d to list. Last value was %d \n",value,entry->val);
}
new_list_item->val = value;
new_list_item->next = NULL;
return new_list_item;
}
void print_list_items(void)
{
list_item *ptr_to_list_item;
for (ptr_to_list_item= head;ptr_to_list_item!= NULL;
ptr_to_list_item=ptr_to_list_item->next) {
printf("Value is %d \n", ptr_to_list_item->val);
}
}
Еще один пример double linked list :
#include< stdio.h>
int main() {
typedef struct person_struct {
/* Data elements */
char* name;
int age;
/* Link elements */
struct person_struct *next;
struct person_struct *prev;
} person_t;
person_t *start;
person_t *pers;
person_t *temp;
char *names[] = {"Linus Torvalds", "Alan Cox", "Rik van Riel"};
int ages[] = {30, 31, 32};
int count; /* Temporary counter */
start = (person_t*)malloc(sizeof(person_t));
start->name = names[0];
start->age = ages[0];
start->prev = NULL;
start->next = NULL;
pers = start;
for (count=1; count < 3; count++) {
temp = (person_t*)malloc(sizeof(person_t));
temp->name = names[count];
temp->age = ages[count];
pers->next = temp;
temp->prev = pers;
pers = temp;
}
temp->next = NULL;
printf("Data structure created\n");
return 0;
}
Указатели
#include "stdio.h"
char *words[]={"apple","belt","corpus","daffodil","epicycle","floppy",
"glands","handles","interfere","jumble","kick","lustiness",
"glands","handles","interfere","jumble","kick","lustiness",
"glands","handles","interfere","jumble","kick","lustiness",
"glands","handles","interfere","jumble","kick","lustiness",
"glands","handles","interfere","jumble","kick","lustiness",
"glands","handles","interfere","jumble","kick","lustiness",
"glands","handles","interfere","jumble","kick","lustiness",
"glands","handles","interfere","jumble","kick","lustiness",
"glands","handles","interfere","jumble","kick","lustiness",
"mangleworsel","nefarious","oleangeous","parsimonious",NULL};
void slow(void)
{
int i,j,count=0;
for (i=0; words[i] != NULL ; i=i+1)
for (j=0; j <= strlen(words[i]) ; j=j+1)
if(words[i][j] == words[i][j+1])
count= count+1;
printf("count %d\n",count);
}
void fast(void)
{
register char **cpp; /* cpp is an array of pointers to chars */
register char *cp;
register int count=0;
for (cpp= words; *cpp ; cpp++) /* loop through words. The final
NULL pointer terminates the loop */
for (cp = *cpp ; *cp ; cp++) /* loop through letters of a word.
The final '\0' terminates the loop */
if(*cp == *(cp+1))
count++;
printf("count %d\n",count);
}
/*count the number of double letters, first using arrays, then pointers */
void main(int argc, char *argv[]){
slow();
fast();
}
A data filter
Программа распечатывает содержимое ASCI-файла,состоящего из последовательности чисел.
#include < stdio.h>
#include < stdlib.h>
int answer;
float offset;
float scale;
char buf[BUFSIZ];
int xcoord = 0;
char *cptr;
int transform(int a)
{
return a * scale + offset + 0.5;
}
char* eat_space(char *cptr){
/* This while loop skips to the nonspace after spaces.
If this is the end of the line, return NULL
`While a space, keep going'
*/
while (*cptr ==' '){
if (*cptr == '\0')
return NULL;
else
cptr++;
}
return cptr;
}
char * next_next_num(char *cptr){
/* This while loop skips to the 1st space after a number.
If this is the end of the line, return NULL
`While NOT a space, keep going'
*/
while (*cptr !=' '){
if (*cptr == '\0')
return NULL;
else
cptr++;
}
/* Now move to the start of the next number */
return eat_space(cptr);
}
int main(int argc, char *argv[])
{
offset = 2.3;
scale = 7.5;
while(1){
/* if we haven't reached the end of the file ...*/
if(fgets(buf, BUFSIZ,stdin)!= NULL){
/* initialise cptr to point to the first number ...*/
cptr = eat_space(buf);
do{
/* convert the representation of the num into an int */
sscanf(cptr,"%d", &num);
/* print x and y to stdout */
printf("%d %d\n",xcoord, tranform(num));
/* skip to the start of the next number on the line */
cptr=next_next_num(cptr);
xcoord++;
}while ( cptr!=NULL);
}
else{
exit(0);
}
}
}
Чтение директорий.
#include < stdio.h>
#include < sys/types.h>
#include < dirent.h>
#include < sys/stat.h>
#define REQUEST_DIR "/"
int main(int argc, char *argv[]){
FILE *fp;
DIR *dirp;
struct dirent *dp;
struct stat buf;
dirp = opendir(REQUEST_DIR);
chdir(REQUEST_DIR);
/* Look at each entry in turn */
while ((dp = readdir(dirp)) != NULL) {
/* Now stat the file to get more information */
if (stat(dp->d_name, &buf) == -1)
perror("stat\n");
if (S_ISDIR(buf.st_mode))
printf("%s is a directory\n", dp->d_name);
else if (S_ISREG(buf.st_mode))
printf("%s is a regular file\n", dp->d_name);
}
(void) closedir(dirp);
}
Многомерные массивы.
Элементы массива aai[4][2] хранятся в памяти в следующем порядке :
aai[0][0]aai[0][1]aai[1][0]aai[1][1]
aai[2][0]aai[2][1]aai[3][0]aai[3][1]
При этом
aai[1][2] == *( (aai[1])+2) == *(*(aai+1)+2)
Realloc
#include < stdlib.h>
int *array = NULL;
int nalloc = 0;
int num_of_elements = 0;
install(x)
int x;
{
if(num_of_elements >= nalloc){
/* We're out of space. Reallocate with space for 10 more ints */
nalloc += 10;
array = (int *)realloc((char *)array, nalloc * sizeof(int));
if(array == NULL){
fprintf(stderr, "out of memory with %d elements\n",
num_of_elements);
exit(1);
}
}
array[num_of_elements++] = x;
}
Вариант для 2-мерного массива:
/* create an array of pointers */
int **array = (int **)malloc(nrows * sizeof(int *));
if (array == NULL){
fprintf(stderr,"Out of memory\n");
exit(1);
}
for(i = 0; i < nrows; i++){
/* create space for an array of ints */
array[i] = (int *)malloc(ncolumns * sizeof(int));
if (array[i] == NULL){
fprintf(stderr,"Out of memory\n");
exit(1);
}
}
Signals and error
Программа может получать различные сигналы(или прерывания) . Их можно обрабатывать или игнорировать.
#include < signal.h>
/* this will ignore control-C */
signal(SIGINT, SIG_IGN);
В следующем примере используется прерывание по таймеру.
Сначала нужно вызвать Timer , который вызовет прерывание :
#include < signal.h>
static void onalarm(void)
{
something();
signal(SIGALRM,SIG_DFL);
}
...
void Timer(int n) /* waits for 'n' milliseconds */
{
long usec;
struct itimerval it;
if (!n) return;
usec = (long) n * 1000;
memset(&it, 0, sizeof(it));
if (usec>=1000000L) { /* more than 1 second */
it.it_value.tv_sec = usec / 1000000L;
usec %= 1000000L;
}
it.it_value.tv_usec = usec;
signal(SIGALRM,onalarm);
setitimer(ITIMER_REAL, &it, (struct itimerval *)0);
}
|