efghijklmn... D #00 S ...abcdefEhijklmn... D #01 S ...abcdefEhijklmn... D #01 S ...abcdeDEhijklmn... D #02 S ...abcdeDEhijklmn... D #02 S ...abcdCDEhijklmn... D #03 S ...abcdCDEhijklmn... D #03 S ...abcBCDEhijklmn... D #04 S ...abcBCDEhijklmn... D #04 S ...abABCDEhijklmn... D bcopy() - , - . ( malloc-): char *lines[NLINES]; : . , 1992-95 - 111 - UNIX void scrollUp(){ char *save = lines[0]; bcopy((char *) lines+1, /* from */ (char *) lines, /* to */ sizeof(char *) * (NLINES-1)); lines[NLINES-1] = save; } void scrollDown(){ char *save = lines[NLINES-1]; bcopy((char *) &lines[0], /* from */ (char *) &lines[1], /* to */ sizeof(char *) * (NLINES-1)); lines[0] = save; } , (void *) - - . - memmove - UNIX SVR4. , - bcopy. , SVR4  mem... (void *) size_t - ( unsigned long); ( - lseek stat). #include <sys/types.h> void memmove(void *Dst, const void *Src, register size_t n){ register caddr_t src = (caddr_t) Src, dst = (caddr_t) Dst; 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); } caddr_t - , (unsigned char *). caddr_t? , void *pointer; int n; pointer + n , sizeof(void) - 0, , ! 2.59. : , `=' `-' ( ...). . , 1992-95 - 112 - UNIX #include <stdio.h> #include <strings.h> char *strdup(const char *s){ extern void *malloc(); return strcpy((char *)malloc(strlen(s)+1), s); } char *ptr; void main(int ac, char *av[]){ ptr - strdup("hello"); /* ptr = ... */ *ptr = 'H'; printf("%s\n", ptr); free(ptr); exit(0); } , ( ) *pointer, pointer==NULL, . ptr NULL - - . UNIX , , NULL (0) , - . ( ). - NULL. MS DOS , - Ctrl/Alt/Del, . 2.60. strdup (,  ), . char *savefromto(register char *from, char *upto) { char *ptr, *s; if((ptr = (char *) malloc(upto - from + 1)) == NULL) return NULL; for(s = ptr; from < upto; from++) *s++ = *from; *s = '\0'; return ptr; } (*upto) , '\0'. 2.61. printf. . , 1992-95 - 113 - UNIX /* * - printf() ( ). * printf - . */ #include <stdio.h> #include <ctype.h> #include <varargs.h> #include <errno.h> #include <string.h> extern int errno; /* , %m */ /* */ #define GETN(n,fmt) \ n = 0; \ while(isdigit(*fmt)){ \ n = n*10 + (*fmt - '0'); \ fmt++; \ } void myprintf(fmt, va_alist) register char *fmt; va_dcl { va_list ap; char c, *s; int i; int width, /* */ prec, /* . */ sign, /* : 1 - , -1 - */ zero, /* 0 */ glong; /* */ va_start(ap); for(;;){ while((c = *fmt++) != '%'){ if( c == '\0' ) goto out; putchar(c); } sign = 1; zero = 0; glong = 0; if(*fmt == '-'){ sign = (-1); fmt++; } if(*fmt == '0'){ zero = 1; fmt++; } if(*fmt == '*'){ width = va_arg(ap, int); if(width < 0){ width = -width; sign = -sign; } fmt++; }else{ GETN(width, fmt); } width *= sign; if(*fmt == '.'){ if(*++fmt == '*'){ prec = va_arg(ap, int); fmt++; }else{ GETN(prec, fmt); } }else prec = (-1); /* */ if( *fmt == 'l' ){ glong = 1; fmt++; } . , 1992-95 - 114 - UNIX switch(c = *fmt++){ case 'c': putchar(va_arg(ap, int)); break; case 's': prStr(width, prec, va_arg(ap, char *)); break; case 'm': prStr(width, prec, strerror(errno)); break; /* strerror - */ case 'u': prUnsigned(width, glong ? va_arg(ap, unsigned long) : (unsigned long) va_arg(ap, unsigned int), 10 /* base */, zero); break; case 'd': prInteger(width, glong ? va_arg(ap, long) : (long) va_arg(ap, int), 10 /* base */, zero); break; case 'o': prUnsigned(width, glong ? va_arg(ap, unsigned long) : (unsigned long) va_arg(ap, unsigned int), 8 /* base */, zero); break; case 'x': prUnsigned(width, glong ? va_arg(ap, unsigned long) : (unsigned long) va_arg(ap, unsigned int), 16 /* base */, zero); break; case 'X': prUnsigned(width, glong ? va_arg(ap, unsigned long) : (unsigned long) va_arg(ap, unsigned int), -16 /* base */, zero); break; case 'b': prUnsigned(width, glong ? va_arg(ap, unsigned long) : (unsigned long) va_arg(ap, unsigned int), 2 /* base */, zero); break; case 'a': /* address */ prUnsigned(width, (long) (char *) va_arg(ap, char *), 16 /* base */, zero); break; case 'A': /* address */ prUnsigned(width, (long) (char *) va_arg(ap, char *), -16 /* base */, zero); break; case 'r': prRoman(width, prec, va_arg(ap, int)); break; case '%': putchar('%'); break; default: putchar(c); break; } } out: va_end(ap); } . , 1992-95 - 115 - UNIX /* --------------------------------------------------------- */ int strnlen(s, maxlen) char *s; { register n; for( n=0; *s && n < maxlen; n++, s++ ); return n; } /* */ static prStr(width, prec, s) char *s; { int ln; /* */ int toLeft = 0; /* */ if(s == NULL){ pr( "(NULL)", 6); return; } /* . * , \0 , * strlen(s) */ ln = (prec > 0 ? strnlen(s, prec) : strlen(s)); /* */ if( ! width ) width = (prec > 0 ? prec : ln); if( width < 0){ width = -width; toLeft = 1; } if( width > ln){ /* */ if(toLeft){ pr(s, ln); prSpace(width - ln, ' '); } else { prSpace(width - ln, ' '); pr(s, ln); } } else { pr(s, ln); } } /* l */ static pr(s, ln) register char *s; register ln; { for( ; ln > 0 ; ln-- ) putchar( *s++ ); } /* n c */ static prSpace(n, c) register n; char c;{ for( ; n > 0 ; n-- ) putchar( c ); } /* --------------------------------------------------------- */ static char *ds; /* */ static prRoman(w,p,n){ char bd[60]; ds = bd; if( n < 0 ){ n = -n; *ds++ = '-'; } prRdig(n,6); *ds = '\0'; prStr(w, p, bd); } . , 1992-95 - 116 - UNIX static prRdig(n, d){ if( !n ) return; if( d ) prRdig( n/10, d - 2); tack(n%10, d); } static tack(n, d){ static char im[] = " MDCLXVI"; /* ..1000 500 100 50 10 5 1 */ if( !n ) return; if( 1 <= n && n <= 3 ){ repeat(n, im[d+2]); return; } if( n == 4 ) *ds++ = im[d+2]; if( n == 4 || n == 5 ){ *ds++ = im[d+1]; return; } if( 6 <= n && n <= 8 ){ *ds++ = im[d+1]; repeat(n - 5, im[d+2] ); return; } /* n == 9 */ *ds++ = im[d+2]; *ds++ = im[d]; } static repeat(n, c) char c; { while( n-- > 0 ) *ds++ = c; } /* --------------------------------------------------------- */ static char aChar = 'A'; static prInteger(w, n, base, zero) long n; { /* */ char bd[128]; int neg = 0; /* < 0 */ if( n < 0 ){ neg = 1; n = -n; } if( base < 0 ){ base = -base; aChar = 'A'; } else { aChar = 'a'; } ds = bd; prUDig( n, base ); *ds = '\0'; /* */ prIntStr( bd, w, zero, neg ); } . , 1992-95 - 117 - UNIX static prUnsigned(w, n, base, zero) unsigned long n; { char bd[128]; if( base < 0 ){ base = -base; aChar = 'A'; } else { aChar = 'a'; } ds = bd; prUDig( n, base ); *ds = '\0'; /* */ prIntStr( bd, w, zero, 0 ); } static prUDig( n, base ) unsigned long n; { unsigned long aSign; if((aSign = n/base ) > 0 ) prUDig( aSign, base ); aSign = n % base; *ds++ = (aSign < 10 ? '0' + aSign : aChar + (aSign - 10)); } static prIntStr( s, width, zero, neg ) char *s; { int ln; /* */ int toLeft = 0; /* */ ln = strlen(s); /* s */ /* : , */ if( ! width ){ width = ln; /* */ if( neg ) width++; /* 1 */ } if( width < 0 ){ width = -width; toLeft = 1; } if( ! neg ){ /* */ if(width > ln){ if(toLeft){ pr(s, ln); prSpace(width - ln, ' '); } else { prSpace(width - ln, zero ? '0' : ' '); pr(s, ln); } } else { pr(s, ln); } }else{ /* */ if(width > ln){ /* */ width -- ; /* width */ if(toLeft){ putchar('-'); pr(s, ln); prSpace(width - ln, ' '); } else{ if( ! zero ){ prSpace(width - ln, ' '); putchar('-'); pr(s,ln); } else { putchar('-'); prSpace(width - ln, '0'); pr(s, ln); } } } else { putchar('-'); pr(s, ln); } } } . , 1992-95 - 118 - UNIX /* --------------------------------------------------------- */ main(){ int i, n; static char s[] = "Hello, world!\n"; static char p[] = "Hello, world"; long t = 7654321L; myprintf( "%%abc%Y\n"); myprintf( "%s\n", "abs" ); myprintf( "%5s|\n", "abs" ); myprintf( "%-5s|\n", "abs" ); myprintf( "%5s|\n", "xyzXYZ" ); myprintf( "%-5s|\n", "xyzXYZ" ); myprintf( "%5.5s|\n", "xyzXYZ" ); myprintf( "%-5.5s|\n", "xyzXYZ" ); myprintf( "%r\n", 444 ); myprintf( "%r\n", 999 ); myprintf( "%r\n", 16 ); myprintf( "%r\n", 18 ); myprintf( "%r\n", 479 ); myprintf( "%d\n", 1234 ); myprintf( "%d\n", -1234 ); myprintf( "%ld\n", 97487483 ); myprintf( "%2d|%2d|\n", 1, -3 ); myprintf( "%-2d|%-2d|\n", 1, -3 ); myprintf( "%02d|%2d|\n", 1, -3 ); myprintf( "%-02d|%-2d|\n", 1, -3 ); myprintf( "%5d|\n", -12 ); myprintf( "%05d|\n", -12 ); myprintf( "%-5d|\n", -12 ); myprintf( "%-05d|\n", -12 ); for( i = -6; i < 6; i++ ) myprintf( "width=%2d|%0*d|%0*d|%*d|%*d|\n", i, i, 123, i, -123, i, 123, i, -123); myprintf( "%s at location %a\n", s, s ); myprintf( "%ld\n", t ); n = 1; t = 1L; for( i=0; i < 34; i++ ){ myprintf( "for %2d |%016b|%d|%u|\n\t |%032lb|%ld|%lu|\n", i, n, n, n, t, t, t ); n *= 2; t *= 2; } myprintf( "%8x %8X\n", 7777, 7777 ); myprintf( "|%s|\n", p ); myprintf( "|%10s|\n", p ); myprintf( "|%-10s|\n", p ); myprintf( "|%20s|\n", p ); myprintf( "|%-20s|\n", p ); myprintf( "|%20.10s|\n", p ); myprintf( "|%-20.10s|\n", p ); myprintf( "|%.10s|\n", p ); } . , 1992-95 - 119 - UNIX : %abcY abs abs| abs | xyzXYZ| xyzXYZ| xyzXY| xyzXY| CDXLIV CMXCIX XVI XVIII CDLXXIX 1234 -1234 97487483 1|-3| 1 |-3| 01|-3| 1 |-3| -12| -0012| -12 | -12 | width=-6|123 |-123 |123 |-123 | width=-5|123 |-123 |123 |-123 | width=-4|123 |-123|123 |-123| width=-3|123|-123|123|-123| width=-2|123|-123|123|-123| width=-1|123|-123|123|-123| width= 0|123|-123|123|-123| width= 1|123|-123|123|-123| width= 2|123|-123|123|-123| width= 3|123|-123|123|-123| width= 4|0123|-123| 123|-123| width= 5|00123|-0123| 123| -123| Hello, world! at location 400980 7654321 for 0 |0000000000000001|1|1| |00000000000000000000000000000001|1|1| for 1 |0000000000000010|2|2| |00000000000000000000000000000010|2|2| for 2 |0000000000000100|4|4| |00000000000000000000000000000100|4|4| for 3 |0000000000001000|8|8| |00000000000000000000000000001000|8|8| for 4 |0000000000010000|16|16| |00000000000000000000000000010000|16|16| for 5 |0000000000100000|32|32| |00000000000000000000000000100000|32|32| for 6 |0000000001000000|64|64| |00000000000000000000000001000000|64|64| for 7 |0000000010000000|128|128| |00000000000000000000000010000000|128|128| for 8 |0000000100000000|256|256| |00000000000000000000000100000000|256|256| for 9 |0000001000000000|512|512| |00000000000000000000001000000000|512|512| for 10 |0000010000000000|1024|1024| . , 1992-95 - 120 - UNIX |00000000000000000000010000000000|1024|1024| for 11 |0000100000000000|2048|2048| |00000000000000000000100000000000|2048|2048| for 12 |0001000000000000|4096|4096| |00000000000000000001000000000000|4096|4096| for 13 |0010000000000000|8192|8192| |00000000000000000010000000000000|8192|8192| for 14 |0100000000000000|16384|16384| |00000000000000000100000000000000|16384|16384| for 15 |1000000000000000|32768|32768| |00000000000000001000000000000000|32768|32768| for 16 |10000000000000000|65536|65536| |00000000000000010000000000000000|65536|65536| for 17 |100000000000000000|131072|131072| |00000000000000100000000000000000|131072|131072| for 18 |1000000000000000000|262144|262144| |00000000000001000000000000000000|262144|262144| for 19 |10000000000000000000|524288|524288| |00000000000010000000000000000000|524288|524288| for 20 |100000000000000000000|1048576|1048576| |00000000000100000000000000000000|1048576|1048576| for 21 |1000000000000000000000|2097152|2097152| |00000000001000000000000000000000|2097152|2097152| for 22 |10000000000000000000000|4194304|4194304| |00000000010000000000000000000000|4194304|4194304| for 23 |100000000000000000000000|8388608|8388608| |00000000100000000000000000000000|8388608|8388608| for 24 |1000000000000000000000000|16777216|16777216| |00000001000000000000000000000000|16777216|16777216| for 25 |10000000000000000000000000|33554432|33554432| |00000010000000000000000000000000|33554432|33554432| for 26 |100000000000000000000000000|67108864|67108864| |00000100000000000000000000000000|67108864|67108864| for 27 |1000000000000000000000000000|134217728|134217728| |00001000000000000000000000000000|134217728|134217728| for 28 |10000000000000000000000000000|268435456|268435456| |00010000000000000000000000000000|268435456|268435456| for 29 |100000000000000000000000000000|536870912|536870912| |00100000000000000000000000000000|536870912|536870912| for 30 |1000000000000000000000000000000|1073741824|1073741824| |01000000000000000000000000000000|1073741824|1073741824| for 31 |10000000000000000000000000000000|-2147483648|2147483648| |10000000000000000000000000000000|-2147483648|2147483648| for 32 |0000000000000000|0|0| |00000000000000000000000000000000|0|0| for 33 |0000000000000000|0|0| |00000000000000000000000000000000|0|0| 1e61 1E61 |Hello, world| |Hello, world| |Hello, world| | Hello, world| |Hello, world | | Hello, wor| |Hello, wor | |Hello, wor| 2.62. : . , 1992-95 - 121 - UNIX int A[1024], B[1024], C[1024]; ... for(i=0; i < 1024; i++) C[i] = A[i] + B[i]; for(i=1024-1; i >=0 ; --i) ...; ? foreach i in (0..1023) ...; , , 1024 ! , . - - . ( - ). . , 1992-95 - 122 - UNIX 3. . . , - ( #define #ifdef) - ( , , , ) . - , , , , ! 3.1. , char, short, int, long, float, double, (char *) . sizeof. 3.2. , , : 1) . 2) . 3) . 4) |x|, 0, x - . 5) e, 1 1+e ( - ). 3.3. , ( int). : . 3.4. #define EOF (-1) #define NULL ((char *) 0) /* ((void *)0) */ : . -, include-, #include <stdio.h> . -, - : ( ) ! , - , <stdio.h>. #include <fcntl.h> int fd = open( ߔ, O_RDONLY); /* O_WRONLY, O_RDWR */ int fd = open( ߔ, 0); /* 1, 2 */ 3.5. ? #include <sys/types.h> #include <stdio.h> time_t t; extern time_t time(); ... t = time(0); /* 1 . 1970 .*/ : , time() : time_t time( time_t *t ); . . , 1992-95 - 123 - UNIX 0 ( int). IBM PC AT 286 - 2 , - . . time() - , . : t = time(NULL); ( time()) time( &t ); : t = time((time_t *)NULL); : , , NULL ( - ), 0. 3.6. : void f(x, s) long x; char *s; { printf( "%ld %s\n", x, s ); } void main(){ f( 12, "hello" ); } IBM PC 386, IBM PC 286. . , sin(12). , f long (4 IBM PC 286), int (2 ). x ; , - s. - , . IBM PC 386 int long 4 , ! -, ( - !). void f(long x, char *s); . void, . , ( "" Pascal Algol). void f, f (int), ( return). . int x = f((long) 666, "good bye" ); x . f void, - . (void *) (, [], *, -> : - " "). , , (memory allocation) malloc() ( |= ) : ____________________ |- "" "" . ++, , (pointer reference)  ( ). ____________________ . , 1992-95 - 124 - UNIX void *malloc(unsigned size); /* size */ char *s = (char *) malloc( strlen(buf)+1 ); struct ST *p = (struct ST *) malloc( sizeof(struct ST)); /* sizeof(*p) */ char *malloc(); 3.7. sizeof. , sizeof . ! sizeof  , . char a[] = "abcdefg"; char *b = "hijklmn"; sizeof(a) 8 ( \0 - ) sizeof(b) 2 PDP-11 ( ) strlen(a) 7 strlen(b) 7 b = "This ia a new line"; strcpy(a, "abc"); sizeof(b) 2 sizeof(a) 8 sizeof ( ), . sizeof . ,  .  - , double f(){ printf( "Hi!\n"); return 12.34; } main(){ int x = 2; long y = 4; printf( "%u\n", sizeof(x + y + f())); } , sizeof(double), "Hi!" - . sizeof ( ), : sizeof(char *); sizeof x; 3.8. , , , . : union all{ char *s; int i; double f; ____________________ |= "" (heap, pool) - , - , . . , 1992-95 - 125 - UNIX } x; x.i = 12 ; printf("%d\n", x.i); x.f = 3.14; printf("%f\n", x.f); x.s = "Hi, there"; printf("%s\n", x.s); printf("int=%d double=%d (char *)=%d all=%d\n", sizeof(int), sizeof(double), sizeof(char *), sizeof x); , x - int, double, char *. ,  - ! , , - , int - , ( PDP VAX). , , sizeof(int) != sizeof(char *), , . ( "poor style"), ,  ! , . , , - : /* : */ typedef void *PTR; /* */ struct a { int x, y; PTR pa; } A; struct b { double u, v; PTR pb; } B; #define Aptr(p) ((struct a *)(p)) #define Bptr(p) ((struct b *)(p)) PTR ptr1, ptr2; main(){ ptr1 = &A; ptr2 = &B; Bptr(ptr2)->u = Aptr(ptr1)->x = 77; printf("%f %d\n", B.u, A.x); } /* : ' */ /* : */ extern struct a; extern struct b; /* : */ typedef union everything { int i; double d; char *s; struct a *ap; struct b *bp; } ALL; struct a { int x, y; ALL pa; } A; struct b { double u, v; ALL pb; } B; ALL ptr1, ptr2, zz; main(){ ptr1.ap = &A; ptr2.bp = &B; zz.i = 77; ptr2.bp->u = ptr1.ap->x = zz.i; printf("%f %d\n", B.u, A.x); } 3.9. ( ), include- <ctype.h> if( '0' <= c && c <= '9' ) ... . , 1992-95 - 126 - UNIX #include <ctype.h> ..... if(isdigit(c)) ... if((c >='a' && c <= 'z') || (c >= 'A' && c <= 'Z')) ... if(isalpha(c)) ... , < > - . , -8 . , char c1, c2; c1 < c2 , c1 c2 ! - "" . , if( c >= '' && c <= '' ) . <ctype.h> - , ( ). : extern unsigned char _ctype[]; /* */ #define US(c) (sizeof(c)==sizeof(char)?((c)&0xFF):(c)) /* */ /* */ #define _U 01 /* uppercase: */ #define _L 02 /* lowercase: */ #define _N 04 /* number: */ #define _S 010 /* space: */ /* ... ... */ #define isalpha(c) ((_ctype+1)[US(c)] & (_U|_L) ) #define isupper(c) ((_ctype+1)[US(c)] & _U ) #define islower(c) ((_ctype+1)[US(c)] & _L ) #define isdigit(c) ((_ctype+1)[US(c)] & _N ) #define isalnum(c) ((_ctype+1)[US(c)] & (_U|_L|_N)) #define tolower(c) ((c) + 'a' - 'A' ) #define toupper(c) ((c) + 'A' - 'a' ) _ctype[] ( ) . : unsigned char _ctype[256 /* */ + 1] = { /* EOF (-1) */ 0, ... /* '1' 061 0x31 */ _N, ... /* 'A' 0101 0x41 */ _U, ... /* 'a' 0141 0x61 */ _L, ... }; . , 1992-95 - 127 - UNIX : |- #define isalpha(c) (((c) >= 'a' && (c) <= 'z') || \ ((c) >= 'A' && (c) <= 'Z')) 7 . isalpha <ctype.h> ( ) - : &. _ctype+1 _U|_L - , . toupper tolower ASCII|=, . , tolower , toupper - - : if( isupper(c) ) c = tolower(c); isspace(c), - #define isspace(c) (c==' ' ||c=='\t'||c=='\f'|| \ c=='\n'||c=='\r') #define isspace(c) (strchr(" \t\f\n\r",(c)) != NULL) , , _ctype[]. -,  . : isprint(c), , c , .. ; iscntrl(c), , c , .. - , , - - . , , - ("") , ^A '\01'. : <ctype.h> . . : ( !): : : 1 4 2 5 3 0 : 0 1 2 3 4 5 Ctou : unsigned char UU[] = { 5, 0, 2, 4, 1, 3 }; /* - 256 : UU[256] */ Ctou(c) unsigned char c; { return UU[c]; } int strcmp(s1, s2) char *s1, *s2; { /* */ while(*s1 && *s1 == *s2) s1++, s2++; /* [] */ return Ctou(*s1) - Ctou(*s2); ____________________ |- , \ - , . |= ASCII - American Standard Code for Information Interchange - - ( ). . , 1992-95 - 128 - UNIX } UU. 3.10. UNIX- ctype - . - - LANG. - - "C", . , ... #include <locale.h> ... main(){ setlocale(LC_ALL, ""); ... ... } 3.11. char. #include <stdio.h> #include <locale.h> #include <ctype.h> int main(int ac, char *av[]){ char c;