, ( - ). scanf(), . - . 5.3. , . 5.4. , - . - strcmp(). 5.5. , - , , . , . 5.6. , - : , , ; ; ; , ; ; . 5.7. ? struct man { char name[20]; int salary; } workers[] = { { "", 200 }, { "", 180 }, { "", 150 } }, *wptr, chief = { "", 550 }; main(){ struct man *ptr, *cptr, save; ptr = wptr = workers + 1; cptr = &chief; save = workers[2]; workers[2] = *wptr; *wptr = save; wptr++; ptr--; ptr->salary = save.salary; printf( "%c %s %s %s %s\n%d %d %d %d\n%d %d %c\n", *workers[1].name, workers[2].name, cptr->name, ptr[1].name, save.name, wptr->salary, chief.salary, (*ptr).salary, workers->salary, wptr - ptr, wptr - workers, *ptr->name ); } : 180 550 150 150 2 2 5.8. : #include <stdio.h> struct man{ . , 1992-95 - 177 - UNIX char *name, town[4]; int salary; int addr[2]; } men[] = { { "", "Msc", 100, { 12, 7 } }, { "", "Len", 120, { 6, 51 } }, { "", "Rig", 140, { 23, 84 } }, { NULL, "" , -1, { -1, -1 } } }; main(){ struct man *ptr, **ptrptr; int i; ptrptr = &ptr; *ptrptr = &men[1]; /* men+1 */ printf( "%s %d %s %d %c\n", ptr->name, ptr->salary, ptr->town, ptr->addr[1], ptr[1].town[2] ); (*ptrptr)++; /* *ptr men[0] */ men[0].name = ptr->name; /* (char *) #1 */ strcpy( men[0].town, ptr->town ); /* char [] #2 */ men[0].salary = ptr->salary; /* int #3 */ for( i=0; i < 2; i++ ) men[0].addr[i] = ptr->addr[i]; /* #4 */ /* */ for(ptr=men; ptr->name; ptr++ ) printf( "%s %s %d\n", ptr->name, ptr->town, ptr->addr[0]); } : 1) (ptrptr). 2) , (int, char, long, ..., ) (. #1 #3). () , - ( #4). ( ) strcpy ( #2). , . , : men[0]= *ptr; 3) printf() , - . 4) (- ), NULL name - . 5) town 3 , 4 . , "Msc" 3, 4 - : 'M','s','c','\0'. . () ( men ): . , 1992-95 - 178 - UNIX --ptr-- --ptrptr-- ptr | * |<------|---* | ---|--- ---------- | / =========men[0]== / men:|name | *---|-----> "" | |---------------| | |town |M|s|c|\0| | |---------------| | |salary| 100 | | |---------------| | |addr | 12 | 7 | \ ----------------- \ =========men[1]== \-->|name | *---|-----> "" ............ 5.9. " ", . . 5.10. ( ) , . , - , . ? int data[2]; data[0] = my_key; data[1] = my_value; write(fd, (char *) data, 2 * sizeof(int)); -, ( , 3 2 3). write(fd, (char *) data, sizeof data); , data, &data? (: ). -, , ? struct _data { int key; int value; } data; data.key = my_key; data.value = my_value; write(fd, &data, sizeof data); 5.11. ? - . #include <stdio.h> struct lnk{ char c; . , 1992-95 - 179 - UNIX struct lnk *prev, *next; } chain[20], *head = chain; add(c) char c; { head->c = c; head->next = head+1; head->next->prev = head; head++; } main(){ char *s = "012345"; while( *s ) add( *s++ ); head->c = '-'; head->next = (struct lnk *)NULL; chain->prev = chain->next; while( head->prev ){ putchar( head->prev->c ); head = head->prev; if( head->next ) head->next->prev = head->next->next; } } 5.12. , , - . - '\n'. '+'. . . / . : struct elem{ char letter; /* */ char *word; /* */ struct elem *prev; /* */ struct elem *next; /* */ }; struct elem *head, /* */ *tail, /* */ *ptr, /* */ *prev; /* */ int c, cmp; ... while((c = getchar()) != '\n' ) Insert(c, tail); for(ptr=head; ptr != NULL; ptr=ptr->next) printf(" %c\n", ptr->letter); , calloc(), malloc(), '\0' (0, NULL). : extern char *calloc(); /* c */ struct elem *NewElem(c) char c; { struct elem *p = (struct elem *) calloc(1, sizeof(struct elem)); /* calloc , * prev next */ p->letter = c; return p; } . , 1992-95 - 180 - UNIX /* ptr ( - tail) */ Insert(c, ptr) char c; struct elem *ptr; { struct elem *newelem = NewElem(c), *right; if(head == NULL){ /* */ head=tail=newelem; return; } right = ptr->next; ptr->next = newelem; newelem->prev = ptr; newelem->next = right; if( right ) right->prev = newelem; else tail = newelem; } /* ptr */ Delete( ptr ) struct elem *ptr; { struct elem *left=ptr->prev, *right=ptr->next; if( right ) right->prev = left; if( left ) left->next = right; if( tail == ptr ) tail = left; if( head == ptr ) head = right; free((char *) ptr); } . struct elem *NewElem(char *s) { struct elem *p = (struct elem *) calloc(1, sizeof(struct elem)); p->word = strdup(s); return p; } void DeleteElem(struct elem *ptr){ free(ptr->word); free(ptr); } :  . strcmp(), : struct elem *newelem; if (head == NULL){ /* */ head = tail = NewElem(_); return; } /* */ for(cmp= -1, ptr=head, prev=NULL; ptr; prev=ptr, ptr=ptr->next ) if((cmp = strcmp(_, ptr->word)) <= 0 ) break; cmp==0, . cmp < 0, ptr ,  _, prev -  (prev==NULL , ); .. prev ptr. cmp > 0, - ( ptr==NULL). head ==> "a" ==> "b" ==> "d" ==> NULL | | prev "c" ptr . , 1992-95 - 181 - UNIX if(cmp == 0) return; /* */ newelem = NewElem( _ ); if(prev == NULL){ /* */ newelem->next = head; newelem->prev = NULL; head->prev = newelem; head = newelem; } else if(ptr == NULL){ /* */ newelem->next = NULL; newelem->prev = tail; tail->next = newelem; tail = newelem; } else { /* prev ptr */ newelem->next = ptr; newelem->prev = prev; prev->next = newelem; ptr ->prev = newelem; } 5.13. struct complex { double re, im; }; , : struct complex add( c1, c2 ) struct complex c1, c2; { struct complex sum; sum.re = c1.re + c2.re; sum.im = c1.im + c2.im; return sum; } struct complex a = { 12.0, 14.0 }, b = { 13.0, 2.0 }; main(){ struct complex c; c = add( a, b ); printf( "(%g,%g)\n", c.re, c.im ); } 5.14. , - . : - typedef struct { int ai[5]; } intarray5; intarray5 a, b = { 1, 2, 3, 4, 5 }; a = b; : . , 1992-95 - 182 - UNIX a.ai[2] = 14; for(i=0; i < 5; i++) printf( "%d\n", a.ai[i] );  . : typedef int ARR16[16]; ARR16 d; void f(ARR16 a){ printf( "%d %d\n", a[3], a[15]); a[3] = 2345; } void main(void){ d[3] = 9; d[15] = 98; f(d); printf("Now it is %d\n", d[3]); } printf "Now it is 2345", f  - , ; a[3]=2345  . , , - , ( , ). 5.15.   - ,  - . :_. ( ). struct XYZ { /* unsigned */ unsigned x:2; /* 0 .. 2**2 - 1 */ unsigned y:5; /* 0 .. 2**5 - 1 */ unsigned z:1; /* YES=1 NO=0 */ } xyz; main(){ printf("%u\n", sizeof(xyz)); /* == sizeof(int) */ xyz.z = 1; xyz.y = 21; xyz.x = 3; printf("%u %u %u\n", xyz.x, ++xyz.y, xyz.z); /* * 2**_ - 1 */ xyz.y = 32 /* */ + 7; xyz.x = 16+2; xyz.z = 11; printf("%u %u %u\n", xyz.x, xyz.y, xyz.z); /* 2 7 1 */ } 1 : #define FLAG1 01 #define FLAG2 02 #define FLAG3 04 int x; /* */ x |= FLAG1; x &= ~FLAG2; if(x & FLAG3) ...; struct flags { unsigned flag1:1, flag2:1, flag3:1; } x; x.flag1 = 1; x.flag2 = 0; if( x.flag3 ) ...; . , 1992-95 - 183 - UNIX , (.. ). "&", ! 5.16. . - . : , ! #include <stdio.h> #define SZ 5 extern char *malloc(); #define VARTYPE char struct obj { struct header { /* */ int cls; int size; /* */ } hdr; VARTYPE body [1]; /* : */ } *items [SZ]; /* */ #define OFFSET(field, ptr) ((char *) &ptr->field - (char *)ptr) int body_offset; /* */ struct obj *newObj( int cl, char *s ) { char *ptr; struct obj *op; int n = strlen(s); /* ( VARTYPE) */ int newsize = sizeof(struct header) + n * sizeof(VARTYPE); printf("[n=%d newsize=%d]\n", n, newsize); /* newsize = (sizeof(struct obj) - sizeof(op->body)) + n * sizeof(op->body); , struct(obj) sizeof(int). , op->body. newsize = body_offset + n * sizeof(op->body); */ /* */ ptr = (char *) malloc(newsize); /* */ op = (struct obj *) ptr; op->hdr.cls = cl; op->hdr.size = n; strncpy(op->body, s, n); return op; } . , 1992-95 - 184 - UNIX void printobj( struct obj *p ) { register i; printf( "OBJECT(cls=%d,size=%d)\n", p->hdr.cls, p->hdr.size); for(i=0; i < p->hdr.size; i++ ) putchar( p->body[i] ); putchar( '\n' ); } char *strs[] = { "a tree", "a maple", "an oak", "the birch", "the fir" }; int main(int ac, char *av[]){ int i; printf("sizeof(struct header)=%d sizeof(struct obj)=%d\n", sizeof(struct header), sizeof(struct obj)); { struct obj *sample; printf("offset(cls)=%d\n", OFFSET(hdr.cls, sample)); printf("offset(size)=%d\n", OFFSET(hdr.size, sample)); printf("offset(body)=%d\n", body_offset = OFFSET(body, sample)); } for( i=0; i < SZ; i++ ) items[i] = newObj( i, strs[i] ); for( i=0; i < SZ; i++ ){ printobj( items[i] ); free( items[i] ); items[i] = NULL; } return 0; } 5.17. , "". , , . . UNIX : , ( ). /* , , * .. "" - , "" - . * ! * . */ #include <stdio.h> extern char *malloc(), *gets(); #define MAX 3 /* */ int nelems = 0; /* */ struct elem { /* */ char *key; /* - - */ struct elem *next; /* */ /* ... - ... */ } *head; /* */ void printList(), addList(char *), forget(); . , 1992-95 - 185 - UNIX void main(){ /* a b c d b a c */ char buf[128]; while(gets(buf)) addList(buf), printList(); } /* */ void printList(){ register struct elem *ptr; printf( " %d \n", nelems ); for(ptr = head; ptr != NULL; ptr = ptr->next ) printf( "\t\"%s\"\n", ptr->key ); } /* */ void addList(char *s) { register struct elem *p, *new; /* - */ for(p = head; p != NULL; p = p->next ) if( !strcmp(s, p->key)){ /* . */ if( head == p ) return; /* */ /* */ new = p; /* */ for(p = head; p->next != new; p = p->next ); /* p new */ p->next = new->next; goto Insert; } /* */ if( nelems >= MAX ) forget(); /* */ if((new = (struct elem *) malloc(sizeof(struct elem)))==NULL) goto bad; if((new->key = malloc(strlen(s) + 1)) == NULL) goto bad; strcpy(new->key, s); nelems++; Insert: new->next = head; head = new; return; bad: printf( " \n" ); exit(13); } /* */ void forget(){ struct elem *prev = head, *tail; if( head == NULL ) return; /* */ /* ? */ if((tail = head->next) == NULL){ tail=head; head=NULL; goto Del; } for( ; tail->next != NULL; prev = tail, tail = tail->next ); prev->next = NULL; Del: free(tail->key); free(tail); nelems--; } . , 1992-95 - 186 - UNIX  * 6. UNIX. *  . . - . UNIX - (). , - .   - , , ...  - ( ). , , . , "" (.. ) , - . "" , "" , " " , - (, , !). "" (swapping). ,   ; ( ) . , , , - -  ( ), - /bin/csh ( /bin/sh). "", "" : a) main: void main(int argc, char *argv[], char *envp[]); $ a.out a1 a2 a3 main a.out argc = 4 /* */ argv[0] = "a.out" argv[1] = "a1" argv[2] = "a2" argv[3] = "a3" argv[4] = NULL argv[0] |-. b) "" ( "") char *envp[], extern char **environ; "=" NULL ( argv). -  char *getenv( char * ); , NULL . c) . () 3 : FILE * stdin stdout stderr fd 0 1 2 ____________________ |- ps -ef #include <stdio.h> main(ac, av) char **av; { execl("/bin/sleep", "Take it easy", "1000", NULL); } . , 1992-95 - 187 - UNIX " " , . , - ( open, creat, pipe, fopen). 20 ( ), (, 64). MS DOS 2 : stdaux - , stdprn - . d) , int pid = getpid(); "" int ppid = getppid(); : kill(pid /* */, sig /* */); signal (sig /* */, f /* f(sig)*/); e) : , , , . f) () : , , -"", chdir(char *__);  ( MS DOS, ). "" - : ; (pgrp); () (uid), (gid), , ; ... g) ( ) ("") "" . h) (""). , - , (- shared memory); ( ).  , ""-, ""- ( ); "", - ( - ) ( ). " ". ? - - . , - . . - . - , (.. ) ,  |-. ____________________ |- , - , , ,  .  ,   ( , ), - ! , : UNIX- . - " ", , ..  , . , , -  , : , (    - - ). , , , - , include- .  . . , 1992-95 - 188 - UNIX " " " - ", .. .  , |=, , ( MS DOS, , ). 2 : - -"", -  . - - - - . : 1. ; 2. , , u-area (context switching); 3. ; 4. , ( , -  ); 5. ; 6. ; 7. - - ; 8. ; 9. ; 10. . ( 7) "", (, ). - . "" ( ) - . : 0 - , (-1) - ; ( open(), (-1) - . errno , ( , include- <errno.h> E). ,   , , : #include <errno.h> /* */ extern int errno; extern char *sys_errlist[]; int value; if((value = sys_call(...)) < 0 ){ printf("Error:%s(%d)\n", sys_errlist[errno], errno ); exit(errno); /* */ } ____________________ , - . , UNIX , - fork, exec, wait - ! -   (, , - ,  ). - ( - , ), , , . |= , ( ), ... . , 1992-95 - 189 - UNIX sys_errlist, , - (-). per- ror(). 6.1. . 6.1.1. stat, , : , , , FIFO-. : #include <sys/types.h> #include <sys/stat.h> typeOf( name ) char *name; { int type; struct stat st; if( stat( name, &st ) < 0 ){ printf( "%s \n", name ); return 0; } printf(" %d \n", st.st_nlink); switch(type = (st.st_mode & S_IFMT)){ case S_IFREG: printf( " %ld \n", st.st_size ); break; case S_IFDIR: printf( "\n" ); break; case S_IFCHR: /* */ case S_IFBLK: /* */ printf( "\n" ); break; case S_IFIFO: printf( "FIFO-\n" ); break; default: printf( " \n" ); break; } return type; } 6.1.2. , : , , - . struct stat st; int used, fd; for(fd=0; fd < NOFILE; fd++ ){ used = fstat(fd, &st) < 0 ? 0 : 1; ... } 0..NOFILE-1 ( 0..19). fstat - fd (<0), , (.. ). NOFILE include- <sys/param.h>, . 6.1.3. ls, ( ".") . , . "." ".." . header- <sys/dir.h> "" - : - , direct, , : . , 1992-95 - 190 - UNIX struct direct { unsigned short d_ino; /* 2 : I- */ char d_name[DIRSIZ]; /* */ }; BSD - , - , 1 256 .  , '\0', '/', . , ( !),  ( MS DOS,  , ()), (.. ) ! 14 (DIRSIZ) ,   '\0'. : 1. putchar()- . - DIRSIZ, '\0'. 2. d_name : char buf[ DIRSIZ + 1 ]; strncpy(buf, d.d_name, DIRSIZ); buf[ DIRSIZ ] = '\0'; , , , . 3. printf(): #include <sys/types.h> #include <sys/dir.h> struct direct d; ... printf( "%*.*s\n", DIRSIZ, DIRSIZ, d.d_name ); , d_ino 0 ( I- 1, 0). () , I- , - , : d_ino=0; - ! d_ino==0 - . (creat, link, mknod) ( ) d_ino==0, - ( - ). - .  : "." - ( I-node), ".." - . "/" (.. d_ino==2).   . "" ... UNIX - .  - .  ( |=)  - - write.  , creat, unlink, link, mkdir, rmdir, rename, mknod. : w  S_IWRITE. ____________________ |= (superuser) uid==0. "" - , . , ... . , 1992-95 - 191 - UNIX . : , . , - , ! r  S_IREAD. ( opendir, . ): , .