UNIX 2.18. ? int i; // . int *pi; // . int *api[3]; // 3 - . int (*pai)[3]; // 3 . // int **pai; int fi(); // , . int *fpi(); // -, . - . int (*pfi)(); // - -, . int *(*pfpi)(); // - -, . - int. int (*pfpfi())(); // -, // ", ". int (*fai())[3]; // -, . - // 3 . // int **fai(); int (*apfi[3])(); // 3 - , // . . int (*f)(); , f int value; value = (*f)(1, 2, 3 /* */); . ( "Communications of the ACM"), . - Algol-68. ref  " " proc()  ", " array of  " " x:  "x " , : int (*f())(); (*f())() : int *f() : proc() int f() : ref proc() int f : proc() ref proc() int f - , , . int (*f[3])(); (*f[])() : int *f[] : proc() int f[] : ref proc() int f : array of ref proc() int f - , . : g - , 5 , - . . , 1992-95 - 91 - UNIX g : ref p() ref array of ref p() ref int *g : p() ref array of ref p() ref int (*g)() : ref array of ref p() ref int *(*g)() : array of ref p() ref int (*(*g)())[5] : ref p() ref int *(*(*g)())[5] : p() ref int (*(*(*g)())[5])(): ref int *(*(*(*g)())[5])(): int int *(*(*(*g)())[5])(); , : proc() array of ... proc() ref array of ... (, ) - ( ): g = ( int *(*(*(*)())[])() ) 0; 2.19. strcat(d,s), s d. : char *strcat(d,s) register char *d, *s; { while( *d ) d++; /* d */ while( *d++ = *s++ ); /* strcpy(d, s) */ return (d-1); /* */ } , "strcpy" - do{ char c; c = (*d = *s); s++; d++; } while(c != '\0'); strcat , - strcpy: char *strcat(d,s) register char *d, *s; { char *p = d; while( *d ) d++; strcpy(d, s); return p; } , . ,  , ( - 1- ). 2.20. , , . gets(), - strcat(). sprintf(result,"%s%s",s1,s2); 2.21. , ( ) . strlen(). - strlen: /* */ . , 1992-95 - 92 - UNIX int strlen(s) char s[]; { int length = 0; for(; s[length] != '\0'; length++); return (length); } /* */ int strlen(s) char *s; { int length; for(length=0; *s; length++, s++); return length; } /* */ int strlen(register char *s) { register char *p = s; while(*p) p++; /* */ return (p - s); } - : TYPE *p1, *p2; p2 - p1 = TYPE p2 p1 p2 = p1 + n p2 - p1 = n p2 < p1, p2 . 2.22. , s n . : if( strlen(s) > n ) s[n] = '\0'; . , s , n , n, .. n- ( ). 2.23. , , . - ; . : #define isdigit(c) ('0' <= (c) && (c) <= '9') int atoi(s) register char *s; { register int res=0, neg=0; for(;;s++){ switch(*s){ case ' ': case '\t': continue; case '-': neg++; case '+': s++; } break; } while(isdigit(*s)) res = res * 10 + *s++ - '0'; return( neg ? -res : res ); } int backatoi(s) register char *s; { int res=0, pow=1; while(isdigit(*s)){ . , 1992-95 - 93 - UNIX res += (*s-- - '0') * pow; pow *= 10; } if(*s == '-') res = -res; return res; } 2.24. s "hello" char s[6]; s = "hello"; char s[6], d[] = "hello"; s = d; : . . strcpy(s,d). s ( - , ), "hello" ( d ).  ! ,  : char s[6] = "hello"; char s[6] = { 'h', 'e', 'l', 'l', 'o', '\0' }; char s[] = "hello"; char s[] = { "hello" }; . , (  ) , , '\0' - , . char s[5] = "hello"; , (5) , 6 . s[],  - . , , , . "" - ( static- - \0). char s[12] = "hello"; : h e l l o \0 ? ? ? ? ? ? " " '\0'. strlen(s). "()  " " ,  ": sizeof(s). 5 12. : char *sp = "bye bye"; sp = "hello"; , sp - (.. , ),  (, ). - , : sp , "bye bye"; sp , . , 1992-95 - 94 - UNIX "hello". , - sp . : char d[5]; char s[] = "abcdefgh"; strcpy(d, s); d . ( , strcpy, ), ""  d , . . - strncpy(d,s,len); strncat(d,s,len); strncmp(s1,s2,len). () , len s ( s1, s2). - ! strncmp ( len ), strncpy: char *strncpy(dst, src, n) register char *dst, *src; register int n; { char *save; for(save=dst; --n >= 0; ) if( !(*dst++ = *src++)){ while(--n >= 0) *dst++ = '\0'; return save; } return save; } , strncpy : n <= strlen(src), dst '\0', - ( ) . : int strncmp(register char *s1, register char *s2, register int n) { if(s1 == s2) return(0); while(--n >= 0 && *s1 == *s2++) if(*s1++ == '\0') return(0); return((n < 0)? 0: (*s1 - *--s2)); } 2.25. ? #include <stdio.h> /* putchar */ char s[] = "We don't need no education"; main(){ while(*s) putchar(*s++); } : s - , ++. char *s = "We don't need no education"; s cc. . 2.26. ? . , 1992-95 - 95 - UNIX char a[] = ""; /* */ char b[] = "\0"; char c = '\0'; char z[] = "ab"; char aa[] = { '\0' }; char bb[] = { '\0', '\0' }; char xx[] = { 'a', 'b' }; char zz[] = { 'a', 'b', '\0' }; char *ptr = "ab"; 2.27. : main() { char mas[] = {'s', 'o', 'r', 't'}; /* "sort" ? */ printf("%s\n", mas); } : '\0' ( printf ,  mas, .. ); - static: main() { static char mas[] = {'s', 'o', 'r', 't', '\0'}; } , main(){ char *mas = "sort"; } , .. , . 2.28. ? : a.c b.c cc a.c b.c -o ab a.c b.c --------------------------------------------------- int n = 2; extern int n; char s[] = "012345678"; extern char *s; main(){ f(){ f(); s[n] = '+'; printf("%s\n", s ); } } : , (char *) - , char[] - , : f(char *arg){...} f(char arg[]){...}  , char (.. ).  , arg++. , (char *) char[] , , : arg[i].  ! char *p; , (): -------- ------- p:| *--|----->| '0' | char -------- | '1' | char ... . , 1992-95 - 96 - UNIX char a[20]; ( ): ------- a:| '0' | char | '1' | char ... b.c s . - s , char. ------- s:| '0' | \ | '1' | / . | '2' | ... ! - . , , char s[] = "012345678"; char **ss = s; /* s - " " */ /* s : */ char *p = ss[0]; p[2] = '+'; b.c extern char s[]; /* */ , , ( - long). IBM PC 80386, sizeof(char *) = sizeof(long) = 4 a.c b.c --------------------------------------------------- char s[20] = {1,2,3,4}; extern char *s; main(){ f(){ /* long */ f(); printf( "%08lX\n", s ); } } 04030201. 2.29. ? static char str1[ ] = "abc"; static char str2[4]; strcpy( str2, str1 ); /* str2 = str1; ? */ printf( str1 == str2 ? "":" " ); ? - ? :  , . . , 1992-95 - 97 - UNIX char str1[2]; char str2[2]; main(){ printf( str1 < str2 ? "<":">"); } <, char str2[2]; char str1[2]; >. 2.30. , , . strcmp() ( ""). 2.31. strcmp() ? #include <stdio.h> main() { printf("%d\n", strcmp("abc", "abc")); /* 0 */ printf("%d\n", strcmp("ab" , "abc")); /* -99 */ printf("%d\n", strcmp("abd", "abc")); /* 1 */ printf("%d\n", strcmp("abc", "abd")); /* -1 */ printf("%d\n", strcmp("abc", "abe")); /* -2 */ } 2.32. : , ( ) if( strcmp("abc", "bcd") < 0) ... ; if( strcmp("abc", "bcd") == 0) ... ; if( "abc" < "bcd" ) ... ; if( "abc" == "bcd" ) ... ; char d[80], s[80]; strcpy( d, s ); d = s; 2.33. , - : int char double long for while if 2.34. , : ? char s[] = "You're a smart boy, now shut up."; int i, len; for(i=0; i < strlen(s); i++) putchar(s[i]); : . , 1992-95 - 98 - UNIX i=0; LOOP: if( !(i < strlen(s))) goto ENDLOOP; putchar(s[i]); i++; goto LOOP; ENDLOOP: ; , s , strlen(s) - , ! : for(i=0, len=strlen(s); i < len; i++ ) putchar(s[i]); for(i=0, len=strlen(s); len > 0; i++, --len ) putchar(s[i]); , while( i < strlen(s))...; ! , , , , strlen. (, , " " - :  ). 2.35. ? #include <stdio.h> main(){ static char str[] = " "; char *pt; pt = str; puts(pt); puts(++pt); str[7] = '\0'; puts(str); puts(pt); puts(++pt); } 2.36. ? main() { static char name[] = ""; char *pt; pt = name + strlen(name); while(--pt >= name) puts(pt); } 2.37. ? char str1[] = "abcdef"; char str2[] = "xyz"; main(){ register char *a, *b; a = str1; b = str2; while( *b ) *a++ = *b++; printf( "str=%s a=%s\n", str1, a ); a = str1; b = str2; . , 1992-95 - 99 - UNIX while( *b ) *++a = *b++; printf( "str=%s a=%s\n", str1, a ); } : str=xyzdef a=def str=xxyzef a=zef 2.38. ? char *s; for(s = ""; *s; s+= 2){ putchar(s[0]); if(!s[1]) break; } putchar('\n'); 2.39. ? s, - strs[]. . ++ , - ? , - - . ! #include <stdio.h> /* NULL */ /* : abcdefghijklmnopqrstuvwxyz */ char *strs[] = { "abcd","ABCD","0fpx","159", "hello","-gop","A1479",NULL }; main(){ char c, **s = strs, *p; c = *++*s; printf("#1 %d %c %s\n", s-strs, c, *s); c = **++s; printf("#2 %d %c %s\n", s-strs, c, *s); c = **s++; printf("#3 %d %c %s\n", s-strs, c, *s); c = ++**s; printf("#4 %d %c %s\n", s-strs, c, *s); c = (**s)++; printf("#5 %d %c %s\n", s-strs, c, *s); c = ++*++*s; printf("#6 %d %c %s\n", s-strs, c, *s); c = *++*s++; printf("#7 %d %c %s %s\n", s-strs, c, *s, strs[2]); c = ++*++*s++; printf("#8 %d %c %s %s\n", s-strs, c, *s, strs[3]); c = ++*++*++s; printf("#9 %d %c %s\n", s-strs,c,*s); c = ++**s++; printf("#10 %d %c %s\n",s-strs,c,*s); p = *s; c = ++*(*s)++; printf("#11 %d %c %s %s %s\n",s-strs,c,*s,strs[6],p); c = ++*((*s)++); printf("#12 %d %c %s %s\n", s-strs, c, *s, strs[6]); c = (*++(*s))++; printf("#13 %d %c %s %s\n", s-strs, c, *s, strs[6]); for(s=strs; *s; s++) printf("strs[%d]=\"%s\"\n", s-strs, *s); putchar('\n'); } : . , 1992-95 - 100 - UNIX #1 0 b bcd strs[0]="bcd" #2 1 A ABCD strs[1]="ABCD" #3 2 A 0fpx strs[2]="px" #4 2 1 1fpx strs[3]="69" #5 2 1 2fpx strs[4]="hello" #6 2 g gpx strs[5]="iop" #7 3 p 159 px strs[6]="89" #8 4 6 hello 69 #9 5 h hop #10 6 i A1479 #11 6 B 1479 1479 B1479 #12 6 2 479 479 #13 6 7 89 89 , char *strs[1] = { "hello" }; , strs[0]   , "hello". ! *, ++, (). 2.40. ? char str[25] = "Hi, "; char *f(char **s){ int cnt; for(cnt=0; **s != '\0'; (*s)++, ++cnt); return("ny" + (cnt && (*s)[-1] == ' ') + (!cnt)); } void main(void){ char *s = str; if( *f(&s) == 'y') strcat(s, "dude"); else strcat(s, " dude"); printf("%s\n", str); } , char str[25]="Hi,"; char str[25]=""; 2.41. ? ( ) main(){ char *buf; /* char buf[]; */ gets( buf ); printf( "%s\n", buf ); } : buf , buf - . : char buf[80]; char mem[80], *buf = mem; , , ( ), , - . -, , "", " "! "" ( ) . . , 1992-95 - 101 - UNIX , . SPARCstation 20 "Segmentation fault" (SIGSEGV). , - " ". main(){ int *iptr; int ival = *iptr; printf("%d\n", ival); } 2.42. "Life is life" : main(){ char buf[ 60 ]; strcat( buf, "Life " ); strcat( buf, "is " ); strcat( buf, "life" ); printf( "%s\n", buf ); } buf? : , - '\0', strcat() . - *buf = '\0'; strcat()-, strcat()- strcpy( buf, "Life " ); 2.43. copystr(s1, s2) s2 s1. 2.44. lenstr(s) . (1-3 - ) , , . "", . ++ - - inline ( "intrinsic"). 2.45. (- ) : abcdef --> fedcba. 2.46. index(s, t), t s; t , -1. , . - NULL. UNIX System-V strchr. : char *strchr(s, c) register char *s, c; { while(*s && *s != c) s++; return *s == c ? s : NULL; } . , 1992-95 - 102 - UNIX , p=strchr(s,'\0'); . - : extern char *strchr(); char *s = "abcd/efgh/ijklm"; char *p = strchr(s, '/'); printf("%s\n", p==NULL ? " / " : p); if(p) printf(" = s[%d]\n", p - s ); 2.47. strrchr(), . : char *strrchr(s, c) register char *s, c; { char *last = NULL; do if(*s == c) last = s; while(*s++); return last; } : extern char *strrchr(); char p[] = "wsh"; /* */ main(argc, argv) char *argv[];{ char *s = argv[1]; /* */ /* * a.out csh * a.out /bin/csh * a.out wsh * a.out /usr/local/bin/wsh */ char *base = (base = strrchr(s, '/')) ? base+1 : s; if( !strcmp(p, base)) printf(", %s\n" , p); else printf(", %s\n", base); /* : */ if( !strcmp(p,(base=strrchr(s,'/')) ? ++base : (base=s)) ) printf("Yes %s\n", p); else printf("No %s\n", base); } 2.48. substr(to,from,n,len) to from n- len. strncpy. : #define substr(to, from, n, len) strncpy(to, from+n, len) : . , 1992-95 - 103 - UNIX char *substr(to, from, n, len) char *to, *from; { int lfrom = strlen(from); if(n < 0 ){ len += n; n = 0; } if(n >= lfrom || len <= 0) *to = '\0'; /* */ else{ /* : */ if(len > lfrom-n) len = lfrom - n; strncpy(to, from+n, len); to[len] = '\0'; } return to; } 2.49. , , ".abc", - ".abc" . - . . - . s p : int ls = strlen(s), lp = strlen(p); if(ls >= lp && !strcmp(s+ls-lp, p)) ......; 2.50. c ( ) ( ). " ", .. . : /* */ char delete(s, at) register char *s; { char c; s += at; if((c = *s) == '\0') return c; while( s[0] = s[1] ) s++; return c; } /* strcpy(s+at, s+at+1); */ /* */ insert(s, at, c) char s[], c; { register char *p; s += at; p = s; while(*p) p++; /* */ p[1] = '\0'; /* */ for( ; p != s; p-- ) p[0] = p[-1]; *s = c; } 2.51. c s , . : . , 1992-95 - 104 - UNIX delc(s, c) register char *s; char c; { register char *p = s; while( *s ) if( *s != c ) *p++ = *s++; else s++; *p = '\0'; /* ! */ } 2.52. S1 , - S2. 2.53. scopy(s,t), s t, - "\n" "\t". switch. 2.54. , "" , - ( "\n") ('\n'). : extern char *strchr(); void unquote(s) char *s; { static char from[] = "nrtfbae", to [] = "\n\r\t\f\b\7\33"; char c, *p, *d; for(d=s; c = *s; s++) if( c == '\\'){ if( !(c = *++s)) break; p = strchr(from, c); *d++ = p ? to[p - from] : c; }else *d++ = c; *d = '\0'; } 2.55. , S P Q, : P = ""; Q = ""; S = "--!"; : "--!" 2.56. ( , - '\0'), .  - . : n memcpy(dst,src,n); c memset(s,c,n); memchr(s,c,n); memcmp(s1,s2,n); : #define REG register char *memset(s, c, n) REG char *s, c; { REG char *p = s; while( --n >= 0 ) *p++ = c; return s; } char *memcpy(dst, src, n) REG char *dst, *src; REG int n; { REG char *d = dst; . , 1992-95 - 105 - UNIX while( n-- > 0 ) *d++ = *src++; return dst; } char *memchr(s, c, n) REG char *s, c; { while(n-- && *s++ != c); return( n < 0 ? NULL : s-1 ); } int memcmp(s1, s2, n) REG char *s1, *s2; REG n; { while(n-- > 0 && *s1 == *s2) s1++, s2++; return( n < 0 ? 0 : *s1 - *s2 ); }  . 2.57.  (strcpy, strlen, strchr, memcpy, ...)? : , , , . . , . 2.58. , : #include <stdio.h> #include <string.h> char string[] = "abcdefghijklmn"; void main(void){ memcpy(string+2, string, 5); printf("%s\n", string); exit(0); abababahijklmn. , 5 "abcde" : ab[abcde]hijklmn, ab[ababa]hijklmn - - ... ? , (src) (dst) , *src , ! , : . , 1992-95 - 106 - UNIX #include <stdio.h> #include <string.h> #include <ctype.h> char string[] = "abcdefghijklmn"; char *src = &string[0]; char *dst = &string[2]; int n = 5; void show(int niter, char *msg){ register length, i; printf("#%02d %s\n", niter, msg); length = src-string; putchar('\t'); for(i=0; i < length+3; i++) putchar(' '); putchar('S'); putchar('\n'); printf("\t...%s...\n", string); length = dst-string; putchar('\t'); for(i=0; i < length+3; i++) putchar(' '); putchar('D'); putchar('\n'); } void main(void){ int iter = 0; while(n-- > 0){ show(iter, ""); *dst++ = toupper(*src++); show(iter++, ""); } exit(0); } : . , 1992-95 - 107 - UNIX #00 S ...abcdefghijklmn... D #00 S ...abAdefghijklmn... D #01 S ...abAdefghijklmn... D #01 S ...abABefghijklmn... D #02 S ...abABefghijklmn... D #02 S ...abABAfghijklmn... D #03 S ...abABAfghijklmn... D #03 S ...abABABghijklmn... D #04 S ...abABABghijklmn... D #04 S ...abABABAhijklmn... D , , (n - ). dst src src dst ######## @@@@@@@@ @@@@@@@@ ######## dst+n <= src src+n <= dst dst <= src-n dst >= src+n ! (dst <= src - n || dst >= src + n) = (dst > src - n && dst < src + n) dst > src. src < dst && dst < src + n ( dst==src, ). " . , 1992-95 - 108 - UNIX ": void bcopy(register char *src, register char *dst, register int n){ if(dst >= src){ dst += n-1; src += n-1; while(--n >= 0) *dst-- = *src--; }else{ while(n-- > 0) *dst++ = *src++; } } , : void bcopy(register char *src, register char *dst, register int n){ if(dst==src || n <= 0) return; if(src < dst && dst < src + n) { dst += n-1; src += n-1; while(--n >= 0) *dst-- = *src--; }else memcpy(dst, src, n); } #include <stdio.h> #include <string.h> #include <ctype.h> char string[] = "abcdefghijklmn"; char *src = &string[0]; char *dst = &string[2]; int n = 5; void show(int niter, char *msg){ register length, i; printf("#%02d %s\n", niter, msg); length = src-string; putchar('\t'); for(i=0; i < length+3; i++) putchar(' '); putchar('S'); putchar('\n'); printf("\t...%s...\n", string); length = dst-string; putchar('\t'); for(i=0; i < length+3; i++) putchar(' '); putchar('D'); putchar('\n'); } . , 1992-95 - 109 - UNIX void main(void){ int iter = 0; if(dst==src || n <= 0){ printf(" \n"); return; } if(src < dst && dst < src + n) { dst += n-1; src += n-1; while(--n >= 0){ show(iter, ""); *dst-- = toupper(*src--); show(iter++, ""); } }else while(n-- > 0){ show(iter, ""); *dst++ = toupper(*src++); show(iter++, ""); } exit(0); } . , 1992-95 - 110 - UNIX #00 S ...abcd