Вы находитесь на странице: 1из 232

.. , .. .

.. , ..

C( ) -
, ,
,
. C ,
,
.
, ,
.
C,
UNIX DEC PDP-11,
. ,
C
UNIX ( ,
) C.
C , IBM SYSTEM/
370, HONEYWELL 6000, INTERDATA 8/32. C, ,
- ,
,
, C-.
,
C. ,
-
,
. ,
, . ,
,
, .
, ,
. ,
, , ,

.
;

, , ,
.
,
.
, C ,

.. , ..

.
, .
, .

,
. , , , ,
-, ,
. , ,
, , , , ,
, , , , ,
, , ,

.
.
.

.. , ..

................................................................................................. 2
............................................................................................... 4
0.1. . ........................................................................................... 9
1.
. ................................................................................ 14
1.1. H. .............................................................................................. 14
1.2. . ................................................................. 17
1.3. FOR. ...................................................................................... 21
1.5. . ................................................................. 23
1.5.1.
. .............................................................. 23
1.5.2.
. .................................................................... 23
1.5.3.
. ....................................................................... 25
1.5.4.
. ............................................................................. 27
1.5.5.
. ............................................................................... 28
1.6. . ............................................................................................... 30
1.7. . ............................................................................................... 32
1.8. - . ........................................................ 34
1.9. . .............................................................................. 35
1.10. : . .......................................... 38
2.
, . ......................................... 40
2.1. . .............................................................................. 40
2.2. . ..................................................................... 40
2.3. . ............................................................................................ 41
2.3.1.
. ............................................................... 42
2.3.2.
............................................................. 42
2.3.3.
..................................................................... 43
2.4. ............................................................................................... 43
2.5. . ................................................................. 44
2.6. ................................... 45
2.7. ......................................................................... 46
2.8. ................................................. 50
2.9. ........................................................ 52
2.10. . ............................................... 54
2.11. . .......................................................................... 55
2.12. . ................................................. 57
3.
.................................................................... 59
3.1. ............................................................................... 59
3.2. IF - ELSE ................................................................................................ 59
3.3. ELSE - IF ................................................................................................ 61
3.4. ...................................................................................... 62
3.5. - WHILE FOR ........................................................................ 64
3.6. DO - WHILE ................................................................................ 67
3.7. BREAK ................................................................................. 68

.. , ..

3.8. CONTINUE .......................................................................... 69


3.9. GOTO ..................................................................... 70
4.
. ................................... 72
4.1. . ............................................................................. 72
4.2. , . .................................... 75
4.3. . .............................................................. 78
4.4. . ......................................................................... 79
4.5. , . ....................................... 83
4.5.1.
. ........................................................................ 83
4.6. . .................................................................... 87
4.8. . ............................................................................... 89
4.9. . .................................................................................... 90
4.10. . ............................................................................................... 92
4.11. C. ..................................................................... 93
4.11.1.
...................................................................... 93
4.11.2.
...................................................................... 94
5.
............................................................ 96
5.1. ................................................................................ 96
5.2. ......................................................... 98
5.3. ......................................................................... 100
5.4. ....................................................................... 103
5.5. ........................................................ 106
5.6. - . ........................................................................ 109
5.7. . .................................................................... 110
5.8. ; .................................... 112
5.9. . ............................................. 116
5.10. ................................................. 117
5.11. .......................................................... 117
5.12. ....................................................................... 122
6.
. .................................................................................. 126
6.1. . .......................................................................... 126
6.2. . ....................................................................... 128
6.3. . .............................................................................. 130
6.4. . ................................................................... 135
6.5. , . ................................................... 137
6.6. . ................................................................................ 141
6.7. . ................................................................................................... 144
6.8. . ..................................................................................... 146
6.9. .............................................................................. 148
7.
.............................................................................. 150
7.1. ............................................ 150
7.2. - GETCHAR PUTCHAR .. 150
7.3. - PRINTF ............................................. 152

.. , ..

7.5. ..............................................
7.6. ................................................................................
7.7. - STDERR EXIT .............................................
7.8. ...........................................................................
7.9. .................................................
7.9.1.
...........................
7.9.2.
UNGETC ...................................................................
7.9.3.
...............................................................
7.9.4.
................................................................
8.
UNIX .................................................
8.1. .........................................................................
8.2. / - READ WRITE. .........
8.3. , , (UNLINK). ............
8.4. - SEEK LSEEK. ........................................
8.5. - FOPEN GETC. ............................
8.6. - .................................................
8.7. - . ....................................................
9.
:
C ....................
9.1. .............................................................................................
10. ..................................................................
10.1. ......................................................................................
10.2. () ..................................................................
10.3. .................................................................................
10.4. ..........................................................................................
10.4.1.
......................................................................
10.4.2.
......................................................
10.4.3.
............................................................
10.4.4.
.............................................................
10.5. ................................................................................................
10.6. ..............................................
11. ...................................................................
12. ? ....................................................................
14. .................................................................................
14.1. ...............................................................................
14.2. FLOAT DOUBLE ..................................................................
14.3. .........................................
14.4. .............................................................................
14.5. ..................................................................................
14.6. ....................................................
15. .........................................................................................
15.1. ......................................................................
15.2. .............................................................................

157
158
161
162
163
163
164
164
164
165
165
166
168
170
171
175
179
184
184
184
184
184
185
185
185
185
186
186
186
187
187
187
189
189
189
189
190
190
190
191
191
193

.. , ..

15.3.
15.4.
15.5.
15.6.
15.7.
15.8.
15.9.

......................................................... 195
....................................................................... 195
................................................................................ 196
........................................................................ 196
.......................................................................... 196
.................................................................... 197
- .....................
-: .......................................................................... 197
15.10. - ......................
-: ............................................................................. 197
15.11. ................................................................... 197
15.12. ............................................................. 197
15.13. ............................................................................ 198
15.14. .................................................................... 198
15.15. ............................................................................... 199
16. ............................................................................................ 199
16.1. ........................................................ 200
16.2. ......................................................................... 200
16.3. ........................................................................................... 201
16.4. ............................................................................. 201
16.5. .................................................. 203
16.6. .................................................................................. 206
16.7. ....................................................................................... 208
16.8. TYPEDEF ........................................................................................... 209
17. .......................................................................................... 209
17.1. ................................................................... 209
17.2. ( ) ........................................................ 210
17.3. ......................................................................... 210
17.4. WHILE ............................................................................... 210
17.5. DO ...................................................................................... 211
17.6. FOR .................................................................................... 211
17.7. SWITCH ............................................................................ 211
17.8. BREAK .............................................................................. 212
17.9. CONTINUE ....................................................................... 212
17.10. ............................................................................ 213
17.11. GOTO ................................................................................ 213
17.12. ...................................................................... 213
17.13. ............................................................................... 213
18. ....................................................................... 214
18.1. ....................................................... 214
18.2. ......................................................... 215
19. , ..................................... 215
19.1. ......................................................... 216

8
19.2.
20.
20.1.
20.2.
20.3.
21.
22.
22.1.
22.2.
22.3.
22.4.
23.
24.
25.
26.
26.1.
26.2.
26.3.
26.4.
27.
28.
29.

.. , ..

................................
...................................................
....................................................................................
............................................................................
........................................................................
.............................................................................
.....................................................................................
.................................................................
.............................................................................................
, ...................................................
...................................................
...................................................................
........................................................
.....................................................................................
........................................................
.........................................................................................
............................................................................................
-: ......................................................
: .................................................
..................................................................
..............................................................................
C. ...............

217
217
217
218
218
219
219
219
220
220
221
222
223
224
224
224
226
228
228
229
230
231

.. , ..

0.1. .
C .
UNIX ,
UNIX C.
, , - ;
,
,
,
.
C - .
; , C
, , ,
, .
,
.
C ,
, , ,
, . , ,
PL/1, .
,
,
; (HEAP),
, -68. ,
C -:
READ WRITE
.
.
, C ,
: , ,
, , ,
.

(,
, ?!),
. C
,
. C . ,
;

10

.. , ..


, 80
.
.
, C, , ,
, . PDP -11,
, 32-
.
, ,
-,
,
, , , ;
C.
- , C
, C ,

.
UNIX, C.
13000 800
. ,
UNIX C;
UNIX(
) PDP-11.
C ,
-
, .. ,
.
,
UNIX, : HONEYWELL, IBM
INTERDATA. C
, -,
,
(ANSI).
UNIX PDP-11, INTERDATA 8/32.
,
-, , . C
. 7000 ,

-, 95 .
, ,

.. , ..

11

, C.
C
, BCPL ,
. BCPL C
B, 1970
UNIX PDP-7.
C BCPL ,
. BCPL B ;
,
. C ,
. ,
, , , ,
.
C ,
: ,
(IF), (WHILE,
FOR) (DO)
(SWITCH). ( BCPL,
;
).
C .

,
. ,
, ,
.
,
.
,
, ..
. ,

. C - .
, ,
,
.
.
,

.
C

12

.. , ..

68. ,

PL/1.

, ..
, ,
. LINT
, . LINT
,
, . ,
,

,
.. ,
LINT, ,
, , , -68.
LINT ,
.
, C, ,
. ;
;
, . C

.
. 1
C.
- , ,
,
- . , ,
; ,
, N=N+1.
, ,
.
; ,
, .
2- 6- C
, 1, -
, ,
.
2 , .
3 : IF-ELSE ,WHILE ,FOR
.. 4 -
, ..

.. , ..

13

5 . 6
.
7 - C,
.
- ,
C, , ,
,
.
8 C -
UNIX. -,
.
UNIX, , UNIX,
,
,
.
A C.
C
( - )
.
C ,
,
- .
.
, ,
UNIX PDP-11 ,
C.
C .

14

.. , ..

1. .
C. - ,
, .
(,
). ,
, , :
, , ,
.
C, ,
, ,
C, .
, , .
,
, , ,
. , -
, ,
.
, .
,
. ,
, .
,

.
. ,
,
, 2.
1.1. H.
-
. , , -
: : HELLO, WORLD.
- ; ,
- , , ,
, .
, .
HELLO, WORLD C :
MAIN ()

.. , ..

15

PRINTF(HELLO, WORLD\N);
- .
, UNIX
, .C , , HELLO.C
,
CC HELLO.C
- ,
,
.OUT .
A.OUT

HELLO, WORLD
;
.
1-1.
.

.
. C-,
, ,
, .
C PL/1,
.. MAIN.
, MAIN -
; MAIN.
, -
MAIN. MAIN
,
, - ,
.

. , ,
; IN - ,
(). , ,
, DO-END PL/1 BEGIN-END
, ..
, .
CALL, PL/1.
, .

16

.. , ..

PRINTF(HELLO, WORLD\N);
,
PRINTF HELLO, WORLD\N. PRINTF
, (
- ).
, .
,
...,
.
PRINTF .
\N
C ,
.
\N ( ), ,
.
\N -
PRINTF; -
PRINTF(HELLO, WORLD
);
C-
.
PRINTF ,

. ,
,
MAIN()
PRINTF(HELLO, );
PRINTF(WORLD);
PRINTF(\N);
, \N .
, \N ,

. C :
\ - , \B - , \ -
\\ .
1-2.
, ,
, PRINTF \X,

.. , ..

17

X - , .
1.2. .

,

C =
20
40
60
...
260
280
300

(5/9)*(F-32). 0
-6.7
4.4
15.6
...
126.7
137.8
140.9

-17.8

:
/* PRINT FAHRENHEIT-CELSIUS TABLE
FOR F = 0, 20, ..., 300 */
MAIN()
INT LOWER, UPPER, STEP;
FLOAT
FAHR, CELSIUS;
LOWER
= 0; /* LOWER LIMIT OF TEMPERATURE
TABLE
*/
UPPER
=300; /* UPPER LIMIT */
STEP= 20; /* STEP SIZE */
FAHR = LOWER;
WHILE (FAHR <= UPPER)
CELSIUS = (5.0/9.0) * (FAHR -32.0);
PRINTF(%4.0F %6.1F\N, FAHR, CELSIUS);
FAHR = FAHR + STEP;


/* PRINT FAHRENHEIT-CELSIUS TABLE
FOR F = 0, 20, ..., 300 */
, ,
. /* */ ;
. ,

18

.. , ..

.
C ,
.
,
. ,
,
INT LOWER, UPPER, STEP;
FLOAT FAHR, CELSIUS;
INT , ; FLOAT
, .. ,
. INT , TAK FLOAT , . PDP-11, , INT
16- , .. , 32768 +32767. FLOAT - 32- ,
10-38 10+38. 2
.
C ,
INT FLOAT:
CHAR
-
SHORT
LONG

DOUBLE
-;
2. ,
, , ;
.


LOWER = 0;
UPPER =300;
STEP = 20;
FAHR =LOWER;
.
.
,
, .
WHILE:
WHILE (FAHR <= UPPER)
...
.
(FAHR UPPER),

.. , ..

19

( , ).
, ,
. ( FAHR UPPER ),
,
.
, .
WHILE ,
, ,
, , ,
WHILE (I < J)
I = 2 * I;
, WHILE,
, ,
.
. C
,
.
()
. ;
.
.
.
CELAIUS
CELSIUS = (5.0/9.0) * (FAHR-32.0);
5.0/9.0
5/9 , C,
, ,
. , 5/9 ,
, , .
,
, , , 5.0/9.0 0.5555... .
32.0 32 , , FAHR FLOAT , 32
FLOAT ( 32.0) .
,
; ,
, .
,
, 2. ,

20

.. , ..

FAHR = LOWER;

WHILE (FAHR <= UPPER)


, , - .
, PRINTF.
PRINTF
, 7.
, ,
% ,
/, , .../ . ,
PRINTF(%4.0F %6.1F\N, FAHR, CELSIUS);
%4.0F ,

. %6.1F
,
, F6.1
F(6,1) PL/1.
: %6F ,
; %2
, ; %F
, .
PRINTF : %D -
, % - , % - , % - , %S - %%
- %.
% PRINTF
, , .. ;
;
.
, PRINTF C;
C -.
PRINTF ; - ,
, C. ,
- 7. ,
. -
SCANF 7, 7.4. SCANF
PRINTF , , .

.. , ..

21

1-3.
,
.
1-4.

.
1.3. FOR.
,
.
:
MAIN()

/* FAHRENHEIT-CELSIUS TABLE */

INT FAHR;
FOR (FAHR = 0; FAHR <= 300; FAHR = FAHR + 20)
PRINTF(%4D %6.1F\N, FAHR, (5.0/9.0)*(FAHR-32.0));
, . - ;
FAHR , INT ( ,
%D PRINTF).
FOR ,
, ,
,
PRINTF , .

C - ,
, .
PRINTF
, %6.1F,
.
FOR - , WHILE.
,
WHILE . FOR ,
.
FAHR = 0
. , , :
FAHR <= 300
, ,

22

.. , ..

( PRINTF ).

FAHR =FAHR + 20
. ,
. , WHILE ,
,
.
.
WHILE FOR
, . FOR ,

, ,
WHILE , .
1-5.
,
, .. 300 0.
1.4. .
,
. , 300 20,
- ; , ,
, ,
. C
, .
#DEFINE ,
,
.
.
,

#DEFINE LOWER 0/* LOWER LIMIT OF TABLE */
#DEFINE UPPER 300 /* UPPER LIMIT */
#DEFINE STEP 20 /* STEP SIZE */
MAIN () /* FAHRENHEIT-CELSIUS TABLE */
INT FAHR;
FOR (FAHR =LOWER; FAHR <= UPPER; FAHR =FAHR + STEP)
PRINTF(%4D %6.1F\N, FAHR, (5.0/9.0)*(FAHR-32));
LOWER, UPPER STEP
.
,

.. , ..

23

. ,
. ,
,
FOR .
1.5. .
,

. ,
, .
1.5.1. .

. GETCHAR()
, ,
. ,
C = GETCHAR()
C .
,
7.
PUTCHAR(C) GETCHAR :

PUTCHAR (C)
C ,
. PUTCHAR PRINTF
; ,
.
PRINTF , GETCHAR PUTCHAR
. C,
.
1.5.2. .
GETCHAR PUTCHAR
, -,
.
.
:

WHILE ( )

24

.. , ..


, C, :
MAIN()

/* COPY INPUT TO OUTPUT; 1ST VERSION */

INT C;
C = GETCHAR();
WHILE (C != EOF)
PUTCHAR (C);
C = GETCHAR();
!= .
,
. , GETCHAR ,
, ;
, , .
, ,
,
.
, EOF ,
. EOF -1, 0,

#DEFINE

EOF

-1

EOF

#DEFINE

EOF ,
GETCHAR ,
,
.
C INT , CHAR ,
, GETCHAR . 2,
INT,
EOF.
, C,
. C ,
C = GETCHAR()
; -
, .
C WHILE ,
:

.. , ..

25

MAIN() /* COPY INPUT TO OUTPUT; 2ND VERSION */


INT C;
WHILE ((C = GETCHAR()) != EOF)
PUTCHAR(C);
, C
, . WHILE, .
WHILE . , , ,
WHILE ,
MAIN .
-
GETCHAR - .
- C,
. ,
.
.
,
. != ,
=, ,
!= =. ,

C = GETCHAR()

!= EOF


C = (GETCHAR() != EOF)
, , , C
0 1 , GETCHAR
. 2/.
1.5.3. .
;
.
MAIN()

/* COUNT CHARACTERS IN INPUT */

LONG NC;
NC = 0;
WHILE (GETCHAR() != EOF )
++NC;
PRINTF(%1D\N, NC);

26

.. , ..

++NC;
, ++, . NC = NC + 1 , ++NC
.
. ++
(++NC), (NC++); ,
2, , ++NC, NC++
NC. .

LONG, INT . PDP-11 32767,
INT ,
; C HONEYWELL IBM LONG INT
.
%1D PRINTF ,
LONG .
,
DOUBLE / FLOAT /. FOR
WHILE , .
MAIN()

/* COUNT CHARACTERS IN INPUT */

DOUBLE NC;
FOR (NC = 0; GETCHAR() != EOF; ++NC)
;
PRINTF(%.0F\N, NC);
PRINTF %F FLOAT ,
DOUBLE ; %.0F
.
FOR ,
.
C , FOR .
, , ,
. ,
.
, ,
, WHILE
FOR GETCHAR , ,
, , .. .
. WHILE FOR
, , .. .
, , ,

.. , ..

27

.
, .
WHILE FOR .
1.5.4. .
.
,
\N, .
MAIN()

/* COUNT LINES IN INPUT */

INT C,NL;
NL = 0;
WHILE ((C = GETCHAR()) != EOF)
IF (C ==\N)
++NL;
PRINTF(%D\N, NL);
WHILE IF ,
++NL. IF
, , /
, /. , , .
== C
/ .EQ. /. ,
=,
. C -
, , , .
,
,
; .
, , A - ; ASCII
/ / 65,
. , A , 65:
.
, ,
.
\N
. , \N - ,
; \N -
, .

28

.. , ..

2.
1-6.
, .
1-7.
, ,
.
1.5.5. .

, ,
, ,
, . / -
WC UNIX/
#DEFINE

YES

#DEFINE

NO

MAIN()

/* COUNT LINES, WORDS, CHARS IN INPUT */

INT C, NL, NW, INWORD;


INWORD = NO;
NL = NW = NC = 0;
WHILE((C = GETCHAR()) != EOF)
++NC;
IF (C == \N)
++NL;
IF (C== \!\! C==\N \!\! C==\T)
INWORD = NO;
ELSE IF (INWORD == NO)
INWORD = YES;
++NW;
PRINTF(%D %D %D\N, NL, NW, NC);
, , . INWORD ,
;
, NO.
YES NO 1
0, . ,
, , ,
-

.. , ..

29

, .
,
, .

NL = NW = NC = 0;
. ,
,

. , ,
NC = (NL = (NW = 0));
\!\! OR ,
IF( C== \!\! C==\N \!\! C==\T)
- , - , - ..../
\T /.
&& AND. ,
&& \!\! , ,
, ,
, . ,
C , ,
C ,
. , ,
,
.
ELSE C,
, , ,
IF, .
:
IF () -1 ELSE -2
,
IF-ELSE. , -1;
- -2.
. ,
ELSE , IF ,
.
1-9.
?
K ?
1-10.

30

.. , ..

, ,
.
1-11.
,
; , ,
, .
1.6. .
,
/, , /
. , ,

C.
,
,
. :
MAIN()

/* COUNT DIGITS, WHITE SPACE, OTHERS */

INT C, I, NWHITE, NOTHER;


INT NDIGIT[10];
NWHITE = NOTHER = 0;
FOR (I = 0; I < 10; ++I)
NDIGIT[I] = 0;
WHILE ((C = GETCHAR()) != EOF)
IF (C >= 0 && C <= 9)
++NDIGIT[C-0'];
ELSE IF(C== \!\! C== \N \!\! C== \T)
++NWHITE;
ELSE
++NOTHER;
PRINTF(DIGITS =);
FOR (I = 0; I < 10; ++I)
PRINTF( %D, NDIGIT[I]);
PRINTF(\NWHITE SPACE = %D, OTHER = %D\N,
NWHITE, NOTHER);

INT

NDIGIT[10];

, NDIGIT . C
/ 1, PL/
1/, NDIGIT[0], NDIGIT[1],...,

.. , ..

31

NDIGIT[9]. FOR ,
.
, , ,
, I , .

. , ,
IF( C >= 0 && C <= 9)...
, C , ,
/ C - 0/.
, 0, 1
.. , ,
, 0 9. ,
.
,
CHAR INT,
INT, TAK CHAR
INT. ;
, C -0'- 0 9
, 0 9 C, , ,
NDIGIT.
, ,
- ,

IF (C >= 0 && C <= 9)


++NDIGIT[C-0'];
ELSE IF(C == \!\! C == \N \!\! C == \T)
++NWHITE;
ELSE
++NOTHER;

IF ()
ELSE IF ()
ELSE

,
.
, - ; ,
. /,
, /.

32

.. , ..

, ,
ELSE, . E ELSE
( ),
. IF ELSE

ELSE IF ()
,
, .
SWITCH (), 3,
. ,
, ,
. ,
SWITCH, 3.
1-12.
,
. - ;
.
1.7. .
C
PL/1, ..
,
,
.
.
, ,
; , . C
, ,
.
, , ,
.

PRINTF, GETCHAR PUTCHAR;
. C ,
** PL/1,
POWER(M,N),
N. POWER(2,5) 32. , **,
,
, .

.. , ..

33

POWER
, .
MAIN()

/* TEST POWER FUNCTION */

INT I;
FOR(I = 0; I < 10; ++I)
PRINTF(%D %D %D\N,I,POWER(2,I),POWER(-3,I));
POWER(X,N)
INT X,N;

/* RAISE

N-TH POWER; N > 0

*/

INT I, P;
P = 1;
FOR (I =1; I <= N; ++I)
P = P * X;
RETURN (P);
:
( , )
,


. ,
, ,
, ,
. ,
C- , ,
, .
POWER
PRINTF(%D %D %D\N,I,POWER(2,I),POWER(-3,I));
POWER, ,
, .
POWER(2,I) , 2 I. /
; 4/.
POWER
, .
INT X,N;
.

34

.. , ..


;
. , POWER,
:
.
I P; I POWER I MAIN.
, POWER, MAIN
RETURN, , PL/1.
. -
; RETURN, ,
,
,
.
1-13.

, OWER(C),
C, C- , ,
C-.
1.8. - .
C ,
, , PL/1. C
. ,

/ /, .
, ,
PL/1, ,
, .
, C
;
.
, , , .
,
,
. ,
, POWER
POWER(X,N) /* RAISE
VERSION 2 */
INT X,N;
INT P;

N-TH POWER; N > 0;

.. , ..

35

FOR (P = 1; N > 0; N)
P = P * X;
RETURN (P);
N ;
, . I
. N POWER
, POWER.
,
.
/,
/,

. 5.
,
, , . /
/.
.
- .
1.9. .
- C
.
, ,
.
:
WHILE ( )
IF ( )

,
. , ,
, .
,
.
GETLINE,
; - GETCHAR.
,
. GETLINE
;
, .
, ;

36

.. , ..

, , 1.
, ,
- . , COPY ,
.
,
GETLINE COPY . :
#DEFINE MAXLINE 1000 /* MAXIMUM INPUT
LINE SIZE */
MAIN() /* FIND LONGEST LINE */
INT LEN; /* CURRENT LINE LENGTH */
INT MAX; /* MAXIMUM LENGTH SEEN SO FAR */
CHAR LINE[MAXLINE]; /* CURRENT INPUT LINE */
CHAR SAVE[MAXLINE]; /* LONGEST LINE, SAVED */
MAX = 0;
WHILE ((LEN = GETLINE(LINE, MAXLINE)) > 0)
IF (LEN > MAX)
MAX = LEN;
COPY(LINE, SAVE);
IF (MAX > 0) /* THERE WAS A LINE */ PRINTF(%S, SAVE);
GETLINE(S,LIM) /* GET LINE INTO S,RETURN LENGTH */
CHAR S[];
INT LIM;
INT C, I;
FOR(I=0;I<LIM-1 && (C=GETCHAR())!=EOF && C!=\N;++I)
S[I] = C;
IF (C == \N) S[I] = C;
++I;
S[I] = \0;
RETURN(I);
COPY(S1, S2)
/* COPY S1 TO S2;
ASSUME S2 BIG ENOUGH */
CHAR S1[], S2[];
INT I;
I = 0;

.. , ..

37

WHILE ((S2[I] = S1[I] != \0)


++I;
MAIN GETLINE ,
. GETLINE
CHAR S[];
INT LIM;
, ,
- .
S ,
MAIN . GETLINE RETURN
, POWER.
; , COPY,
- .
, GETLINE
\0 / ,
/. C:
C -
HELLO\N
,
, \0, ,
PRINTF, :
! H ! E ! L ! L !

! \N

! \0 !

%S , PRINTF ,
. COPY, , ,
\0, S2. /
, \0 /.
, , ,
, .
, MAIN, ,
? GETLINE
:
, .
, MAIN
, , ,
. .
GETLINE ,
. GETLINE

38

.. , ..

. COPY
/ /, ,
.
1-14.

,
.
1-15.
80 .
1-16.
,
, , .
1-17.
REVERSE(S),
S . ,
.
1.10. : .
MAIN(LINE, SAVE ..)
MAIN,
MAIN .
; , I
GETLINE I COPY.
, , ,
.
, ,
.
. / 4
,
/.

,
,
. , .

, , ..
,
, . (
COMMON EXTERNAL PL/1).
,
. ,

.. , ..

39

,
,
, , , .
;
.
, ;
EXTERN,
. ,
, LINE, SAVE MAX
.
, .
#DEFINE MAXLINE 1000
/* MAX. INPUT LINE SIZE*/
CHAR
LINE[MAXLINE]; /* INPUT LINE */
CHAR
SAVE[MAXLINE];/* LONGEST LINE SAVED HERE*/
INT
MAX;/*LENGTH OF LONGEST LINE SEEN SO FAR*/
MAIN() /*FIND LONGEST LINE; SPECIALIZED VERSION*/
INT LEN;
EXTERN INT
MAX;
EXTERN CHAR
SAVE[];
MAX = 0;
WHILE ( (LEN = GETLINE()) > 0 )
IF ( LEN > MAX )
MAX = LEN;
COPY();
IF ( MAX > 0 ) /* THERE WAS A LINE */
PRINTF( %S, SAVE );
GETLINE() /* SPECIALIZED VERSION */
INT C, I;
EXTERN CHAR LINE[];
FOR (I = 0; I < MAXLINE-1
&& (C=GETCHAR()) !=EOF && C!=\N; ++I)
LINE[I] = C;
++I;
LINE[I] = \0
RETURN(I)

40

.. , ..

2. , .
,
. ,
, , , .
, .
. -
.
2.1. .
,
.
; .
_ ;
. ;
-
, - .
,
. ,
, ,
.
. ,
IF, ELSE, INT, FLOAT .., :
. ( ).
, ,
, ,
.
2.2. .
C :
CHAR ,
.
INT ,
.
FLOAT .
DOUBLE .
,
INT: SHORT (), LONG () UNSIGNED ( ).
SHORT LONG .
2
N, N - INT; .
:

.. , ..

41

SHORT INT X;
LONG INT Y;
UNSIGNED INT Z;
C INT , .
,
; .
1
!
DEC PDP-11 HONEYWELL IBM 370 6000 8/32
!
ASCII ASCII EBCDIC
CHAR 8-BITS
9-BITS
8
INT 16 36 32
SHORT 16 36 16
LONG 32 36 32
FLOAT 32 36 32
DOUBLE 64 72 64
-------------------------

INTERDATA

ASCII
BITS 8 32
16
32
32
64

!
BITS !
!
!
!
!
!
------------

-------------

, SHORT LONG
;
INT .
, SHORT LONG
. ,
, , SHORT , LONG.
2.3. .
INT FLOAT . ,

123.456-7,

0.123
FLOAT .
DOUBLE,
E FLOAT, DOUBLE.
123L. ,
INT, LONG.
: 0() INT
, 0X
. , 31

42

.. , ..

037 0X1F .

L, LONG.
2.3.1. .
- ,
, , , .
.
, ASCII , 0,
48, EBCDIC - 240,
0. 0 , 48 240,

.
, ,
.
.

, ,
, \N ( ), \T (), \0 ( ), \\ (
), \ ( ) .. ,
. , ,
\DDD
DDD - ,
#DEFINE

FORMFEED

\014

/* FORM FEED */

\0, 0,
0 ,
.
2.3.2.
- , .
,
, ,
, ,
#DEFINE MAXLINE 1000
CHAR LINE[MAXLINE+1];

SECONDS = 60 * 60 * HOURS;

.. , ..

43

2.3.3.
- ,
, , , ,
I AM A STRING

/* - */

/* NULL STRING */

/* - */

, .
,
, ;
\.
,
.
,
- \0. , , ,
, .
,
. STRLEN(S)
S \0.
STRLEN(S) /* RETURN LENGTH OF S */
CHAR S[];
INT I;
I = 0;
WHILE (S[I] != \0)
++I;
RETURN(I);
,
: X - , X. -
, ,
. -
, ( ) \0.
2.4.
,
, .
,
, , ,

44

.. , ..

INT LOWER, UPPER, STEP;


CHAR C, LINE[1000];
;

INT LOWER;
INT UPPER;
INT STEP;
CHAR C;
CHAR LINE[1000];
,
.

, .
,
, , ,
CHAR BACKSLASH = \\;
INT I = 0;
FLOAT EPS = 1.0E-5;
,
,
.

, . ,
, , (.. ).
,
, , .
,
.
2.5. .
+, -, *, /
%. -,
+.
.
X % Y
X Y , , ,
Y . , ,
4, 100, , 400
.

.. , ..

45

IF(YEAR % 4 == 0 && YEAR % 100 != 0 \!\! YEAR % 400 ==


0)
ELSE

% FLOAT DOUBLE.
+ - ,
*, / %,
.
. (
).
+ - ; ,
. , +(B+C)
(A+B)+C. - ,
,
.
, (..
),
.
2.6.

=>

>

=<

<

.
:
==

!=

.
, I<LIM-1
I<(LIM-1), .
&& \!\! . ,
&& \!\!, ,
,
.
. , , GETLINE, 1.
FOR(I=0;I<LIM-1 && (C=GETCHAR()) != \N && C != EOF;
++I)
S[I]=C;

46

.. , ..

, ,
S, I<LIM-1
. ,
.
C EOF
GETCHAR : , .
&& , \!\!,
. ,
I<LIM-1 && (C = GETCHAR()) != \N && C != EOF
.
!= ,

(C = GETCHAR()) != \N
.
!
0, 1.
!
IF( ! INWORD )

IF( INWORD == 0 )
T , . ! INWORD
( ).
.
2-1.
,
FOR, &&.
2.7.
,
.
, ,
, , ,
F+I. , ,
FLOAT , .
-, CHAR INT
: CHAR
INT.
.

.. , ..

47

ATOI,
.
ATOI(S)
/* CONVERT S TO INTEGER */
CHAR S[];
INT I, N;
N = 0;
FOR ( I = 0; S[I]>=0' && S[I]<=9'; ++I)
N = 10 * N + S[I] - 0;
RETURN(N);
KAK 1,
S[I] - 0
S[I] ,
0, 1 ..
.
CHAR INT LOWER,
.
, LOWER
.
ASCII.
LOWER(C) /* CONVERT C TO LOWER CASE; ASCII ONLY */
INT C;
IF ( C >= A && C <= Z )
RETURN( C + @ - A);
ELSE
/*@ A */
RETURN(C);
ASCII,
, ,
,
- Z , .
EBCDIC IBM 360/370 ,
-
.

. , ,
CHAR .
CHAR INT ?
, ,
. (PDP-11, )

48

.. , ..

CHAR, 1,
( ).
,
.
C ,
,

. ,
,
, .

, 1 EOF.
CHAR C;
C = GETCHAR();
IF ( C == EOF )
...
, ,
, CHAR, EOF
, .
, INT CHAR
, GETCHAR.
INT CHAR
- .
GETCHAR (
) , ,
EOF. EOF CHAR,
INT.

, , I>J, ,
&& \!\!, 1,
, 0, . ,
ISDIGIT = C >= 0 && C <= 9;
ISDIGIT 1, - , 0
. ( IF, WHILE, FOR ..
).
,
. , + *,
( ), ,

. ,
.

.. , ..

49

- CHAR SHORT INT, FLOAT DOUBLE.


- , DOUBLE,
DOUBLE, DOUBLE.
- , LONG,
LONG, LONG.
- , UNSIGNED,
UNSIGNED UNSIGNED.
- INT,
INT.
, FLOAT DOUBLE; C
.
;
, .
,
, . INT CHAR
- .
INT I;
CHAR C;
I = C;
C = I;
. ,
.
FLOAT, I INT,
= I;

I = ;
; FLOAT
INT . DOUBLE
FLOAT .
CHAR
.
,
: ,
CHAR SHORT INT, FLOAT DOUBLE.
INT DOUBLE ,
CHAR FLOAT.
, ()
,
(CAST). ,

50

.. , ..

( )

, .
:
,
. ,
SQRT DOUBLE ,
- . , N
- ,
SQRT((DOUBLE) N)
SQRT N DOUBLE.
(, N ;
N ).
,
, .
2-2.
HTOI(S),
.
1 9 F.
2.8.
C
. ++ 1
, 1.
++ , , ,
IF(C == \N)
++I;
, ++
( , ++N),
( : N++).
N. ++N N
, N++ N
, . , ,
, ,
++N N++ . N = 5,
= N++;
5,
= ++N;

.. , ..

51

6. N 6.

; =(I+J)++ .
, ,
, , ,
IF ( C == \N )
NL++;

. ,
. , , SQUEEZE(S,C),
S, , .
SQUEEZE(S,C)
CHAR S[];
INT C;

/* DELETE ALL C FROM S */

INT I, J;
FOR ( I = J = 0; S[I] != \0; I++)
IF ( S[I] != C )
S[J++] = S[I];
S[J] = \0;
, , ,
J, J 1,
.
IF ( S[I] != C )
S[J] = S[I];
J++;
GETLINE,
1,
IF ( C == \N )
S[I] = C;
++I;

IF ( C == \N )
S[I++] = C;
STRCAT(S,T),
S, S .
, S
.

52

.. , ..

STRCAT(S,T)
CHAR S[], T[];

/* CONCATENATE T TO END OF S */
/* S MUST BE BIG ENOUGH */

INT I, J;
I = J = 0;
WHILE (S[I] != \0) / *FIND END OF S */
I++;
WHILE((S[I++] = T[J++]) != \0) /*COPY T*/
;
T T S ,
++
I J.
2-3.
SQUEEZE(S1,S2),
S1 , - S2.
2-4.
ANY(S1,S2),
S1 - S2 ,
S1 S2, -1.
2.9.
;
FLOAT DOUBLE.
& AND
\!
OR
^
OR
<<
>>
\^ ( )
\ .
AND
; ,
C = N & 0177
N , .
OR :
C = X MASK
, MASK.
&
&& \!\! ,

.. , ..

53

. , =1, Y=2, &Y


, X&&Y ./?/
<< >>
,
. , <<2 ,
,
4.
, PDP-11,
/ /, - / /.
\^ ; ,
1 0 .

X & \^077
. ,
X&\^077
, , , X&0177700, ,
16 .
, \^077
, , .
,
GETBITS(X,P,N), /
/ N .
, 0, N . , GETBITS(,4,3) , 4,3 2.
GETBITS(X,P,N) /* GET N BITS FROM POSITION P */
UNSIGNED X, P, N;
RETURN((X >> (P+1-N)) & \^(\^0 << N));
X >> (P+1-N) .
X UNSIGNED ,
,
, ,
. \^0 1; N
\^0<<N N
; \^
N .
2-5.
GETBITS ,
.

54

.. , ..

2-6.
WORDLENGTH(),
, .. INT.
, ..
.
2-7.
RIGHTROT(N,B),
N B .
2-8.
INVERT(X,P,N),
(.. 1 0 ) N X, P,
.
2.10. .
,
I = I + 2


I += 2
+=.
( +,
) =,
-
+

- *

<<

>>

&

\^

\!

1 2 - ,
1 = 2

1 = (1) (2)
, 1
. 2:
X *= Y + 1

X = X * (Y + 1)

.. , ..

55

X = X * Y + 1
BITCOUNT,
1 .
BITCOUNT(N)
UNSIGNED N;

/* COUNT 1 BITS IN N */

(
INT B;
FOR (B = 0; N != 0; N >>= 1)
IF (N & 01)
B++;
RETURN(B);
)
,
,
. : 2 I I 2,
I, 2 I. , I += 2.
, ,
YYVAL[YYPV[P3+P4] + YYPV[P1+P2]] += 2
T ,
,
, ,
.
.
,
;
WHILE ((C = GETCHAR()) != EOF)
, (+=,
-= ..) , .
.
2-9.
X&(X-1)
1 X.(?)
BITCOUNT.
2.11. .

IF (A > B)

56

.. , ..

Z = A;
ELSE
Z = B;
Z . ,
?:,
.
1 ? 2 : 3
1. (),
2,
. 3,
. 2
3. , Z ,
Z = (A > B) ? A : B;

/* Z = MAX(A,B) */

,
,
. 2 3 ,
, . ,
F FLOAT, N - INT,
(N > 0) ? F : N
DOUBLE , N .
?: ,
,
. , ,
.

. , N
, 10 ,
( ) .
OR (I = 0; I < N; I++)
PRINTF(%6D%C,A[I],(I%10==9 \!\! I==N-1) ? \N :
)

N- .
. , , ,
, .
2-10.
LOWER,
, IF-ELSE

.. , ..

57

.
2.12. .
, , .
, ,
; . ,
, *, / % ,
, + -.
OPERATOR
() [] -> .
! \^ ++ - (TYPE) * & SIZEOF
* / %
+ << >>
< <= > >=
== !=
&
^
\!
&&
\!\!
?:
= += -= ETC.
, (CHAPTER 3)

ASSOCIATIVITY
LEFT TO RIGHT
RIGHT TO LEFT
LEFT TO RIGHT
LEFT TO RIGHT
LEFT TO RIGHT
LEFT TO RIGHT
LEFT TO RIGHT
LEFT TO RIGHT
LEFT TO RIGHT
LEFT TO RIGHT
LEFT TO RIGHT
LEFT TO RIGHT
RIGHT TO LEFT
RIGHT TO LEFT
LEFT TO RIGHT

-> . ;
6 SIZEOF ( ). 5
* ( ) & ().
, &,
^ == !=. ,
,
IF ((X & MASK) == 0) ...

.
, ,
(*, +, &, ^,
), ,
.
; , ,

58

.. , ..

.
C, ,
.
X = F() + G();
F, G, ; ,
F, G ,
, X .

.

,
PRINTF(%D %D\N,++N,POWER(2,N));
( )
, N
POWER. , ,

++N;
PRINTF(%D %D\N,N,POWER(2,N));
, ,

-
. , ,
,
.

A[I] = I++;
, I .

. ,
( ), -
,
.
: ,
,
. , , , ,
,
. ( LINT
, .

.. , ..

59

3.
.

C;
, .
3.1.
, X=0, I++, PRINTF(...),
, , , ,
X = 0;
I++;
PRINTF(...);
C ,
, .
/( /)
,
.
, ,
, -
IF, ELSE, WHILE FOR.(
; 4).
, .
3.2. IF - ELSE
IF - ELSE .

IF () -1
ELSE
-2,
ELSE . ;
/.. /,
-1. / /,
ELSE, -1 -2.
IF ,
.
IF ()
IF ( !=0)
,

60

.. , ..

.
, ELSE IF - ELSE ,
, ELSE
IF.
- ELSE IF,
ELSE. ,
IF ( N > 0 )
IF( A > B )
Z = A;
ELSE
Z = B;
ELSE IF, ,
ELSE IF. , ,
:
IF (N > 0)
IF (A > B)
Z = A;
ELSE
Z = B;
T
IF (N > 0)
FOR (I = 0; I < N; I++)
IF (S[I] > 0)
PRINTF(...);
RETURN(I);
ELSE
/* WRONG */
PRINTF(ERROR - N IS ZERO\N);
ELSE IF , ,
ELSE IF.
.
, ,
IF (A > B)
Z = A;
ELSE
Z = B;
Z=A . ,
IF , Z=A,

.. , ..

61

, .
3.3. ELSE - IF

IF ()
ELSEIF ()

ELSEIF ()

ELSE
,
.
IF
.
; - ,
, .
,
.
ELSE ,
.
;
ELSE
, ,
.

, ,
V.
V .
( 0 N-1),
V, -1, V.
BINARY(X, V, N) /* FIND X IN V[0]...V[N-1] */
INT X, V[], N;
INT LOW, HIGH, MID;
LOW = 0;
HIGH = N - 1;
WHILE (LOW <= HIGH)
MID = (LOW + HIGH) / 2;
IF (X < V[MID])
HIGH = MID - 1;

62

.. , ..

ELSE IF (X > V[MID])


LOW = MID + 1;
ELSE /* FOUND MATCH */ RETURN(MID);
RETURN(-1);
,
, V[MID];
ELSE - IF .
3.4.
SWITCH
,
.
1 ,
,
IF...ELSE IF...ELSE.
.
MAIN() /* COUNT DIGITS,WHITE SPACE, OTHERS */
INT C, I, NWHITE, NOTHER, NDIGIT[10];
NWHITE = NOTHER = 0;
FOR (I = 0; I < 10; I++)
NDIGIT[I] = 0;
WHILE ((C = GETCHAR()) != EOF)
SWITCH (C)
CASE 0:
CASE 1:
CASE 2:
CASE 3:
CASE 4:
CASE 5:
CASE 6:
CASE 7:
CASE 8:
CASE 9:
NDIGIT[C-0']++;
BREAK;
CASE :
CASE \N:
CASE \T:
NWHITE++;

.. , ..

63

BREAK;
DEFAULT :
NOTHER++;
BREAK;
PRINTF(DIGITS =);
FOR (I = 0; I < 10; I++)
PRINTF( %D, NDIGIT[I]);
PRINTF(\NWHITE SPACE = %D, OTHER = %D\N,
NWHITE, NOTHER);
(
- )
(CASE). ,
, .
, CASE,
, .
,
DEFAULT. DEFAULT , ,
, .
.
.
BREAK .
,
,
, . BREAK RETURN .
, BREA
WHILE, FOR DO.
,
. ,
, ,
.
BREAK,
.
,
. ,
,
.
BREAK
( DEFAULT),
. ,
, .

64

.. , ..

3-1.
EXPAND(S, T),
S ,
, \N \. .
3.5. - WHILE FOR
WHILE FOR.
WHILE ()
. ,
.
, ,
.

FOR ( 1; 2; 3)

1;
WHILE ( 2) 3;
FOR .
, 1
3 ,
2 - .
, .
1 3, .
, 2, ,
,
FOR (;;)
...
, ,
( BREAK RETURN).
WHILE FOR - , .
WHILE ((C = GETCHAR())
== \!\! C == \N \!\! C == \T)
;
/* SKIP WHITE SPACE CHARACTERS */
, , WHIL
.
FOR, , ,
,
.

.. , ..

65


FOR (I = 0; I < N; I++)
C N
, DO PL/1. ,
, , ,
,
. FOR
,
.
FOR , ,
.

ATOI, .
;
+ -. ( 4 ATOF,
).
:
- ,
- ,
-

.
, .
ATOI(S)
/* CONVERT S TO INTEGER */
CHAR S[];
INT I, N, SIGN;
FOR(I=0;S[I]== \!\!
S[I]==\N \!\! S[I]==\T;I++)
; /* SKIP WHITE SPACE */
SIGN = 1;
IF(S[I] == + \!\! S[I] == -) /* SIGN */
SIGN = (S[I++]==+) ? 1 : - 1;
FOR( N = 0; S[I] >= 0 && S[I] <= 9; I++)
N = 10 * N + S[I] - 0;
RETURN(SIGN * N);

, .
.
, ,
, .

66

.. , ..


. ,

.
SHELL(V, N)
/* SORT V[0]...V[N-1]
INTO INCREASING ORDER */
INT V[], N;
INT GAP, I, J, TEMP;
FOR (GAP = N/2; GAP > 0; GAP /= 2)
FOR (I = GAP; I < N; I++)
FOR (J=I-GAP; J>=0 && V[J]>V[J+GAP]; J-=GAP)
TEMP = V[J];
V[J] = V[J+GAP];
V[J+GAP] = TEMP;
.
, N/2
, .
, ;
.
,
. ,
FOR , ,
.
C ,,
FOR. , ,
,
. ,
FOR , ,
. REVERSE(S),
S .
REVERSE(S) /* REVERSE STRING S IN PLACE */
CHAR S[];
INT C, I, J;
FOR(I = 0, J = STRLEN(S) - 1; I < J; I++, J)
C = S[I];
S[I] = S[J];
S[J] = C;
, ,

.. , ..

67

..,
.
3-2.
EXPAND(S1,S2),
-Z S1
...XYZ S2.
. --, -Z0-9 --Z.
( , -,
, ).
3.6. DO - WHILE
1, WHILE FOR
, ,
. C, DO-WHILE,
, ;
. :
DO

WHILE ()
, .
, ..
, .
, DO-WHILE
, WHILE FOR, .
, , , ,
ITOA, (
ATOI). ,
. ,
.
, .
ITOA(N,S)
CHAR S[];
INT N;

/*CONVERT N TO CHARACTERS IN S */

INT I, SIGN;
IF ((SIGN = N) < 0)
/* RECORD SIGN */
N = -N;
/* MAKE N POSITIVE */
I = 0;
DO /* GENERATE DIGITS IN REVERSE ORDER */

68

.. , ..

S[I++] = N % 10 + 0;/* GET NEXT DIGIT */


WHILE
((N /=10) > 0); /* DELETE IT */ IF (SIGN < 0)
S[I++] = -
S[I] = \0;
REVERSE(S);
DO-WHILE , , ,
N, S .
, DOWHIL, , ,
WHILE WHILE.
3-3.

ITOA , ..
N A -2 -1, - . .
, .
3-4.
ITOB(N,S),
N S.
ITOH, .
3-5.
I, , .
- ; ,
, ,
.
3.7. BREAK

, . BR
FOR, WHILE DO ,
. BR
( ).

. BR
, .
#DEFINE MAXLINE 1000
MAIN()
/* REMOVE TRAILING BLANKS AND TABS */
INT N;
CHAR LINE[MAXLINE];
WHILE ((N = GETLINE(LINE,MAXLINE)) > 0)

.. , ..

69

WHILE (N >= 0)
IF (LINE[N] != && LINE[N] != \T
&& LINE[N] != \N)
BREAK;
LINE[N+1] = \0;
PRINTF(%S\N,LINE);
GETLINE .
LINE (, N N
)
, , .
, , N (.., ). ,
,
.
BR :
WHILE ((N = GETLINE(LINE,MAXLINE)) > 0)
WHILE (N >= 0
&& (LINE[N] == \!\! LINE[N] == \T
\!\! LINE[N] == \N))
;
...
,
. , &&, \!\!, !
, .
3.8. CONTINUE
CONTINUE BR, ;
(FOR,
WHILE, DO ). WHILE DO
; FOR
. ( CONTINUE ,
. CONTINUE
).
,
; .
FOR (I = 0; I < N; I++)
IF (A[I] < 0) /* SKIP NEGATIVE ELEMENTS */
CONTINUE;
... /* DO POSITIVE ELEMENTS */
CONTINUE ,

70

.. , ..

, ,
,
.
3-6.
, ,

. ( UNIQ UNIX).
3.9. GOTO
C GOTO,
, .
GOTO ,
. GOTO .
, , GOTO
. ,
,
, .
BR,
. :
FOR ( ... )
FOR ( ... )
...
IF (DISASTER)
GOTO ERROR;
...
ERROR:
CLEAN UP THE MESS

, .
, ,
. ,
GOTO.

. (
5). :
FOR (I = 0; I < N; I++)
FOR (J = 0; J < M; J++)
IF (V[I][J] < 0)
GOTO FOUND;

.. , ..

71

/* DIDNT FIND */
...
FOUND:
/* FOUND ONE AT POSITION I, J */
...
, GOTO,
, , ,
. ,
:
FOUND = 0;
FOR (I = 0; I < N
FOR (J = 0; J < M
FOUND = V[I][J] <
IF (FOUND)
/* IT WAS AT I-1,
...
ELSE
/* NOT FOUND */
...

&& !FOUND; I++)


&& !FOUND; J++)
0;
J-1 */

, ,
GOTO, .

72

.. , ..

4. .

, ,
.

, ,
, , .
C
; C-
, .

;

. ,
.

/GETCHAR , PUTCHAR/
/SIN, COS, SQRT/.
.
4.1. .

, . /
- GREP UNIX/. ,
THE
NOW IS THE TIME
FOR ALL GOOD
MEN TO COME TO THE AID
OF THEIR PARTY

NOW IS THE TIME
MEN TO COME TO THE AID
OF THEIR PARTY

:
WHILE ( )
IF ( )
,

.. , ..

73

,
.
, ,

. ,
.
- GETLINE, ,
1, - PRINTF,
- . ,
,
. ,
PL/1: INDEX(S,) ,
, S, T, -1, S .
0, 1, C
.
,
INDEX; .
, ,
.
, ,
. , ,
INDEX,
.
5 ,
,
.
GETLINE; 1.
#DEFINE MAXLINE 1000
MAIN() /* FIND ALL LINES MATCHING A PATTERN */
CHAR LINE[MAXLINE];
WHILE (GETLINE(LINE, MAXLINE) > 0)
IF (INDEX(LINE, THE) >= 0)
PRINTF(%S, LINE);
GETLINE(S, LIM) /* GET LINE INTO S, RETURN LENGTH *
CHAR S[];
INT LIM;
INT C, I;
I = 0;
WHILE(LIM>0 && (C=GETCHAR()) != EOF && C != \N)

74

.. , ..

S[I++] = C;
IF (C == \N)
S[I++] = C;
S[I] = \0;
RETURN(I);
INDEX(S,T) /* RETURN INDEX OF T IN S,-1 IF NONE */
CHAR S[], T[];
INT I, J, K;
FOR (I = 0; S[I] != \0; I++)
FOR(J=I, K=0; T[K] !=\0' && S[J] == T[K]; J++;
K++)
;
IF (T[K] == \0)
RETURN(I);
RETURN(-1);
, ( , ),
, , ,
.
, ;

DUMMY ()
.
/
/.
- ,
; .
.

/ /;
.
,
, , .
RETURN
, . RETURN
:
RETURN ()
,

.. , ..

75

. , RETURN
;
.
- ,
,
. E
, ,
- .
, ,
. LINT .
C-,
, .
UNIX, , CC,
1. ,
MAIN., GETLINE.C INDEX. .
CC MAIN.C GETLINE.C INDEX.C
,
MAIN.O, GETLINE.O INDEX.O
, A.OUT .
- , MAIN.C,


CC MAIN.C GETLIN.O INDEX.O
CC . .
, .
4-1.
RINDEX(S,T),
S -1, S T.
4.2. , .
-
. ,
, , ,
WHILE (GETLINE(LINE, MAXLINE) > 0)
, ,
,
. ,
, INT.
CHAR INT,

76

.. , ..

, CHAR.
, .
, -
? , SQRT, SIN COS
DOUBLE;
. , ,
ATF(S), S . ATF
I, 2 3;
,
, ,
./
; , /.
-, ATF ,
INT. FLOAT
DOUBLE, , ATOF FLOAT;
,
, DOUBLE.
, :
DOUBLE ATOF(S) /* CONVERT STRING S TO DOUBLE */
CHAR S[];
DOUBLE VAL, POWER;
INT I, SIGN;
FOR(I=0; S[I]== \!\! S[I]==\N \!\! S[I]==\T;
I++)
;
/* SKIP WHITE SPACE */
SIGN = 1;
IF (S[I] == + \!\! S[I] == -)
/* SIGN */
SIGN = (S[I++] == +) ? 1 : -1;
FOR (VAL = 0; S[I] >= 0 && S[I] <= 9; I++)
VAL = 10 * VAL + S[I] - 0;
IF (S[I] == .)
I++;
FOR (POWER = 1; S[I] >= 0 && S[I] <= 9; I++)
VAL = 10 * VAL + S[I] - 0;
POWER *= 10;
RETURN(SIGN * VAL / POWER);
, , ,
, ATOF , INT .

.. , ..

77

/
/, ,
, , .
#DEFINE
MAXLINE
100
MAIN() /* RUDIMENTARY DESK CALKULATOR */
DOUBLE SUM, ATOF();
CHAR LINE[MAXLINE];
SUM = 0;
WHILE (GETLINE(LINE, MAXLINE) > 0)
PRINTF(\T%.2F\N,SUM+=ATOF(LINE));

DOUBLE

SUM, ATOF();

, SUM DOUBLE , ATOF


, DOUBLE .
, SUM, ATOF(...)
.
ATOF , C
, ,
. ATOF MAIN
,
. ATOF /
/, ,
ATOF DOUBLE, MAIN
, INT , . /
LINT /.
ATOF, , , ATOI
( INT):
ATOI(S)
/* CONVERT STRING S TO INTEGER */
CHAR S[];
DOUBLE ATOF();
RETURN(ATOF(S));
RETURN.

RETURN ()

. RETURN

78

.. , ..

F, DOUBLE, INT,
ATOI INT. ( 2,
INT
).
4-2.
ATOF ,

123.45-6
E
, .
4.3. .
1 ,
, ..
, . ,
.
, , .
,
; .
, .
, . 5 ,

.
,
. ,
,
,
. , , ,
,
, MAX PL/1.
,
,
, .
C - PRINTF .
,
. PRINTF
,
, ,
.
.

.. , ..

79

,
, - ; , ,
( )
.
4.4. .
C ,
, .
,
,
. - ,
, .
, C
.
, ,
( , ),
.
COMON EXTERNAL PL/1. ,
,
, .

, ,
.
- ,
, .
,
,
, . , ,
1,
,
.
. , . .

.
;
. , ,
. , .
, ,
,
,

80

.. , ..

.
.
, ,
. +,-,*,/ = ( ).
, .
;
(1-2)*(4+5)=

12-45+*=

. ;
, (
) ,
. 1 2
, -1. 4 5
,9. -1 9
, -9. = ,
( ).
,,

, .
,
. ,
. , :
WHILE( ,
IF ( )

LSE IF ( )



ELSE

, , ,
, . .
.
MAIN ,
. MAIN

.. , ..

81

, ;
.
,
PUSH ( ) POP ( ), MAIN.
.

; , -, ,
, 3.
#DEFINE MAXOP
20 /* MAX SIZE OF OPERAND,OPERTOR *
#DEFINE NUMBER 0 /* SIGNAL THAT NUMBER FOUND */
#DEFINE TOOBIG 9 /* SIGNAL THAT STRING IS TOO BIG *
MAIN() /* REVERSE POLISH DESK CALCULATOR */
/(
INT TUPE;
CHAR S[MAXOP];
DOUBLE OP2,ATOF(),POP(),PUSH();
WHILE ((TUPE=GETOP(S,MAXOP)) !=EOF);
SWITCH(TUPE) /(
CASE NUMBER:
PUSH(ATOF(S));
BREAK;
CASE +:
PUSH(POP()+POP());
BREAK;
CASE *:
PUSH(POP()*POP());
BREAK;
CASE -:
OP2=POP();
PUSH(POP()-OP2);
BREAK;
CASE /:
OP2=POP();
IF (OP2 != 0.0)
PUSH(POP()/OP2);
ELSE
PRINTF(ZERO DIVISOR POPPED\N);
BREAK;
CASE =:
PRINTF(\T%F\N,PUSH(POP()));
BREAK;
CASE C:
CLEAR();

82

.. , ..

BREAK;
CASE TOOBIG:
PRINTF(%.20S ... IS TOO LONG\N,S)
BREAK;
/)
/)
#DEFINE MAXVAL 100 /* MAXIMUM DEPTH OF VAL STACK */
INT SP = 0;
/* STACK POINTER */
DOUBLE VAL[MAXVAL]; /*VALUE STACK */
DOUBLE PUSH(F)
/* PUSH F ONTO VALUE STACK */
DOUBLE F;
/(
IF (SP < MAXVAL)
RETURN(VAL[SP++] =F); ELSE
/(
PRINTF(ERROR: STACK FULL\N);
CLEAR();
RETURN(0);
/)
/)
DOUBLE POP()
/* POP TOP VALUE FROM STEACK */
/(
IF (SP > 0)
RETURN(VAL[SP]); ELSE
/(
PRINTF(ERROR: STACK EMPTY\N);
CLEAR();
RETURN(0);
/)
/)
CLEAR()
/* CLEAR STACK */
/(
SP=0;
/)
C CLEAR,
PUSH POP. GETOP
.
1, ,
.
, PUSH, POP CLEAR,
. MAIN
, - .
, = ,

.. , ..

83

PUSH(POP());
, , .
, + * , ,
, ,
- / .
4-3.

. /%/
. ,
. . / ,

/.
4.5. , .
, C-,
;
,
. :
,
?
,
?
4.5.1. .
,
. ,
, ,
, ,
, .
.
,
, . , VAL,
SP, PUSH, POP CLEAR ,
, :
INT SP
DOUBLE
DOUBLE
DOUBLE
CLEAR()

= 0;
VAL[MAXVAL];
PUSH(F) ...
POP() ...
...

VAL SP PUSH, POP

84

.. , ..

CLEAR ; .
,
, ,
, , EXTERN.
.
/ , ../;
.

INT SP;
DOUBLE VAL[MAXVAL];
SP VAL,

.
EXTERN
EXTERN

INT SP;
DOUBLE VAL[];

SP
INT, VAL DOUBLE / /
, .
, ,
;
EXTERN . / EXTERN
, /.
.
, EXTERN .
,
VAL SP ,
PUSH, POP CLEAR .
:
1:
INT SP = 0; /* STACK POINTER */
DOUBLE VAL[MAXVAL]; /* VALUE STACK */
2:
EXTERN INT SP;
EXTERN DOUBLE VAL[];
DOUBLE PUSH(F) ...
DOUBLE POP()
...
CLEAR()
...
EXTERN 1
, ;

.. , ..

85

2.

, #INCLUDE,
EXTERN
.
GETOP,
. :
, .
, .
/ / NUMBER , .
,
,
. GETOP /
/ , .
, NUMBER
. , GETOP ,
;
TOOBIG .
GETOP(S, LIM) /* GET NEXT OPRERATOR OR OPERAND */
CHAR S[];
INT LIM;
INT I, C;
WHILE((C=GETCH())== \!\! C==\T \!\! C==\N)
;
IF (C != . && (C < 0 \!\! C > 9))
RETURN(C);
S[0] = C;
FOR(I=1; (C=GETCHAR()) >=0' && C <= 9; I++)
IF (I < LIM)
S[I] = C;
IF (C == .)
/* COLLECT FRACTION */
IF (I < LIM)
S[I] = C;
FOR(I++;(C=GETCHAR()) >=0' && C<=9';I++)
IF (I < LIM)
S[I] =C;
IF (I < LIM)
UNGETCH(C);
S[I] = \0;

/* NUMBER IS OK */

86

.. , ..

RETURN (NUMBER);
ELSE /* ITS TOO BIG; SKIP REST OF LINE */
WHILE (C != \N && C != EOF)
C = GETCHAR();
S[LIM-1] = \0;
RETURN (TOOBIG);
GETCH UNGETCH?
, , , ,
, .
, :
, , .
, , .
,
. ,
,
, ,
. ,
, . GETCH , ; UNGETCH ,
GETCH .
, , .
UNGETCH
, . GETCH
, - ; ,
GETCHAR. ,
.
GETCH
UNGETCH
, .
, GETCH, UNGETCH :
#DEFINE BUFSIZE 100
CHAR BUF[BUFSIZE]; /* BUFFER FOR UNGETCH */
INT BUFP = 0; /* NEXT FREE POSITION IN BUF */
GETCH() /* GET A (POSSIBLY PUSHED BACK) CHARACTER*/
RETURN((BUFP > 0) ? BUF[BUFP] : GETCHAR());
UNGETCH(C) /* PUSH CHARACTER BACK ON INPUT */ INT C;
IF (BUFP > BUFSIZE)
PRINTF(UNGETCH: TOO MANY CHARACTERS\N);

.. , ..

87

ELSE
BUF [BUFP++] = C;
,
,
.
4-4.
UNGETS(S) ,
. UNGETS BUF BUFP
UNGETCH ?
4-5.
, .
GETCH UNGETCH .
4-6.
GETCH UNGETCH EOF . ,
, EOF,
.
4.6. .
,
EXTERN,
.
, .
, ,
, , ,
,
. ,
, .
, , , ,
PRINTF , .

, , - .
, , BUF BUFP
GETCH-UNGETCH,
, GETCH
UNGETCH , .

STATIC CHAR BUF[BUFSIZE]; /* BUFFER FOR UNGETCH */
STATIC INT BUFP=0; /*NEXT FREE POSITION IN BUF */
GETCH() ...
UNGETCH() ...

88

.. , ..

BUF BUFP;
,
.
, , ,
STATIC , .
, , ,
.
;
. , , STATIC ;
, .
C STATIC , ,
.
; /
/ ,
,
.


,
. , GETCH UNGETCH
; BUF BUFP
, .
PUSH, POP CLEAR ; VAR SP
.
4.7. .
.
REGISTER ,
. , , REGISTER,
,
. REGISTER
REGISTER INT X;
REGISTER CHAR C;
..; INT . REGISTER

.
:
F(C,N)
REGISTER INT C,N;
REGISTER INT I;
...

.. , ..

89

,
.
,
.
REGISTER .
( 5).
. , ,
PDP-11 REGISTER
, INT, CHAR .
4.8. .
C PL/1
; .
, ,
. ( )
, ,
, . ,
, ,
,
.
IF (N > 0)
INT I; /* DECLARE A NEW I */
FOR (I = 0; I < N; I++)
...
I IF; I
I .
.

INT X;
F()
DOUBLE X;
...
X F
DOUBLE, F - .
:
INT X;
F(X)
DOUBLE X;
...

90

.. , ..

F X ,
.
4.9. .
,
, . ,
,
, .
,
;
().
( ) ,
:
INT X = 1;
CHAR SQUOTE = \;
LONG DAY = 60 * 24;

/* MINUTES IN A DAY */


, .
.

:
,
. ,
3
BINARY(X, V, N)
INT X, V[], N;
INT LOW = 0;
INT HIGH = N - 1;
INT MID;
...

BINARY(X, V, N)
INT X, V[], N;
INT LOW, HIGH, MID;
LOW = 0;
HIGH = N - 1;
...

.. , ..

91

,
. -
. ,
.
.
,
,
. 1,

MAIN()
/* COUNT DIGITS, WHITE SPACE, OTHERS */
(
INT C, I, NWHITE, NOTHER;
INT NDIGIT[10];
NWHITE = NOTHER = 0;
FOR (I = 0; I < 10; I++)
NDIGIT[I] = 0;
...
)

INT NWHITE = 0;
INT NOTHER = 0;
INT NDIGIT[10] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ;
MAIN()
/* COUNT DIGITS, WHITE SPACE, OTHERS */
(
INT C, I;
...
)
,
, - .
, ,
.
. ,
,
, .

;
:
CHAR PATTERN[] = THE;
, :

92

.. , ..

CHAR PATTERN[] =

T, H, E, \0 ;

,
, .
( \0).
4.10. .
C ; ,
.
.
, :
,
.
. ,
3 ITOA,

. PRINTD
.
PRINTD(N) /* PRINT N IN DECIMAL */
INT N;
CHAR S[10];
INT I;
IF (N < 0)
PUTCHAR(-);
N = -N;
I = 0;
DO
S[I++] = N % 10 + 0; /* GET NEXT CHAR */
WHILE ((N /= 10) > 0); /* DISCARD IT */
WHILE (I >= 0)
PUTCHAR(S[I]);
,
PRINTD ,
, .
PRINTD(N)
INT N;
(
INT I;
IF (N < 0)

/* PRINT N IN DECIMAL (RECURSIVE)*/

.. , ..

93

PUTCHAR(-);
N = -N;
IF ((I = N/10) != 0)
PRINTD(I);
PUTCHAR(N % 10 + 0);
)
,
,
. , PRINTD(123)
PRINTD N = 123. 12 PRINTD,
, 3. PRINTD
1 ( ), 2.
,
- .
.
,
.
, , ;
6.
4-7.
, PRINTD
ITOA; ..
.
4-8.
REVERSE(S),
S.
4.11. C.

.
, , #DEFINE;

.
4.11.1.
#DEFINE
( )
.
#INCLUDE FILENAME

94

.. , ..

FILENAME. ( ).
,
#DEFINE EXTERN .
#INCLUDE.
#INCLUDE
. ,

, , , .
, -TO ,
.
4.11.2.

#DEFINE TES

-
. #DEFINE
, ;
.
; , \
. , #DEFINE,
.
, , .
, , , YES - ,
PRINTF(YES) .
#DEFINE
K, ,
, . ,
,
#DEFINE THEN
#DEFINE BEGIN
#DEFINE END
;

IF (I > 0) THEN
BEGIN
A = 1;
B = 2
END

.. , ..

95

,
.
, , MAX :
#DEFINE MAX(A, B)

((A) > (B) ? (A) : (B))


X = MAX(P+Q, R+S);

X = ((P+Q) > (R+S) ? (P+Q) : (R+S));
,
, .

; MAX
, .
,
MAX, . ;
, , , ,
.
,
. (
#DEFINE SQUARE(X)

X * X

, SQUARE(Z+1)).
:
, ,
.
.
7
-, GETCHAR PUTCHAR
( PUTCHAR ),
.
.
4-9.
SWAP(X, Y),
INT. ( ).

96

.. , ..

5.
- , .
C. ,
,
,
, , .
GOTO,
, .
A, ;
, - .
, ,
.
.
5.1.
,
. , - ,
, INT, - ,
. & ,
= &;
; , .
& ,
&(-1) &3 .
.
*
, . ,
Y INT,
Y = *;
Y , .
= &;
Y = *;
Y ,
Y = X;
, :
INT X, Y;
INT *PX;

.. , ..

97

X Y .

INT *PX;
;
, *PX INT. , PX
*PX, INT.

, .
, . ,
DOUBLE ATOF(), *DP;
, ATOF() *DP DOUBLE.
, ,
.
. , PX
X, *PX ,
X.
Y = *PX + 1
Y , 1 X;
PRINTF(%D\N, *PX)
X;
D = SQRT((DOUBLE) *PX)
D X, SQRT
X DOUBLE. ( 2).

Y = *PX + 1
* & ,
, ,
PX, 1 Y.
,
Y = *(PX + 1)
.
PX X,
*PX = 0
X ,

98

.. , ..

*PX += 1
,
(*PX)++
; ,
, * ++, ,
PX, , .
, ,
, . PY -
INT,
PY = PX
PX PY, PY
, PX.
5.2.

,
. ,
? ,

SWAP.
SWAP(A, B);
SWAP :
SWAP(X, Y) /* WRONG */
INT X, Y;
INT TEMP;
TEMP = X;
X = Y;
Y = TEMP;
- SWAP
A B .
, .

:
SWAP(&A, &B);
& , &A

.. , ..

99

A. SWAP
.
SWAP(PX, PY)
INT *PX, *PY;

/* INTERCHANGE *PX AND *PY */

INT TEMP;
TEMP = *PX;
*PX = *PY;
*PY = TEMP;
,
. ( ,
SWAP O , ).
GETINT, ,
, . GETINT
, ,
. ,
EOF, .
, 7
SCANF, , GETINT
EOF ;
.
, .
.

GETINT:
INT N, V, ARRAY[SIZE];
FOR (N = 0; N < SIZE && GETINT(&V) != EOF; N++)
ARRAY[N] = V;
V
, . ,
GETINT &V V.
V , GETINT
, .
GETINT
ATOI:
GETINT(PN) /* GET NEXT INTEGER FROM INPUT */
INT *PN;

100

.. , ..

INT C,SIGN;
WHILE ((C = GETCH()) == \!\! C == \N
\!\! C == \T); /* SKIP WHITE SPACE */
SIGN = 1;
IF (C == + \!\! C == -) /* RECORD
SIGN */
SIGN = (C == +) ? 1 : -1;
C = GETCH();
FOR (*PN = 0; C >= 0 && C <= 9; C = GETCH())
*PN = 10 * *PN + C - 0;
*PN *= SIGN;
IF (C != EOF)
UNGETCH(C);
RETURN(C);
*PN GETINT
INT. GETCH UNGETCH (
4) , , ,
.
5-1.
GETFLOAT, GETINT
. GETFLOAT
?
5.3.
C
, ,
. ,
, .
,
, .
INT A[10]
10, .. 10
, A[0], A[1], ..., A[9]. A[I]
I . PA - ,

INT *PA

PA = &A[0]

.. , ..

101

, PA A;
, PA A[0].
X = *PA
A[0] X.
PA A,
PA+1 , PA-I
, I , PA,
PA+I , I . , PA
A[0],
*(PA+1)
A[1], PA+I - A[I], *(PA+I) -
A[I].

A. 1 ,
, , , , .
, I PA+I ,
PA.

.
.
. .
, PA=&A[0]
PA = A
, ,
, A[I] *(A+I).
A[I] C
*(A+I); .
& ,
, &A[I] A+I : A+I - I-
A. , PA ,
: PA[I] *(PA+I). , , ,
, .
,
. ,
PA=A PA++ . ,
: A=PA A++, P=&A .
,

102

.. , ..

.
, ,
, .. , .
STRLEN, .
STRLEN(S) /* RETURN LENGTH OF STRING S */
CHAR *S;
INT N;
FOR (N = 0; *S != \0; S++)
N++;
RETURN(N);
S ,
; S++ STRLEN ,
STRLEN .

CHAR S[];
CHAR *S;
; ,
, . ,
, , ,
, ,
. ,
.
,
. , A - ,
F(&A[2])

F(A+2)
F A[2], &A[2], A+2
,
A. F :
F(ARR)
INT ARR[];
...

.. , ..

103

F(ARR)
INT *ARR;
...
F, ,
, .
5.4.
P , ,
, P++ P ,
, P +=I P ,
, I .

.
C ; ,
.

( , ) .
: ALLOC(N)
P, N
,
ALLOC ; FREE(P)
,
. ,
FREE , ,
ALLOC. ,
ALLOC FREE ,
. C
, , ,
, 8 .
, ,
ALLOC
.
,
, ALLOCBUF.
ALLOC FREE.
, ,
.
, .. ,

104

.. , ..

ALLOC FREE, .
;

.
,
ALLOCBUF .
, ALLOCP. ALLOC
N , ,
ALLOCBUF. , ALLOC ALLOCP
(.. ), N,
. FREE(P) ALLOCP
P , P ALLOCBUF.
DEFINE NULL 0 /* POINTER VALUE FOR ERROR REPORT */
DEFINE ALLOCSIZE 1000 /* SIZE OF AVAILABLE SPACE */
TATIC CHAR ALLOCBUF[ALLOCSIZE];/* STORAGE FOR ALLOC */
TATIC CHAR *ALLOCP = ALLOCBUF; /* NEXT FREE POSITION */
HAR *ALLOC(N) /* RETURN POINTER TO N CHARACTERS */
INT N;
(
IF (ALLOCP + N <= ALLOCBUF + ALLOCSIZE)
ALLOCP += N;
RETURN(ALLOCP - N); /* OLD P */
ELSE
/* NOT ENOUGH ROOM */
RETURN(NULL);
)
REE(P)
/* FREE STORAGE POINTED BY P */
HAR *P;
(
IF (P >= ALLOCBUF && P < ALLOCBUF + ALLOCSIZE)
ALLOCP = P;
)
. ,
, ,
NULL (
) ,
.
STATIC CHAR *ALLOCP = ALLOCBUF;
ALLOCP
, ALLOCBUF, ..
.
,

.. , ..

105

STATIC CHAR *ALLOCP = &ALLOCBUF[0];


, .

IF (ALLOCP + N <= ALLOCBUF + ALLOCSIZE)
, ,
N . , ALLOCP
, ALLOCBUF.
, ALLOC
( ). , ALLOC
, ,
. C ,
,
,
. , , NULL,
, . ,
, - .

IF (ALLOCP + N <= ALLOCBUF + ALOOCSIZE)
IF (P >= ALLOCBUF && P < ALLOCBUF + ALLOCSIZE)
. , . P
Q , ,
<, >= .., . ,
P < Q
, P , Q.
== != .
NULL.
, , . , . ,
.
-, ,
.
P + N
N- , P
. , P
; N
P , P. ,

106

.. , ..

PDP-11 1 CHAR, 2 INT SHORT,


4 LONG FLOAT 8 DOUBLE.
: P Q
, P-Q - P Q.

STRLEN:
STRLEN(S) /* RETURN LENGTH OF STRING S */
CHAR *S;
CHAR *P = S;
WHILE (*P != \0)
P++;
RETURN(P-S);
P
S, .
WHILE ,
\0. \0 , WHILE
, 0,
.
WHILE (*P)
P++;
P , P++ P
, . P-S
,
.. . :
FLOAT,
, CHAR, P
FLOAT, P++ P FLOAT. ,
ALLOC,
FLOAT, CHAR, ALLOC FREE
CHAR FLOAT.
, , .
(
, ),
.
, , , ,
FLOAT DOUBLE.
5.5.
, , ,

.. , ..

107

I AM A STRING
.
\0,
. ,
.
-
, , ,
PRINTF (HELLO, WORLD\N);
, , ,
;
PRINTF .
,
. MESSAGE
CHAR *MESSAGE;

MESSAGE = NOW IS THE TIME;
MESSAGE
. ; .
C -
.
,
-,
7.
- STRCPY(S,T),
S.
, , T S
S = T
:
STRCPY(S, T)
CHAR S[], T[];

/* COPY T TO S */

INT I;
I = 0;
WHILE ((S[I] = T[I]) != \0)
I++;
STRCPY .

108

.. , ..

STRCPY(S, T)
CHAR *S, *T;

/* COPY T TO S; POINTER VERSION 1 */

WHILE ((*S = *T) != \0)


S++;
T++;
, STRCPY
S T , .
, ,
, S T \0.
STRCPY ,
. :
STRCPY(S, T)
CHAR *S, *T;

/* COPY T TO S; POINTER VERSION 2 */

WHILE ((*S++ = *T++) != \0)


;
S T . *T++
, T ;
++ T, .
S, S
. , ,
\0, T S.
, \0
,
STRCPY(S, T)
CHAR *S, *T;

/* COPY T TO S; POINTER VERSION 3 */

WHILE (*S++ = *T++)


;
,
. ,
C-.
- STRCMP(S, T),
S , ,
, , S, T.

, S T .
STRCMP(S, T) /* RETURN <0 IF S<T, 0 IF S==T, >0 IF S>T */
CHAR S[], T[];
INT I;

.. , ..

109

IF (S[I++] == \0)
RETURN(0);
RETURN(S[I]-T[I]);
STRCMP :
STRCMP(S, T) /* RETURN <0 IF S<T, 0 IF S==T, >0 IF S>T */
CHAR *S, *T;
FOR ( ; *S == *T; S++, T++)
IF (*S == \0)
RETURN(0);
RETURN(*S-*T);
++ ,
, * ++ , .

*++P
P ,
P,
*P
P.
5-2.
STRCAT 2: STRCAT(S,
T) T S.
5-3.
STRCPY.
5-4.
,
.
GETLINE / 1 4/, ATOI, ITOA
/ 2, 3 4/, REVERSE / 3/, INDEX GETOP / 4/.
5.6. - .
, , -
.
,
, ;
.
, ,

110

.. , ..

, ,
- . ,
, STRSAVE(S), S
, ALLOC,
.
:
CHAR *STRSAVE(S) /* SAVE STRING S SOMEWHERE */
CHAR *S;
CHAR *P, *ALLOC();
IF ((P = ALLOC(STRLEN(S)+1)) != NULL)
STRCPY(P, S);
RETURN(P);
:
*STRSAVE(S) /* SAVE STRING S SOMEWHERE */
CHAR *P;
IF ((P = ALLOC(STRLEN(S)+1)) != NULL)
STRCPY(P, S);
RETURN(P);
,
INT,
.
,

.
. ( LINT
, ).
5.7. .
C ,

.
.
.
, 1- 60- 61-
. : DAY_OF_YEAR , MONTH_DAY
.
, :

.. , ..

111

MONTH_DAY(1977, 60, &M, &D)


M 3 D 1 (1- ).
,
.
,
,
, . :
STATIC INT DAY_TAB[2][13] =
(0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31),
(0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
;
DAY_OF_YEAR(YEAR, MONTH, DAY) /* SET DAY OF YEAR */
INT YEAR, MONTH, DAY;
/* FROM MONTH & DAY */
INT I, LEAP;
LEAP = YEAR%4 == 0 && YEAR%100 != 0 \!\! YEAR%400 == 0;
FOR (I = 1; I < MONTH; I++)
DAY += DAY_TAB[LEAP][I];
RETURN(DAY);
MONTH_DAY(YEAR, YEARDAY, PMONTH, PDAY) /*SET MONTH,DAY */
INT YEAR, YEARDAY, *PMONTH, *PDAY; /* FROM DAY OF YEAR */
LEAP = YEAR%4 == 0 && YEAR%100 != 0 \!\! YEAR%400 == 0;
FOR (I = 1; YEARDAY > DAY_TAB[LEAP][I]; I++)
YEARDAY -= DAY_TAB[LEAP][I];
*PMONTH = I;
*PDAY = YEARDAY;
DAY_TAB DAY_OF_YEAR,
MONTH_DAY, .
DAY_TAB ,
. C
, .

DAY_TAB[I][J]
DAY_TAB [I, J]
.
, .
, .. -

112

.. , ..

.
,
; .
DAY_TAB ,
1 12, 0 11.
, , .
,
;
, , , .
,
13 INT. ,
DAY_TAB F, F :
F(DAY_TAB)
INT DAY_TAB[2][13];
...
,
F :
INT DAY_TAB[][13];

INT (*DAY_TAB)[13];
, 13
. , []
, *; ,
INT *DAY_TAB[13];
13 .
5.8. ;
,
. .

,
SORT UNIX.
3 ,
. ,
, ,

.. , ..

113

,
. ,
.
.
(,
, ALLOC),
.
. , STRCMP.

, ,
. :

.
:



,
,
.

-. , , , .
, .

,
, , -1. , , .
#DEFINE NULL 0
#DEFINE LINES 100 /* MAX LINES TO BE SORTED */
MAIN()
/* SORT INPUT LINES */
\(
CHAR *LINEPTR[LINES]; /*POINTERS TO TEXT LINES */
INT NLINES;
/* NUMBER OF INPUT LINES READ */
IF ((NLINES = READLINES(LINEPTR, LINES)) >= 0) \(
SORT(LINEPTR, NLINES); WRITELINES(LINEPTR, NLINES);
\)
ELSE
PRINTF(INPUT TOO BIG TO SORT\N);
\)

114

.. , ..

#DEFINE MAXLEN 1000


READLINES(LINEPTR, MAXLINES) /* READ INPUT LINES */ CHAR
*LINEPTR[];
/* FOR SORTING */
INT MAXLINES;
\(
INT LEN, NLINES;
CHAR *P, *ALLOC(), LINE[MAXLEN];
NLINES = 0;
WHILE ((LEN = GETLINE(LINE, MAXLEN)) > 0)
IF (NLINES >= MAXLINES)
RETURN(-1);
ELSE IF ((P = ALLOC(LEN)) == NULL)
RETURN (-1);
ELSE \(
LINE[LEN-1] = \0; /* ZAP NEWLINE */ STRCPY(P,LINE);
LINEPTR[NLINES++] = P;
\)
RETURN(NLINES);
\)
,
, .
WRITELINES(LINEPTR, NLINES) /* WRITE OUTPUT LINES */
CHAR *LINEPTR[];
INT NLINES;
\(
INT I;
FOR (I = 0; I < NLINES; I++)
PRINTF(%S\N, LINEPTR[I]);
\)

CHAR *LINEPTR[LINES];
, LINEPTR LINES ,
- CHAR. ,
LINEPTR[I] - , *LINEPTR[I] .
LINEPTR ,
WRITELINES,
, . :
WRITELINES(LINEPTR, NLINES) /* WRITE OUTPUT LINES */
CHAR *LINEPTR[];

.. , ..

115

INT NLINES;
\(
INT I;
WHILE (NLINES >= 0)
PRINTF(%S\N, *LINEPTR++);
\)
*LINEPTR ;
, NLINES
.
, .
3
: ,
. ,
, -
.
SORT(V, N)
/* SORT STRINGS V[0] ... V[N-1] */
CHAR *V[];
/* INTO INCREASING ORDER */
INT N;
\(
INT GAP, I, J;
CHAR *TEMP;
FOR (GAP = N/2; GAP > 0; GAP /= 2)
FOR (I = GAP; I < N; I++)
FOR (J = I - GAP; J >= 0; J -= GAP) \(
IF (STRCMP(V[J], V[J+GAP]) <= 0)
BREAK;
TEMP = V[J];
V[J] = V[J+GAP];
V[J+GAP] = TEMP;
\)
\)
V (
, LINEPTR) ,
TEMP ,
.
,
.
, , , ,
READLINES, LINE,
ALLOC. ,
,
. , -, ,

116

.. , ..


. ,

, , .
1 , WHILE FOR
, ,

, , .
, ,
, .
5-5.
READLINES ,
, MAIN, ,
ALLOC. ?
5.9. .
MONTH_NAME(N),
, N- .
.
MONTH_NAME
.
- .
CHAR *MONTH_NAME(N) /* RETURN NAME OF N-TH MONTH */
INT N;
\(
STATIC CHAR *NAME[] = \(
ILLEGAL MONTH,
JANUARY,
FEBRUARY,
MARCH,
APRIL,
MAY,
JUN,
JULY,
AUGUST,
SEPTEMBER,
OCTOBER,
NOVEMBER,
DECEMBER
\);
RETURN ((N < 1 \!\! N > 12) ? NAME[0] : NAME[N]);
\)

.. , ..

117

NAME ,
LINEPTR .
;
. , I- - , NAME[I].
NAME , .
5.10.

,
NAME .
INT A[10][10];
INT *B[10];
A B ,
A[5][5], B[5][5]
INT. A - : 100
. B, ,
10 ; ,
. ,
10 , - 100
. ,

. :
,
, .
, B
10 ; , - , .
, ,
,
MONTH_NAME, - .
5-6.
DAY_OF_YEAR MONTH_DAY,
.
5.11.
, ,

. MAIN ,

118

.. , ..

. (
ARGC) ,
; (ARGV) , ,
. - .

ECHO,
, . ,

ECHO HELLO, WORLD

HELLO, WORLD
ARGV[0] ,
, ARGC 1.
ARGC 3, ARGV[0], ARGV[1] ARGV[2] ECHO, HELLO, WORLD.
ARGV[1], - ARGV[ARGC-1]. ARGC 1,
.
ECHO:
MAIN(ARGC, ARGV) /* ECHO ARGUMENTS; 1ST VERSION */
INT ARGC;
CHAR *ARGV[];
\(
INT I;
FOR (I = 1; I < ARGC; I++)
PRINTF(%S%C, ARGV[I], (I<ARGC-1) ? : \N);
\)
ARGV ,
,
, . .
MAIN(ARGC, ARGV) /* ECHO ARGUMENTS; 2ND VERSION */
INT ARGC;
CHAR *ARGV[];
\(
WHILE (ARGC > 0)
PRINTF(%S%C,*++ARGV, (ARGC > 1) ? : \N);
\)
ARGV -,

.. , ..

119

, 1 (++ARGV),
ARGV[1], ARGV[0]. ; *ARGV
. ARGC ; , .
:
MAIN(ARGC, ARGV) /* ECHO ARGUMENTS; 3RD VERSION */
INT ARGC;
CHAR *ARGV[];
\(
WHILE (ARGC > 0)
PRINTF((ARGC > 1) ? %S : %S\N, *++ARGV);
\)
, PRINTF
, , .
, .
,
4.
, ,
.
GREP UNIX, ,
.
#DEFINE MAXLINE 1000
MAIN(ARGC, ARGV) /* FIND PATTERN FROM FIRST ARGUMENT */
INT ARGC;
CHAR *ARGV[];
\(
CHAR LINE[MAXLINE];
IF (ARGC != 2)
PRINTF (USAGE: FIND PATTERN\N);
ELSE
WHILE (GETLINE(LINE, MAXLINE) > 0)
IF (INDEX(LINE, ARGV[1] >= 0)
PRINTF(%S, LINE);
\)
,
. ,
. :
, , :
.
- , ,

120

.. , ..

, .
, , , -X,
-N(),
FIND -X -N THE

NOW IS THE TIME
FOR ALL GOOD MEN
TO COME TO THE AID
OF THEIR PARTY.

2:FOR ALL GOOD MEN
,
,
. ,
INDEX ARGV[2],
, ARGV[1], . ,
,
:
FIND -NX THE
:
#DEFINE MAXLINE 1000
MAIN(ARGC, ARGV) /* FIND PATTERN FROM FIRST ARGUMENT */
INT ARGC;
CHAR *ARGV[];
\(
CHAR LINE[MAXLINE], *S;
LONG LINENO = 0;
INT EXCEPT = 0, NUMBER = 0;
WHILE (ARGC > 0 && (*++ARGV)[0] == -)
FOR (S = ARGV[0]+1; *S != \0; S++)
SWITCH (*S) \(
CASE X:
EXCEPT = 1;
BREAK;
CASE N:
NUMBER = 1;
BREAK;
DEFAULT:

.. , ..

121

PRINTF(FIND: ILLEGAL OPTION %C\N, *S);


ARGC = 0;
BREAK;
\)
IF (ARGC != 1)
PRINTF(USAGE: FIND -X -N PATTERN\N);
ELSE
WHILE (GETLIN(LINE, MAXLINE) > 0) \(
LINENO++;
IF ((INDEX(LINE, *ARGV) >= 0) != EXCEPT) \
IF (NUMBER)
PRINTF(%LD: , LINENO);
PRINTF(%S, LINE);
\)
\)
\)
ARGV , ARGC . ,
ARGC 1, *ARGV
. , *++ARGV
; (*++ARGV)[0] - .
, ( ) *++(ARGV[0]).
**++ARGV.
5-7.
ADD,
. ,
ADD 2 3 4 + *
2*(3+4).
5-8.
ENTAB DETAB (
1) ,
. ,
.
5-9.
ENTAB DETAB ,

ENTAB M +N
N ,

122

.. , ..

M. ( )
.
5-10.
TAIL, N
. N 10,
,
TAIL -N
N . ,
N.
,
: , SORT,
.
5.12.
,
, , , .. , , -N
, .
- ,
, ,
, , , . , ,
,
.
.
,
STRCMP, SWAP;
NUMCMP,
, STRCMP.
MAIN SORT.
SORT .
,
.
#DEFINE LINES 100 /* MAX NUMBER OF LINES
TO BE SORTED */
MAIN(ARGC, ARGV) /* SORT INPUT LINES */
INT ARGC;

.. , ..

123

CHAR *ARGV[];
\(
CHAR *LINEPTR[LINES]; /* POINTERS TO TEXT LINES */
INT NLINES; /* NUMBER OF INPUT LINES READ */
INT STRCMP(), NUMCMP(); /* COMPARSION FUNCTIONS */
INT SWAP(); /* EXCHANGE FUNCTION */
INT NUMERIC = 0; /* 1 IF NUMERIC SORT */
IF(ARGC>1 && ARGV[1][0] == - && ARGV[1][1]==N)
NUMERIC = 1;
IF(NLINES = READLINES(LINEPTR, LINES)) >= 0) \(
IF (NUMERIC)
SORT(LINEPTR, NLINES, NUMCMP, SWAP);
ELSE
SORT(LINEPTR, NLINES, STRCMP, SWAP); WRITELINES(LINEPTR,
NLINES);
\) ELSE
PRINTF(INPUT TOO BIG TO SORT\N);
\)
STRCMP, NIMCMP SWAP - ; ,
, & ,
.
.
SORT:
SORT(V, N, COMP, EXCH) /* SORT STRINGS V[0] ... V[N-1]
*/ CHAR *V[];
/* INTO INCREASING ORDER */
INT N;
INT (*COMP)(), (*EXCH)();
\(
INT GAP, I, J;
FOR(GAP = N/2; GAP > 0; GAP /= 2)
FOR(I = GAP; I < N; I++)
FOR(J = I-GAP; J >= 0; J -= GAP) \(
IF((*COMP)(V[J], V[J+GAP]) <= 0)
BREAK;
(*EXCH)(&V[J], &V[J+GAP]);
\)
\)
.
INT (*COMP)() , COMP ,
INT. ;
INT *COMP() , COMP ,
, , , .

124

.. , ..

COMP
IF (*COMP)(V[J], V[J+GAP]) <= 0)
: COMP - ,
*COMP - ,
(*COMP)(V[J], V[J+GAP])
- .
.
STRCMP,
:
NUMCMP(S1, S2) /* COMPARE S1 AND S2 NUMERICALLY */
CHAR *S1, *S2;
\(
DOUBLE ATOF(), V1, V2;
V1 = ATOF(S1);
V2 = ATOF(S2);
IF(V1 < V2)
RETURN(-1);
ELSE IF(V1 > V2)
RETURN(1);
ELSE
RETURN (0);
\)
SWAP,
. ,
, .
SWAP(PX, PY) /* INTERCHANGE *PX AND *PY */
CHAR *PX[], *PY[];
\(
CHAR *TEMP;
TEMP = *PX;
*PX = *PY;
*PY = TEMP;
\)
,
:
.
5-11.
SORT , -R,

.. , ..

125

() . , -R
-N.
5-12.
-F,
,
: ,
,
.
5-13.
-D ( ),
, .
, -F.
5-14.
,
.
. ( -DF
-N ).

126

.. , ..

6. .
- ,
,
. ( , ,
).
: , ,
, (...), , , ..
: ...
, , .

,
,
, , .
, .
, , ,
, .
6.1. .
5.
, , , , , ,
.
:
STRUCT DATE \(
INT DAY;
INT MONTH;
INT YEAR;
INT YEARDAY;
CHARMON_NAME[4];
\);
,
, STRUCT. STRUCT
, (
DAT). .
, , .
,
(.. ),
. ,
.
, ,

.. , ..

127

, ,
.

STRUCT

\( ...\) X,Y,Z;


INT X,Y,Z;
, X , Y Z
.
, ,
- ;
. , ,
. , DATE,
STRUCT

DATE D;

D DATE.
,
:
STRUCT DATE D=\( 4, 7, 1776, 186, JUL\);


.
.
. LEAP ( )
, D,
LEAP = D.YEAR % 4 == 0 && D.YEAR % 100 != 0
\!\! D.YEAR % 400 == 0;

IF (STRCMP(D.MON_NAME, AUG) == 0) ...
,

D.MON_NAME[0] = LOWER(D.MON_NAME[0]);
;
:

128

.. , ..

STRUCT PERSON \(
CHAR NAME[NAMESIZE];
CHAR ADDRESS[ADRSIZE];
LONG ZIPCODE;
/* */
LONG SS_NUMBER; /* . */
DOUBLE SALARY; /* */
STRUCT DATE BIRTHDATE; /* */
STRUCT DATE HIREDATE; /* */
\);
PERSON DATE .
EMP
STRUCT PERSON EMP;

EMP.BIRTHDATE.MONTH
.
. .
6.2. .
C .
, ,
,
& .
, ,
. (
).
,
. ,
, , ;
.
,
,
.
,
, .
DAY_OF_YEAR,
5:
D.YEARDAY = DAY_OF_YEAR(D.YEAR, D.MONTH, D.DAY);
.
HIREDATE

.. , ..

STRUCT

129

DATE HIREDATE;

DAY_OF_YEAR ,
HIREDATE YEARDAY = DAY_OF_YEAR(&HIREDATE);
HIREDATE DAY_OF_YEAR .
,
, .
DAY_OF_YEAR(PD) /* SET DAY OF YEAR FROM MONTH, DAY */
STRUCT DATE *PD;
\(
INT I, DAY, LEAP;
DAY = PD->DAY;
LEAP = PD->YEAR % 4 == 0 && PD->YEAR % 100 != 0
\!\! PD->YEAR % 400 == 0;
FOR (I =1; I < PD->MONTH; I++)
DAY += DAY_TAB[LEAP][I];
RETURN(DAY);
\)

STRUCT DATE *PD;


, PD DATE. ,

PD->YEAR
. P - , P->
. ( -> - ,
>.)
PD , YEAR

(*PD).YEAR
, ->
. (*PD).YEAR , , * .
, -> ., ,

P->Q->MEMB (P->Q)->MEMB
EMP.BIRTHDATE.MONTH
(EMP.BIRTHDATE).MONTH

130

.. , ..

, MONTH_DAY, .
MONTH_DAY(PD) /* SET MONTH AND DAY FROM DAY OF YEAR */
STRUCT DATE *PD;
\(
INT I, LEAP;
LEAP = PD->YEAR % 4 == 0 && PD->YEAR % 100 != 0
\!\! PD->YEAR % 400 == 0;
PD->DAY = PD->YEARDAY;
FOR (I = 1; PD->DAY > DAY_TAB[LEAP][I]; I++)
PD->DAY -= DAY_TAB[LEAP][I];
PD->MONTH = I;
\)
-> . ()
[]
, , . , ,

STRUCT \(
INT X;
INT *Y;
\) *P;

++P->X
, , ++(P->).

: (++P)-> P , (P++)->X P
. ( . ?)
*P->Y , Y; *P->Y++
Y , ( ,
*S++); (*P->Y)++ , Y; *P++->Y
P , Y.
6.3. .

. , ,
C.
.
KEYWORD
KEYCOUNT:

.. , ..

131

CHAR *KEYWORD [NKEYS];


INT KEYCOUNT [NKEYS];
, ,
. :
CHAR *KEYWORD;
INT KEYCOUNT;
, , .
STRUCT KEY \(
CHAR *KEYWORD;
INT KEYCOUNT; \) KEYTAB [NKEYS];
KEYTAB
. .
:
STRUCT KEY \(
CHAR *KEYWORD;
INT KEYCOUNT; \);
STRUCT KEY KEYTAB [NKEYS];
KEYTAB
,
.
-
:
STRUCT KEY \(
CHAR *KEYWORD;
INT KEYCOUNT; \) KEYTAB[] =\(
BREAK, 0,
CASE, 0,
CHAR, 0,
CONTINUE, 0,
DEFAULT, 0,
/* ... */
UNSIGNED, 0,
WHILE, 0
\);

.
:
\( BREAK, 0 \),

132

.. , ..

\( CASE, 0 \),
. . .

,
. ,
KEYTAB, ,
[] .

KEYTAB. ,
GETWORD,
. KEYTAB
, 3. (,
,
).
#DEFINE
MAXWORD
20
MAIN()
/* COUNT C KEYWORDS */
\(
INT N, T;
CHAR WORD[MAXWORD];
WHILE ((T = GETWORD(WORD,MAXWORD)) != EOF)
IF (T == LETTER)
IF((N = BINARY(WORD,KEYTAB,NKEYS)) >= 0)
KEYTAB[N].KEYCOUNT++;
FOR (N =0; N < NKEYS; N++)
IF (KEYTAB[N].KEYCOUNT > 0)
PRINTF(%4D %S\N,
KEYTAB[N].KEYCOUNT, KEYTAB[N].KEYWORD);
\)
BINARY(WORD, TAB, N) /* FIND WORD IN TAB[0]...TAB[N-1]
*/
CHAR *WORD;
STRUCT KEY TAB[];
INT N;
\(
INT LOW, HIGH, MID, COND;
LOW = 0;
HIGH = N - 1;
WHILE (LOW <= HIGH) \(
MID = (LOW+HIGH) / 2;
IF((COND = STRCMP(WORD, TAB[MID].KEYWORD)) < 0)
HIGH = MID - 1;
ELSE IF (COND > 0)
LOW = MID + 1;

.. , ..

133

ELSE
RETURN (MID);
\)
RETURN(-1);
\)
GETWORD; ,
LETTER , ,
.
NKEYS - KEYTAB .
,
, ,
.

KEYTAB, .
,
, .

SIZE OF KEYTAB / SIZE OF STRUCT KEY
, C
SIZEOF, ,
.
SIZEOF(OBJECT)
, . (
, ,
, CHAR).
, ,
, INT DOUBLE, , .
,
. #DEFINE NKEYS:
#DEFINE NKEYS (SIZEOF(KEYTAB) / SIZEOF(STRUCT KEY))
GETWORD.
GETWORD, ,
. GETWORD
, , , .
; - LETTER, , EOF
, .
GETWORD(W, LIM)

/* GET NEXT WORD FROM INPUT */

134

.. , ..

CHAR *W;
INT LIM;
\(
INT C, T;
IF (TYPE(C=*W++=GETCH()) !=LETTER) \(
*W=\0';
RETURN(C);
\)
WHILE (LIM > 0) \(
T = TYPE(C = *W++ = GETCH());
IF (T ! = LETTER && T ! = DIGIT) \(
UNGETCH(C);
BREAK;
\)
\)
*(W-1) - \0;
RETURN(LETTER);
\)
GETWORD GETCH UNGETCH,
4: ,
GETWORD . UNGETCH
.
GETWORD TYPE
. ,
ASCII.
TYPE(C) /* RETURN TYPE OF ASCII CHARACTER */
INT C;
\(
IF (C>= A && C<= Z \!\! C>= A && C<= Z)
RETURN(LETTER);
ELSE IF (C>= 0 && C<= 9)
RETURN(DIGIT);
ELSE
RETURN(C);
\)
LETTER DIGIT ,
, , EOF;
#DEFINE
#DEFINE

LETTER
DIGIT

A
0

GETWORD ,

.. , ..

135

TYPE
TYPE[ ]. C
ISALPHA ISDIGIT, .
6-1.
GETWORD ,
.
6-2.
TYPE,
.
6-3.
,
.
6.4. .
,
,
, ,
.
KEYTAB ,
MAIN BINARY .
MAIN()
/* COUNT C KEYWORD; POINTER VERSION */
\(
INT T;
CHAR WORD[MAXWORD];
STRUCT KEY *BINARY(), *P;
WHILE ((T = GETWORD(WORD, MAXWORD;) !=EOF)
IF (T==LETTER)
IF ((P=BINARY(WORD,KEYTAB,NKEYS)) !=NULL)
P->KEYCOUNT++;
FOR (P=KEYTAB; P>KEYTAB + NKEYS; P++)
IF (P->KEYCOUNT > 0)
PRINTF(%4D %S/N, P->KEYCOUNT, P->KEYWORD);
\)
STRUCT KEY *BINARY(WORD, TAB, N) /* FIND WORD */ CHAR
*WORD
/* IN TAB[0]...TAB[N-1] */ STRUCT KEY TAB [];
INT N;
\(
INT COND;
STRUCT KEY *LOW = &TAB[0];
STRUCT KEY *HIGH = &TAB[N-1];
STRUCT KEY *MID;

136

.. , ..

WHILE (LOW <= HIGH) \(


MID = LOW + (HIGH-LOW) / 2;
IF ((COND = STRCMP(WORD, MID->KEYWORD)) < 0)
HIGH = MID - 1;
ELSE IF (COND > 0)
LOW = MID + 1;
ELSE
RETURN(MID);
\)
RETURN(NULL);
\)
, . -,
BINARI ,
KEY, ; MAIN,
BINARY. BINARI ,
; , NULL.
-, KEYTAB
.
BINARY:
MID = (LOW + HIGH) / 2
-
( 2)
.
MID = LOW + (HIGH-LOW) / 2
MID ,
LOW HIGH.
LOW HIGH.
;
.
MAIN
FOR (P=KEYTAB; P < KEYTAB + NKEYS; P++)
P ,
P , P++
P , P
. ,
, - -
.
, , .
, , ,

.. , ..

137

STRUCT KEY *BINARY(WORD, TAB, N)


T , .
:
STRUCT KEY *
BINARY(WORD, TAB, N)
; ,
, .
6.5. , .
, ,
.
,
.
,
, ;
. ( ,
). ,
?
,
,
. O ,
, -
. ,
.
;
:




;
.
,
, ,
, . ,
,
, . ,
. ,
;
. ,

138

.. , ..

, .
,
.
.
, ,
:
STRUCT TNODE \( /* THE BASIC NODE */
CHAR *WORD; /* POINTS TO THE TEXT */
INT
COUNT; /* NUMBER OF OCCURRENCES */
STRUCT TNODE *LEFT; /* LEFT CHILD */
STRUCT TNODE *RIGHT; /* RIGHT CHILD */
\);
,
.
,
STRUCT TNODE *LEFT;
LEFT , .
, ,
, ,
. GETWORD
ALLOC
.

GETWORD , TREE.
#DEFINE
MAXWORD
20
MAIN()
/* WORD FREGUENCY COUNT */
\(
STRUCT TNODE *ROOT, *TREE();
CHAR WORD[MAXWORD];
INT
T;
ROOT = NULL;
WHILE ((T = GETWORD(WORD, MAXWORD)) \! = EOF)
IF (T == LETTER)
ROOT = TREE(ROOT, WORD);
TREEPRINT(ROOT);
\)
TREE . MAIN
() .
, ,
TREE ,

.. , ..

139

. - ,
( ),
,
.
TREE ,
.
STRUCT TNODE *TREE(P, W)
/* INSTALL W AT OR BELOW P */
STRUCT TNODE *P;
CHAR *W;
\(
STRUCT TNODE *TALLOC();
CHAR *STRSAVE();
INT COND;
IF (P == NULL) \( /* A NEW WORD
HAS ARRIVED */
P == TALLOC(); /* MAKE A NEW NODE */
P->WORD = STRSAVE(W);
P->COUNT = 1;
P->LEFT = P->RIGHT = NULL;
\) ELSE IF ((COND = STRCMP(W, P->WORD)) == 0)
P->COUNT++;
/* REPEATED WORD */
ELSE IF (COND < 0)/* LOWER GOES INTO LEFT SUBTREE */
P->LEFT = TREE(P->LEFT, W);
ELSE/* GREATER INTO RIGHT SUBTREE */
P->RIGHT = TREE(P->RIGHT, W);
RETURN(P);
\)
TALLOC,
ALLOC, .
,
. ( ).
STRSAVE ,
, .
.
STRSAVE
TALLOC ( ).
TREEPRINT , ;
( ,
), , ( ,
). ,
TREEPRINT ;

140

.. , ..

, .
TREEPRINT (P) /* PRINT TREE P RECURSIVELY */
STRUCT TNODE *P;
\(
IF (P != NULL)
\(
TREEPRINT (P->LEFT);
PRINTF(%4D %S\N, P->COUNT, P->WORD);
TREEPRINT (P->RIGHT);
\)
\)
: , ,
. ,
,
. ,
2-3 AVL ,
, .
,
. ,
,
.

CHAR STRUCT TNODE, . :
,

(,
)? : , ,
ALLOC ?
,
, ,
,
. , PDP-11 ,
ALLOC ,
. -
.
. , ALLOC
, . ALLOC
5 ; 8
, .
ALLOC
, .

.. , ..

141

C - , ALLOC
CHAR,
. , P
CHAR *P;
(STRUCT TNODE *) P

TNODE . , TALLOC :
STRUCT TNODE *TALLOC()
\(
CHAR *ALLOC();
RETURN ((STRUCT TNODE *) ALLOC(SIZEOF(STRUCT TNODE)));
\)

, .
6-4.
, C-
,
, - . ( ,
7 ).
6-5.
, .. ,

, .
6-6.
, ,
.
.
6.6. .

,
.

. , , #DEFINE C.

#DEFINE YES

YES 1 . ,
YES

142

.. , ..

INWORD = YES;
O 1.
,
. INSTALL(S,T) S
T ; S T .
LOOKUP(S) S ,
, NULL, .
-
,
.
, ,
.
, NULL.
,
, .
.
STRUCT NLIST \( /* BASIC TABLE ENTRY */
CHAR *NAME;
CHAR *DEF;
STRUCT NLIST *NEXT; /* NEXT ENTRY IN CHAIN */
\);

DEFINE
HASHSIZE
100
TATIC STRUCT NLIST *HASHTAB[HASHSIZE] /* POINTER TABLE
*/
,
LOOKUP INSTALL ,
. (
,
).
HASH(S)
/* FORM HASH VALUE FOR STRING */
CHAR *S;
\(
INT HASHVAL;
FOR (HASHVAL = 0; *S != \0; )
HASHVAL += *S++;
RETURN(HASHVAL % HASHSIZE);
\)

.. , ..

143

HASHTAB ; - ,
, .
LOOKUP. LOOKUP ,
, ; ,
NULL.
STRUCT NLIST *LOOKUP(S) /* LOOK FOR S IN HASHTAB */
CHAR *S;
\(
STRUCT NLIST *NP;
FOR (NP = HASHTAB[HASH(S)]; NP != NULL;NP=NP->NEXT)
IF (STRCMP(S, NP->NAME) == 0) RETURN(NP); /* FOUND IT */
RETURN(NULL);
/* NOT FOUND */
INSTALL LOOKUP ,
; ,
.
. -
, INSTALL NULL.
STRUCT NLIST *INSTALL(NAME, DEF) /* PUT (NAME, DEF) */
CHAR *NAME, *DEF;
\(
STRUCT NLIST *NP, *LOOKUP();
CHAR *STRSAVE(), *ALLOC();
INT HASHVAL;
IF((NP = LOOKUP(NAME)) == NULL) \( /* NOT FOUND */
NP = (STRUCT NLIST *) ALLOC(SIZEOF(*NP));
IF (NP == NULL)
RETURN(NULL);
IF ((NP->NAME = STRSAVE(NAME)) == NULL)
RETURN(NULL);
HASHVAL = HASH(NP->NAME);
NP->NEXT = HASHTAB[HASHVAL];
HASHTAB[HASHVAL] = NP;
\)
ELSE/* ALREADY THERE */
FREE((NP->DEF);/* FREE PREVIOUS DEFINITION */
IF ((NP->DEF = STRSAVE(DEF)) == NULL)
RETURN (NULL);
RETURN(NP);
\)
STRSAVE ,
, ,

144

.. , ..

ALLOC. 5.
ALLOC FREE
, ALLOC 5
; 7 8.
6-7.
,
, LOOKUP INSTALL.
6-8.
, ,
#DEFINE ,
C-.
GETCHAR UNGETCH.
6.7. .
,

; ,
. ,

.
,
.
, , ,
/ ..
-
CHAR INT.
, ,
, ,
#DEFINE
#DEFINE
#DEFINE

KEYWORD
01
EXTERNAL 02
STATIC 04

( ).
,
, 2.
:
FLAGS \!= EXTERNAL

\! STATIC;

EXTERNAL STATIC FLAGS,


FLAGS &= \^(XTERNAL \! STATIC);

.. , ..

145

,
IF ((FLAGS & (EXTERNAL \! STATIC)) == 0) ...
, .
, C

, .
- INT.
. , #DEFINE, ,
:
STRUCT \(
UNSIGNED IS_KEYWORD : 1;
UNSIGNED IS_EXTERN : 1;
UNSIGNED IS_STATIC : 1;
\) FLAGS;
FLAGS,
1- . .
UNSIGNED, ,
.
, FLAGS.IS_STATIE, FLAGS.
IS_EXTERN, FLAGS.IS_KEYWORD .., ,
.
, .
, :
FLAGS.IS_EXTERN = FLAGS.IS_STATIC = 1;
;
FLAGS.IS_EXTERN = FLAGS.IS_STATIC = 0;
;
IF (FLAGS.IS_EXTERN == 0 &&FLAGS.IS_STATIC == 0)...
.
INT; ,
, INT.
; ( )
.
INT, 0.
,
. - ,
,

146

.. , ..

, .
,
,
, .
, : ;
INT (, ,
UNSIGNED); ; ,
&.
6.8. .
O - ,
,
.
,
- .
, ,
, INT , FLOAT
.
,
,
.
- ,

. , .
UNION U_TAG \(
INT IVAL;
FLOAT FVAL;
CHAR *PVAL;
\) UVAL;
UVAL ,
, ,
, -
. UVAR
, :
.
- ,
; - , ,
.

:
.

.. , ..

147

->
, .
, UVAL, UTYPE,
:
IF (UTYPE == INT)
PRINTF(%D\N,
UVAL.IVAL);
ELSE IF (UTYPE
== FLOAT)
PRINTF(%F\N,
UVAL.FVAL);
ELSE IF (UTYPE
== STRING)
PRINTF(%S\N,
UVAL.PVAL);
ELSE
PRINTF(BAD TYPE %D IN UTYPE\N, UTYPE);
.
( )
, .
, ,
STRUCT \(
CHAR *NAME;
INT FLAGS;
INT UTYPE;
UNION \(
INT IVAL;
FLOAT FVAL;
CHAR *PVAL;
\) UVAL;
\) SYMTAB[NSYM];
IVAL
SYMTAB[I].UVAL.IVAL
PVAL
*SYMTAB[I].UVAL.PVAL
,
. ,
, ,
. , ,
,
; ,
.
, .

148

.. , ..

, 8 , ,
,
.
6.9.
C , TYPEDEF
. ,
TYPEDEF INT LENGTH;
LENGTH INT. LENGTH
, ..
, INT:
LENGTH
LENGTH

LEN, MAXLEN;
*LENGTHS[];


TYPEDEF CHAR *STRING;
STRING CHAR*,
,
STRING P, LINEPTR[LINES], ALLOC();
, TYPEDEF
, TYPEDEF.
TYPEDEF
EXTERN, STATIC . . ,
.

TYPEDEF , :
TYPEDEF STRUCT TNODE \( /* THE BASIC NODE */
CHAR *WORD; /* POINTS TO THE TEXT */
INT COUNT; /* NUMBER OF OCCURRENCES */
STRUCT TNODE *LEFT;
/* LEFT CHILD */
STRUCT TNODE *RIGHT;
/* RIGHT CHILD */
\) TREENODE, *TREEPTR;
: TREENODE
() TREEPTR ( ). TALLOC

TREEPTR TALLOC()
\(

.. , ..

149

CHAR *ALLOC();
RETURN((TREEPTR) ALLOC(SIZEOF(TREENODE)));
\)
, TYPEDEF
- ;
.
:
, , .
TYPEDEF #DEFINE ,

,
C. ,
TYPEDEF INT (*PFI) ();
PFI ,
INT,
5
PFI STRCMP, NUMCMP, SWAP;
TYPEDEF.
,
. ,
-, TYPEDEF,
.

TYPEDEF
SHORT, INT LONG .
TYPEDEF - TREEPTR
, ,
.
, ,
, LINT,
TYPEDEF
.

150

.. , ..

7.
/ ,
.
,
.
/, ,
/ - .
,
,
.
,
, . , ,
,
, ,
,
, ,
.
/;
,
-, .
7.1.
,
,
#INCLUDE <STDIO.H>
STDIO.H ,
/.
-
, (
UNIX LUSRLINELUDE).
,
; PDP-11 UNIX, ,
:
CC

.. -LS

-LS .
7.2. - GETCHAR
PUTCHAR

.. , ..

151

, ,
GETCHAR. GETCHAR()
. ,
,
< : PROG
GETCHAR
PROG<INFILE
, PROG INFILE, .
, PROG
; <INFILE
ARGV.
,
(PIPE) ;
OTHERPROG \! PROG
, OTHERPROG PROG, ,
PROG OTHERPROG.
GETCHAR EOF,
, .
EOF -1 (
#DEFINE STDIO.H), EOF,
-1, .
PUTCHAR(C),
,
.
> : PROG PUTCHAR,
PROG>OUTFILE
OUTFILE,
. UNIX
.
PROG \! ANOTHERPROG
PROG
ANOTHERPROG. PROG
.
, PRINTF,
, PUTCHAR PRINTF .

;
GETCHAR, PUTCHAR PRINTF

152

.. , ..

.
,

. , , LOWER,
:
#INCLUDE <STDIO.H>
MAIN() /* CONVERT INPUT TO LOWER CASE */
\(
INT C;
WHILE ((C = GETCHAR()) != EOF)
PUTCHAR(ISUPPER(C) ? TOLOWER(C) : C);
\)
ISUPPER TOLOWER ,
STDIO.H . ISUPPER ,
, ,
, . TOLOWER
.
, , ,
.
,
, CAT UNIX,
CAT FILE1 FILE2 ... \! LOWER>OUTPUT
,
. ( CAT ).
, /
GETCHAR PUTCHAR .

. 8 ,
.
7.3. - PRINTF
: PRINTF SCANF ( )

E .
.
PRINTF;
.
PRINTF(CONTROL, ARG1, ARG2, ...)

.. , ..

153

,
CONTROL.
: ,
, ,
PRINTF.

% . %
:
- ,
.
- , .
,
, .
, ,
( , )
.
, ,
(
).
- , .
- (),
, ,
FLOAT DOUBLE.
- L, ,
LONG, INT.
:
D - .
O -
( ).
X -
( 0X).
U - .
C - .
S - : ,

, .
E - , FLOAT
DOUBLE,
[-]M.NNNNNNE[+-]XX, N
. 6.
F - , FLOAT
DOUBLE,
[-]MMM.NNNNN, N

154

.. , ..

. 6. ,
F .
G - %E %F, ;
.
% ,
; , % , %%.

.
, .
HELLO,
WORLD (12 ).
, .
:%10S:
:%10-S:
:%20S:
:%-20S:
:%20.10S:
:%-20.10S:
:%.10S:

:HELLO, WORLD:
:HELLO, WORLD:
:
HELLO, WORLD:
:HELLO, WORLD
:
:
HELLO, WOR:
:HELLO, WOR
:
:HELLO, WOR:

: PRINTF
.

, .
7-1.
,
.
(
) .
7.4. - SCANF
SCANF PRINTF

.
SCANF(CONTROL, ARG1, ARG2, ...)
,
, CONTROL,
. ;
, , ,
.
,

. :

.. , ..

155

- , (
), .
- ( %),

.
- , %, *, ,
.

. ,
. , ,
* ,
.
, ;
,
, . ,
, SCANF ,
.
;

.
: D -
; .
O - (
); .
X - ( 0X
); .
H - SHORT;
SHORT.
C - ;
;
.
; ,
, %1S.
S - ;
, ,
\0.
F - ;
FLOAT.
- E F.
FLOAT , ,
,
E, , .

156

.. , ..

D, O X L,
,
LONG, INT. , L
E F, , DOUBLE, FLOAT.
,
INT I;
FLOAT X;
CHAR NAME[50];
SCANF(&D %F %S, &I, &X, NAME);

25

54.32E-1

THOMPSON

I 25,X - 5.432
NAME - THOMPSON,
\ 0. ,
, .
INT I;
FLOAT X;
CHAR NAME[50];
SCANF(%2D %F %*D %2S, &I, &X, NAME);

56789 0123 45A72
I 56, X - 789.0, 0123 NAME
45.
A. NAME
, , &.

4, SCANF:
#INCLUDE <STDIO.H>
MAIN()
/* RUDIMENTARY DESK CALCULATOR */
\(
DOUBLE SUM, V;
SUM =0;
WHILE (SCANF(%LF, &V) !=EOF)
PRINTF(\T%.2F\N, SUM += V);
\)
SCANF , ,

.. , ..

157

. .
. EOF; ,
0,
. SCANF
.
: SCANF
.

SCANF(%D, N);

SCANF(%D, &N);
7.5.
SCANF PRINTF SSCANF SPRINTF,
,
, . :
SPRINTF(STRING, CONTROL, ARG1, ARG2, ...)
SSCANF(STRING, CONTROL, ARG1, ARG2, ...)
, SPRINTF ARG1,
ARG2 .. , CONTROL, STRING, . K,
STRING , . ,
NAME - , N - ,
SPRINTF(NAME, TEMP%D, N);
NAME TEMPNNN, NNN - N.
SSCANF -
STRING CONTROL ARG1, ARG2 ..
.
SSCANF(NAME, TEMP%D, &N);
N ,
TEMP NAME.
7-2.
4,
SCANF / SSCANF.

158

.. , ..

7.6.

, ,
.
- ,
, .
, ,
CAT,
. CAT
,
. ,
CAT X.C.Y.C
X.C Y.C .
, ,
.., , ,
.
.
,
FOPEN . FOPEN
( X.C Y.C),
(
) ,
.
, ,
, ,
, ,
.
,
-, STDIO.H,
FILE.
:
FILE *FOPEN(), *FP;
, FP FILE FOPEN
FILE. O , FILE ,
INT, ; TYPEDEF. ( ,
UNIX, 8).
FOPEN :
FP=FOPEN(NAME,MODE);
FOPEN ,

.. , ..

159

. MODE ()
, , .
: (R), (W) (A).
, ,
, ( ).

. .
(,
, ). -
NULL (
STDIO.H).
,
. , GETC
PUTC . GETC
; , ,
. ,
C=GETC(FP)
C ,
FP, EOF, .
PUTC, GETC,
PUTC(C,FP)
C FP C.
GETCHAR PUTCHAR, GETC PUTC , .
,
.
, ; STDIN, STDOUT STDERR.
, STDIN STDOUT
(PIPE), 7.2.
GETCHAR PUTCHAR
GETC, PUTC, STDIN STDOUT : #DEFINE GETCHAR()
GETC(STDIN) #DEFINE PUTCHAR(C) PUTC(C, STDOUT)

FSCANF FPRINTF. SCANF PRINTF,
, ,
,
; .
,
CAT .
:
, . -

160

.. , ..

, .
, .
#INCLUDE <STDIO.H>
MAIN(ARGC, ARGV)
/*CAT: CONCATENATE FILES*/
INT ARGC;
CHAR *ARGV[];
\(
FILE *FP, *FOPEN();
IF(ARGC==1) /*NO ARGS; COPY STANDARD INPUT*/
FILECOPY(STDIN);
ELSE
WHILE (ARGC > 0)
IF ((FP=FOPEN(*++ARGV,R))==NULL) \(
PRINTF(CAT:CANT OPEN %\N,*ARGV);
BREAK;
\) ELSE \(
FILECOPY(FP);
FCLOSE(FP);
\)
\)
FILECOPY(FP) /*COPY FILE FP TO STANDARD OUTPUT*/
FILE *FP;
\(
INT C;
WHILE ((C=GETC(FP)) !=EOF)
PUTC(C, STDOUT);
\)
STDIN STDOUT
- ;
, FILE*.
, ,
- .
FCLOSE FOPEN;
,
FOPEN, .

, . ,
CAT, ,
. FCLOSE
- , PUTC
. ( FCLOSE
).

.. , ..

161

7.7. - STDERR EXIT


CAT . ,
,

. , , ,
(PIPELINE)
.
,
, STDIN STDOUT, ,
STDERR. , ,
STDERR, ,
.
CAT ,
.
INCLUDE <STDIO.H>
MAIN(ARGC,ARGV) /*CAT: CONCATENATE FILES*/
INT ARGC;
CHAR *ARGV[];
\(
FILE *FP, *FOPEN();
IF(ARGC==1) /*NO ARGS; COPY STANDARD INPUT*/FILECOPY(STDIN);
ELSE
WHILE (ARGC > 0) IF((FP=FOPEN(*++ARGV,R#))==NULL) \(
PRINTF(STDERR,
CAT: CANT OPEN,%S\N, ARGV);
EXIT(1);
\) ELSE \(
FILECOPY(FP);
\)
EXIT(0);
\)
.
, FPRINTF, STDERR ,
, ,
(PIPELINE) .
EXIT ,
.
EXIT ,
,
,
. 0
, ,

162

.. , ..

.
EXIT FCLOSE
,
, _EXIT. _EXIT
- ; ,
.
7.8.
FGETS,
GETLINE,
.
FGETS(LINE, MAXLINE, FP)
( )
FP LINE; MAXLINE_1
. \ 0.
FGETS LINE;
NULL. ( GETLINE ,
- ).
FPUTS (
) :
FPUTS(LINE, FP)
, FGETS FPUTS
, ,
-:
#INCLUDE <STDIO.H>
CHAR *FGETS(S,N,IOP) /*GET AT MOST N CHARS FROM IOP*/
CHAR *S;
INT N;
REGISTER FILE *IOP;
\(
REGISTER INT C;
REGISTER CHAR *CS;
CS = S;
WHILE(N>0&&(C=GETC(IOP)) !=EOF)
IF ((*CS++ = C)==\N)
BREAK;
*CS = \0;
RETURN((C==EOF && CS==S) 7 NULL : S);
\)
FPUTS(S,IOP) /*PUT STRING S ON FILS IOP*/

.. , ..

163

REGISTER CHAR *S;


REGISTER FILE *IOP;
\(
REGISTER INT C;
WHILE (C = *S++)
PUTC(C,IOP);
\)
7-3.
,
, .
7-4.

5 ,
, ,
. ?
7-5.
,

.
7.9.

, .
: STRLEN, STRCPY, STRCAT
STRCMP. .
7.9.1.
:
SALPHA(C) 0, C ,
0 - .
SUPPER(C) 0, C ,
0 - .
SLOWER(C) 0, C ,
0 - .
SDIGIT(C) 0, C ,
0 - .
SSPACL(C) 0, C , , 0 -
.
OUPPER(C) C .
OLOWER(C) C .

164

.. , ..

7.9.2. UNGETC

UNGETCH, 4; UNGETC.

UNGETC(C,FP)
C FP.
. UNGETC
SCANF, GETC GETCHAR.
7.9.3.
SYSTEM(S) ,
S, .
S .
, , UNIX
SYSTEM(DATE);
DATE, .
7.9.4.
CALLOC ALLOC,
.
CALLOC(N, SIZEOF(OBJCCT))
,
N , NULL,
. .
, ,
CHAR *CALLOC();
INT *IP;
IP=(INT*) CALLOC(N,SIZEOF(INT));
CFREE(P) , P,
P
CALLOC. , , CALLOC.
, CALLOC,
,
8.

.. , ..

165

8. UNIX
-
UNIX.
C UNIX,
. - ,

C.
: /,
.
UNIX.
7 ,
.

-, .

UNIX ,
.
8.1.
UNIX
,
, ,
. ,
.

;
. ,
( ?
?), ,
, . ,
,
, . (
READ (5,...) WRITE (6,...) ).
;
.

.
(SHELL) ,
, ,
, 0, 1 2
.
, 0

166

.. , ..

1 2,
, .
,
SHELL < > :
PROG <INFILE>OUTFILE
SHELL
0 1 .
2 ,
.
, . ,
SHELL,
. , 0 1
2 , , .
8.2. / - READ WRITE.
/ UNIX
- , - ;
.
: READ WRITE. .
, .
- .
:
N_READ=READ(FD,BUF,N);
N_WRITTEN=WRITE(FD,BUF,N);
,
.
, .
, -1
- .
; ,
, .
, ,
.
1, (..
), 512,
.
,
.
,

.. , ..

167

, ,
1. UNIX
,
.
#DEFINE BUFSIZE 512 /*BEST SIZE FOR PDP-11 UNIX*/
MAIN() /*COPY INPUT TO OUTPUT*/
\(
CHAR BUF[BUFSIZE];
INT N;
WHILE((N=READ(0,BUF,BUFSIZE))>0)
WRITE(1,BUF,N);
\)
BUFSIZE,
READ ,
WRITE;
READ .
, READ
WRITE ,
GETCHAR, PUTCHAR .. , , GETCHAR,
.
#DEFINE CMASK 0377 /*FOR MAKING CHARS > 0*/
GETCHAR() /*UNBUFFERED SINGLE CHARACTER INPUT*/
\(
CHAR C;
RETURN((READ(0,&C,1)>0 7 & CMASK : EOF);
\)
C CHAR,
READ .
0377 ;
. (
0377 PDP-11, ).
GETCHAR
, .
#DEFINE CMASK 0377 /*FOR MAKING CHARS>0*/
#DEFINE BUFSIZE 512
GETCHAR() /*BUFFERED VERSION*/
\(
STATIC CHAR BUF[BUFSIZE];
STATIC CHAR *BUFP = BUF;
STATIC INT
N = 0;
IF (N==0) \( /*BUFFER IS EMPTY*/

168

.. , ..

N=READ(0,BUF,BUFSIZE);
BUFP = BUF;
\)
RETURN((N>=0) ? *BUFP++ & CMASK : EOF);
\)
8.3. , , (UNLINK).
, ,
, ,
. : OPEN CREAT.
OPEN FOPEN,
7, ,
, INT.
INT FD;
FD=OPEN(NAME,RWMODE);
FOPEN, NAME ,
. ,
, : RWMODE : 0 - , 1 - , 2 -
. - , OPEN
-1; .
, , .
CREAT
.
FD=CREAT(NAME,PMODE);
,
NAME, -1 .
, CREAT ; ,
, .
, CREAT
, PMODE.
UNIX
, ,
,
. ,
. , 0755
,
.

, CP UNIX.
( ,

.. , ..

169

).
#DEFINE NULL 0
#DEFINE BUFSIZE 512
#DEFINE PMODE 0644/*RW FOR OWNER,R FOR GROUP,OTHERS*/
MAIN(ARGC,ARGV) /*CP: COPY F1 TO F2*/
INT ARGC;
CHAR *ARGV[];
\(
INT F1, F2, N;
CHAR BUF[BUFSIZE];
IF (ARGC ! = 3)
ERROR(USAGE:CP FROM TO, NULL);
IF ((F1=OPEN(ARGV[1],0))== -1)
ERROR(CP:CANT OPEN %S, ARGV[1]);
IF ((F2=CREAT(ARGV[2],PMODE))== -1)
ERROR(CP: CANT CREATE %S, ARGV[2]);
WHILE ((N=READ(F1,BUF,BUFSIZE))>0)
IF (WRITE(F2,BUF,N) !=N)
ERROR(CP: WRITE ERROR, NULL);
EXIT(0);
\)
ERROR(S1,S2) /*PRINT ERROR MESSAGE AND DIE*/
CHAR *S1, S2;
\(
PRINTF(S1,S2);
PRINTF(\N);EXIT(1);
\)
( 15 - 25) ,
.
, ,
.
CLOSE

. EXIT
.
UNLINK (FILENAME)
FILENAME ( .
, , .).
8-1.
CAT 7, READ,
WRITE, OPEN CLOSE .

170

.. , ..


.
8.4. - SEEK LSEEK.

: READ WRITE
,
.
.
LSEEK ,
.
LSEEK(FD,OFFSET,ORIGIN);
FD
OFFSET (), ,
ORIGIN ( ).
. OFFSET LONG; FD
ORIGIN INT.
ORIGIN 0,1 2, ,
OFFSET ,
. , ,
:
LSEEK(FD,0L,2);
( ), :
LSEEK(FD,0L,0);
0L;
(LONG) 0.
LSEEK ,
, .
, , ,
.
GET(FD,POS,BUF,N) /*READ N BYTES FROM POSITION POS*/
INT FD, N;
LONG POS;
CHAR *BUF;
\(
LSEEK(FD,POS,0); /*GET TO POS*/
RETURN(READ(FD,BUF,N));
\)

.. , ..

171

, 7 UNIX,
- SEEK. SEEK
LSEEK, , OFFSET INT,
LONG. , PDP-11 16
, OFFSET, SEEK,
65535; ORIGIN 3, 4, 5,
SEEK OFFSET 512
( ) ORIGIN, 0, 1 2 . ,
, SEEK:
, , , ORIGIN
1 .
8-2.
, SEEK LSEEK
. .
8.5. - FOPEN GETC.
FOPEN GETC
,
.
,
, .
, :
, ; ,
; ;
, ..; .
STDIO.H,
( #INCLUDE)
, .
.
STDIO.H ,
, ,
.
DEFINE _BUFSIZE 512
DEFINE _NFILE
20 /*FILES THAT CAN BE HANDLED*/
TYPEDEF STRUCT _IOBUF \(
CHAR*_PTR; /*NEXT CHARACTER POSITION*/
INT _CNT; /*NUMBER OF CHARACTERS LEFT*/
CHAR*_BASE;
/*LOCATION OF BUFFER*/
INT _FLAG; /*MODE OF FILE ACCESS*/
INT _FD; /*FILE DESCRIPTOR*/
) FILE;

172

.. , ..

XTERN FILE _IOB[_NFILE];


DEFINE
STDIN
(&_IOB[0])
DEFINE
STDOUT (&_IOB[1])
DEFINE
STDERR (&_IOB[2])
DEFINE
_READ
01 /* FILE OPEN FOR READING */
DEFINE
_WRITE 02 /* FILE OPEN FOR WRITING */
DEFINE
_UNBUF 04 /* FILE IS UNBUFFERED */
DEFINE
_BIGBUF 010 /* BIG BUFFER ALLOCATED */
DEFINE _EOF 020 /* EOF HAS OCCURRED ON THIS FILE */
DEFINE _ERR 040 /* ERROR HAS OCCURRED ON THIS FILE */
DEFINE
NULL 0
DEFINE
EOF (-1)
DEFINE
GETC(P) ((P)->_CNT >= 0 \
? *(P)->_PTR++ & 0377 : _FILEBUF(P))
DEFINE
GETCHAR() GETC(STDIN)
DEFINE
PUTC(X,P) ((P)->_CNT >= 0 \
? *(P)->_PTR++ = (X) : _FLUSHBUF((X),P))
DEFINE
PUTCHAR(X)
PUTC(X,STDOUT)
GETC ,
. ( #DEFINE ,
).
, GETC _FILEBUF,
, .

: GETC 0377,
, PDP-11,
.
- ,
PUTC, ,
, GETC,
_FLUSHBUF.
FOPEN.
FOPEN
, ,
. FOPEN -
; _FILEBUF .
#INCLUDE <STDIO.H>
#DEFINE PMODE 0644 /*R/W FOR OWNER;R FOR OTHERS*/
FILE *FOPEN(NAME,MODE) /*OPEN FILE,RETURN FILE PTR*/
REGISTER CHAR *NAME, *MODE;
\(
REGISTER INT FD;

.. , ..

173

REGISTER FILE *FP;


IF(*MODE !=R&&*MODE !=W&&*MODE !=A) \(
FPRINTF(STDERR,ILLEGAL MODE %S OPENING %S\N, MODE,NAME);
EXIT(1);
\)
FOR (FP=_IOB;FP<_IOB+_NFILE;FP++)
IF((FP->_FLAG & (_READ \! _WRITE))==0)
BREAK; /*FOUND FREE SLOT*/
IF(FP>=_IOB+_NFILE) /*NO FREE SLOTS*/
RETURN(NULL);
IF(*MODE==W) /*ACCESS FILE*/
FD=CREAT(NAME,PMODE);
ELSE IF(*MODE==A) \(
IF((FD=OPEN(NAME,1))==-1)
FD=CREAT(NAME,PMODE);
LSEEK(FD,OL,2);
\) ELSE
FD=OPEN(NAME,0);
IF(FD==-1) /*COULDNT ACCESS NAME*/
RETURN(NULL);
FP->_FD=FD;
FP->_CNT=0;
FP->_BASE=NULL;
FP->_FLAG &=(_READ \! _WRITE);
FP->_FLAG \!=(*MODE==R) ? _READ : _WRITE;
RETURN(FP);
\)
_FILEBUF .
, _FILEBUF
,
.
CALLOC, ;
, _FILEBUF / ,
, .
#INCLUDE <STDIO.H>
_FILLBUF(FP) /*ALLOCATE AND FILL INPUT BUFFER*/
REGISTER FILE *FP;
(
STATIC CHAR SMALLBUF(NFILE);/*FOR UNBUFFERED 1/0*/
CHAR *CALLOC(); IF((FR->_FLAG&_READ)==0\!\!(FP
>_FLAG&(EOF\!_ERR))\!=0
RETURN(EOF);
WHILE(FP->_BASE==NULL) /*FIND BUFFER SPACE*/

174

.. , ..

IF(FP->_FLAG & _UNBUF) /*UNBUFFERED*/ FP


>_BASE=&SMALLBUF[FP->_FD];
ELSE IF((FP->_BASE=CALLOC(_BUFSIZE,1))==NULL)
FP->_FLAG \!=_UNBUF; /*CANT GET BIG BUF*/
ELSE
FP->_FLAG \!=_BIGBUF; /*GOT BIG ONE*/ FP->_PTR=FP
>_BASE; FP->_CNT=READ(FP->_FD, FP->_PTR,
FP->_FLAG & _UNBUF ? 1 : _BUFSIZE); FF(FP->_CNT<0) \(
IF(FP->_CNT== -1)
FP->_FLAG \! = _EOF;
ELSE
FP->_FLAG \! = _ ERR;
FP->_CNT = 0;
RETURN(EOF);
\)
RETURN(*FP->_PTR++ & 0377); /*MAKE CHAR POSITIVE*/ )
GETC
, _FILEBUF.
_FILEBUF , ,
EOF.
, , .
_FLAG .
, _FILEBUF
READ ,
.
,
. _IOB
STDIN, STDOUT STDERR:
FILE _IOB[NFILE] = \(
(NULL,0,_READ,0), /*STDIN*/
(NULL,0,NULL,1), /*STDOUT*/
(NULL,0,NULL,_WRITE \! _UNBUF,2) /*STDERR*/
);
_FLAG ,
STDIN , STDOUT - STDERR
- .
8-3.
FOPEN _FILEBUF,
.
8-4.
_FLUSHBUF FCLOSE.

.. , ..

175

8-5.

FSEEK(FP, OFFSET, ORIGIN)
LSEEK, , FP
, . FSEEK. ,
FSEEK ,
.
8.6. -
, , .
LS ( ) UNIX.
, ,
, , ..
, , UNIX
, , LS ;
.
, LS ,
.
FSIZE.
FSIZE LS,
, .
,
FSIZE .
, .
.
- ,
, .
, I - . I-
- , , .
: I-
. SYS/
DIR.H,
#DEFINE DIRSIZ 14 /*MAX LENGTH OF FILE NAME*/
STRUCT DIRECT /*STRUCTURE OF DIRECTORY ENTRY*/
\(
INO_T&_INO; /*INODE NUMBER*/
CHAR &_NAME[DIRSIZ]; /*FILE NAME*/
\);
INO_T - TYPEDEF ,
I- . PDP-11 UNIX

176

.. , ..

UNSIGNED, ,
: .
TYPEDEF.
SYS/TUPES.H.
STAT I-
( -1, ).
,
STRUCT STAT STBUF;
CHAR *NAME;
STAT(NAME,&STBUF);
STBUF I-
NAME. , STAT
, SYS/STAT.H
:
STRUCT
\(
DEV_T
INO_T
SHORT
SHORT
SHORT
SHORT
DEV_T
OFF_T
TIME_T
TIME_T
TIME_T
\)

STAT /*STRUCTURE RETURNED BY STAT*/


ST_DEV;
/* DEVICE OF INODE */
ST_INO;
/* INODE NUMBER */
ST_MODE
/* MODE BITS */
ST_NLINK;
/ *NUMBER OF LINKS TO FILE */
ST_UID;
/* OWNERS USER ID */
ST_GID;
/* OWNERS GROUP ID */
ST_RDEV;
/* FOR SPECIAL FILES */
ST_SIZE;
/* FILE SIZE IN CHARACTERS */
ST_ATIME; /* TIME LAST ACCESSED */
ST_MTIME; /* TIME LAST MODIFIED */
ST_CTIME; /* TIME ORIGINALLY CREATED */

.
ST.MODE , ;
SYS/STAT.H.
#DEFINE
#DEFINE
#DEFINE
#DEFINE
#DEFINE
#DEFINE
#DEFINE
#DEFINE
#DEFINE

S_IFMT
S_IFDIR
S_IFCHR
S_IFBLK
S_IFREG
S_ISUID
S_ISGID
S_ISVTX
S_IREAD

0160000 /* TYPE OF FILE */


0040000 /* DIRECTORY */
0020000 /* CHARACTER SPECIAL */
0060000 /* BLOCK SPECIAL */
0100000 /* REGULAR */
04000 /* SET USER ID ON EXECUTION */
02000 /* SET GROUP ID ON EXECUTION */
01000 /*SAVE SWAPPED TEXT AFTER USE*/
0400 /* READ PERMISSION */

.. , ..

#DEFINE S_IWRITE
#DEFINE S_IEXEC

0200
0100

177

/* WRITE PERMISSION */
/* EXECUTE PERMISSION */

FSIZE.
STAT , ,
.
,
; , .
,
; FSIZE
.
#INCLUDE <STDIO.H.>
#INCLUDE <SYS/TYPES.H> /*TYPEDEFS*/
#INCLUDE <SYS/DIR.H>
/*DIRECTORY ENTRY STRUCTURE*/
#INCLUDE <SYS/STAT.H> /*STRUCTURE RETURNED BY STAT*/
#DEFINE BUFSIZE 256
MAIN(ARGC,ARGV) /*FSIZE:PRINT FILE SIZES*/
CHAR *ARGV[];
\(
CHAR BUF[BUFSIZE];
IF(ARGC==1) \( /*DEFAULT:CURRENT DIRECTORY*/
ATRCPY(BUF,.);
FSIZE(BUF);
\) ELSE
WHILE(ARGC>0) \(
STRCPY(BUF,*++ARGV);
FSIZE(BUF);
\)
\)
FSIZE .
, FSIZE DIRECTORY
.
S_IFMT _IFDIR STAT.H.
FSIZE(NAME) /*PRINT SIZE FOR NAME*/
CHAR *NAME;
\(
STRUCT STAT STBUF;
IF(STAT(NAME,&STBUF)== -1) \(
FPRINTF(STDERR,FSIZE:CANT FIND %S\N,NAME); RETURN;
\)
IF((STBUF.ST_MODE & S_IFMT)==S_IFDIR)
DIRECTORY(NAME);

178

.. , ..

PRINTF(%8LD %S\N,STBUF.ST_SIZE,NAME);
\)
DIRECTORY .

, .
DIRECTORY(NAME) /*FSIZE FOR ALL FILES IN NAME*/
CHAR *NAME;
(
STRUCT DIRECT DIRBUF;
CHAR *NBP, *NEP;
INT I, FD;
NBP=NAME+STRLEN(NAME);
*NBP++=/; /*ADD SLASH TO DIRECTORY NAME*/
IF(NBP+DIRSIZ+2>=NAME+BUFSIZE) /*NAME TOO LONG*/
RETURN;
IF((FD=OPEN(NAME,0))== -1)
RETURN;
WHILE(READ(FD,(CHAR *)&DIRBUF,SIZEOF(DIRBUF))>0) \(
IF(DIRBUF.D_INO==0) /*SLOT NOT IN USE*/ CONTINUE;
IF(STRCMP (DIRBUF.D_NAME,.)==0
\!\! STRCMP(DIRBUF.D_NAME,..)==0
CONTINUE; /*SKIP SELF AND PARENT*/
FOR (I=0,NEP=NBP;I<DIRSIZ;I++)
*NEP++=DIRBUF.D_NAME[I];
*NEP++=\0';
FSIZE(NAME);
\)
CLOSE(FD);
*NBP=\0'; /*RESTORE NAME*/
)

( ), I-
, .
, ., , ..; , ,
, .
FSIZE ,
. -,
; ,
. -,
,
, STAT.H DIR.H,
, .

.. , ..

179

8.7. - .
5 ALLOC. ,
, :
ALLOC FREE ; ,
ALLOC .
, ,
, -
- ,
, TYPEDEF.
,
, ALLOC
.
, ,
ALLOC, . . ,
.
, (
) , .

, .
,
. , ,
,
. ,
,
; .

.
-
, ,
.
, .
, 5,
, ALLOC
,
. ,
, ,

, .
, IBM 360/370,HONEYWELL 6000
,
DOUBLE; PDP-11 INT.
,

180

.. , ..

;
.
, .
,
:
TYPEDEF INT ALIGN; /*FORCES ALIGNMENT ON PDP-11*/
UNION HEADER \( /*FREE BLOCK HEADER*/
STRUCT \(
UNION HEADER *PTR; /*NEXT FREE BLOCK*/
UNSIGNED SIZE; /*SIZE OF THIS FREE BLOCK*/
\) S;
ALIGN X; /*FORCE ALIGNMENT OF BLOCKS*/ \);
TYPEDEF UNION HEADER HEADER;
ALLOC
; , ,
, ,
, SIZE . ,
ALLOC, , .
STATIC HEADER BASE; /*EMPTY LIST TO GET STARTED*/
STATIC HEADER *ALLOCP=NULL; /*LAST ALLOCATED BLOCK*/
CHAR *ALLOC(NBYTES)/*GENERAL-PURPOSE STORAGE ALLOCATOR*/
UNSIGNED NBYTES;
\(
HEADER *MORECORE();
REGISTER HEADER *P, *G;
REGISTER INT NUNITS;
NUNITS=1+(NBYTES+SIZEOF(HEADER)-1)/SIZEOF(HEADER);
IF ((G=ALLOCP)==NULL) \( /*NO FREE LIST YET*/
BASE.S PTR=ALLOCP=G=&BASE;
BASE.S.SIZE=0;
\)
FOR (P=G>S.PTR; ; G=P, P=P->S.PTR) \(
IF (P->S.SIZE>=NUNITS) \( /*BIG ENOUGH*/
IF (P->S.SIZE==NUNITS) /*EXACTLY*/
G->S.PTR=P->S.PTR;
ELSE \( /*ALLOCATE TAIL END*/
P->S.SIZE-=NUNITS;
P+=P->S.SIZE;
P->S.SIZE=NUNITS;
\)
ALLOCP=G;
RETURN((CHAR *)(P+1));

.. , ..

181

\)
IF(P==ALLOCP) /*WRAPPED AROUND FREE LIST*/
IF((P=MORECORE(NUNITS))==NULL)
RETURN(NULL); /*NONE LEFT*/
\)
\)
BASE . ALLOCP
NULL, ALLOC,
:
.
.
(ALLOCP), ;
. ,
; ,
. ,
. ,
ALLOC P .
MORECORE .
, , , , .
UNIX SBRK(N) N
.(
).
,
ALLOC. MORECORE
;
, .
, .
#DEFINE NALLOC 128 /*#UNITS TO ALLOCATE AT ONCE*/
STATIC HEADER *MORECORE(NU) /*ASK SYSTEM FOR MEMORY*/
UNSIGNED NU;
\(
CHAR *SBRK();
REGISTER CHAR *CP;
REGISTER HEADER *UP;
REGISTER INT RNU;
RNU=NALLOC*((NU+NALLOC-1)/NALLOC);
CP=SBRK(RNU*SIZEOF(HEADER));
IF ((INT)CP==-1) /*NO SPACE AT ALL*/
RETURN(NULL);
UP=(HEADER *)CP;
UP->S.SIZE=RNU;
FREE((CHAR *)(UP+1));

182

.. , ..

RETURN(ALLOCP);
\)
, SBRK
-1, NULL .
-1 INT.
() ,

.
- FREE. ALLOCP,

. ,
. ,
, .
, , ,
.
FREE(AP) /*PUT BLOCKE AP IN FREE LIST*/
CHAR *AP;
\(
REGISTER HEADER *P, *G;
P=(HEADER*)AP-1; /*POINT TO HEADER*/
FOR (G=ALLOCP; !(P>G && P>G->S.PTR);G=G->S.PTR)
IF (G>=G->S.PTR && (P>G \!\! P<G->S.PTR))
BREAK; /*AT ONE END OR OTHER*/
IF (P+P->S.SIZE==G->S.PTR)\(/*JOIN TO UPPER NBR*/
P->S.SIZE += G->S.PTR->S.SIZE;
P->S.PTR = G->S.PTR->S.PTR;
\) ELSE
P->S.PTR = G->S.PTR;
IF (G+G->S.SIZE==P) \( /*JOIN TO LOWER NBR*/
G->S.SIZE+=P->S.SIZE;
G->S.PTR=P->S.PTR;
\) ELSE
G->S.PTR=P;
ALLOCP = G;
\)

, ,
.
TYPEDEF UNION
( , SBRK ).

.

.. , ..

183

,
.
8-6.
CALLOC(N,SIZE)
N SIZE,
. CALLOC,
ALLOC , ,
.
8-7.
ALLOC ,
; FREE , ,
, .
,
.
8-8.
BFREE(P,N),
P N ,
ALLOC FREE. BFREE
.

184

.. , ..

9. :
C
9.1.
DEC PDP-11,
HONEYWELL 6000, IBM /370 INTERDATA 8/32. ,
, PDP-11,
, .
,
;
.
10.
: , ,
, , . , ,
(, ),
, , ,
. -
, , .

,
, .
10.1.
/* /*.
.
10.2. ()
- ;
. _ .
. ,
, .
,
, :
DEC PDP-11
7 , 2
HONEYWELL 6000 6 , 1
IBM 360/370
7 , 1
INTERDATA 8/32
8 , 2

.. , ..

185

10.3.

:
INT
EXTERN
ELSE
CHAR
REGISTER
FOR
FLOAT
TYPEDEF
DO
DOUBLE
STATIC
WHILE
STRUCT
GOTO
SWITCH
UNION
RETURN
CASE
LONG
SIZEOF
DEFAULT
SHORT
BREAK
ENTRY
UNSIGNED
CONTINUE
*AUTO
IF
ENTRY -
; .
FORTRAN ASM
10.4.
, .
10.6 ,
.
10.4.1.
, ,
, 0 ( ),
. 8 9 10 11
. ,
0 (, -) 0 ( -),
.
() () F () F ()
10 15. ,
, ;
,
, .
10.4.2.
, ,
L (-) L (-),
. ,
.

186

.. , ..

10.4.3.
- , ,
, , X.
.
,
\
:

NL/LF/
\N

HT
\T
BS
\B

CR
\R

FF
\F

\
\\

\

DDD
\DDD
\DDD ,
1,2 3 ,
.
\0 ( ), NUL.
, .
10.4.4.
, ,
, E () E ()
. , .
, ( ) ; ,
() ( ) . .
10.5.
- ,
, , ,....
STATIC (. 4 ).
. , ,
. \0,
.

\; ,
, .
, \,
, .

.. , ..

187

10.6.

, .
,
, .
1
DEC PDP-11
ASCII
CHAR 8 BITS
INT 16
SHORT 16
LONG 32
FLOAT 32
DOUBLE 64
RANGE -38/+38

HONEYWELL
ASCII
9 BITS
36
36
36
36
72
38/+38

IBM 370
EBCDIC
8 BITS
32
16
32
32
64
-76/+76

INTERDATA
ASCII
8 BITS
32
16
32
32
64 -76/+76

8/32

11.

(. .:
),
- .
. ,
, ,
\(
\)
,
. 18.
12. ?
C
: .
, ;
, , .
: , ,
.
.
,
, .

,
.

188

.. , ..

( ) ;

.
C :
, (CHAR), ,

,
,
.
, -.
, SHORT
INT, INT LONG INT. ,
, ,
, ,
. ,
; .
, UNSIGNED,
2**N, N - . (
PDP-11 ).
(FLOAT)
(DOUBLE) .

, .
CHAR INT
. FLOAT DOUBLE
.

,
:
;
, ;
;
,
;
,
.
,
.
13. L-
; L- -
, . L . ,

.. , ..

189

L-; , , E -
, *E L-, E.
L- E1=E2,
L-.
,
L- L-.
14.

.
, .
. 14.6 ,
;
.
14.1.
, . .
; . ,
, , . , , PDP-11
.
PDP-11 -128 127; ASC11
. , ,
; , \377 -1.
CHAR,
; .
14.2. FLOAT DOUBLE
C
, FLOAT ,
DOUBLE .
DOUBLE FLOAT, ,
, DOUBLE FLOAT.
14.3.
-; -

190

.. , ..

.
, .

. ,
.
14.4.

; ,
.
;
,
.
14.5.
, ,

. ,
( 2** ).

.
LONG,
. ,
.
14.6.

.
.
CHAR SHORT INT,
FLOAT DOUBLE. , DOUBLE, DOUBLE,
. , -
LONG, LONG,
.
, - UNSIGNED,
UNSIGNED, .
INT,
.

.. , ..

191

15.

,
. , , ,
+ (.15.4), , ..15.115.3. .

.
.18.
.
,
, ,
. ,
, . ,
( *,+,&,!,^ ),

; ,
.

-.
C ;
0
.
15.1.
, ., ->,
, .
: ()
- [] - (- -L- . - > -:

-,
,
, .
. , ,
..., ,
, ,
.... ,
L-. ,
, ..., ,

192

.. , ..

,
, ....
.
INT, LONG DOUBLE.
.
; ,
, ,
. (
; . . 16.6.)
,
.
, L- .
, ,
. ,
. ...,
INT, .... E1[E2]
* ((E1) + (E2)). ,
, ; ,
* + .. 15.1, 15.2
15.4 ; . 22.3.
,
,
,
. ,
..., .... ,
,
, ,
, ;
, , .
FLOAT
DOUBLE, CHAR SHORT
INT, , ,
. ;
,
. ,
(CAST); . .. 15.2, 16.7.

; , C
.
, .
,
,
. ;
, .

.. , ..

193

.
, ,
. L-,
,
. L-,
.
, (
- >) , .
,
.
L-,
, .
, E1->MOS ,
(*E1).MOS. . 16.5.

,
. . . 22.1.
15.2.
.
-:
*
& L-

\^
++ L-
L-
L- ++
L-
(-)
SIZEOF
SIZEOF -
* :
, L-,
, .
..., ....
& ,
L-. L- ...,
....
- () ,
. UNSIGNED
2**N ( N), N-

194

.. , ..

INT. + () .
! 1,
0, 0, .
INT.
.
\^ , ,
. .
.
, L-
++, . , L. ++ +=1.
(. 15.4) (. 15.14).
++,
L-.
++ L-
, L-. ,
,
, ++.
, L-.
L-
, L-. ,
,
, .
, L-.
,
, .
(CAST). . 16.7.
SIZEOF . (
, SIZEOF.
,
CHAR).
.
.
, .
,
, - .
SIZEOF
.
.
SIZEOF () ,
SIZEOF () - 2 (SIZEOF ()9 - 2.

.. , ..

195

15.3.
*, /, % .
.
-: * /
%
* . * ,

.
/ .
,
, .
, ,
, . , (A/B)*B+A%B A
( B 0).
%
. .
FLOAT.
15.4.
+ - .
.
, .
-: + -
+ .
.

, .
,
, , .
, P ,
P+1 .
.
+ ,
.
- .
. ,
, ,
, .
,
( ) INT,
, .

196

.. , ..

, ,
, ,
, .
15.5.
<< >> .

, .
INT;
. ,
, .
-: << >>
E1<<E2 E1 (
), E2 ;
. E1>>E2 E1,
E2 . E1 UNSIGNE,
( );
( PDP-11) ( ).
15.6.
,
; A<B<C ,
.
-: < >
<= >=
< (), > (), <= ( ) >= (
) 0, , 1,
. ITN.
. ;

. ,
.
15.7.
-: == !=
== () != ( )
, ,
. ( A<B==C<D 1 ,
A<B C<D ).
, , 0.

.. , ..

197

, , 0,
0;
.
15.8.
-: &
& , &
.
; .
.
15.9. -:
^
^ , ^
.
;
. .
15.10. -:
\!
\! , \!
.
;
. .
15.11.
--: &&
&& . 1,
, 0 . &
&& ; ,
0, .
,
, . ITN.
15.12.
--: \!\!
\!\! . 1,
, 0 . \!

198

.. , ..

\!\! ; ,
, .
,
, . INT.
15.13.
-:
? :
.
, ,
;
. ,
, ,
; ,
, ;
, - 0,
. .
15.14.
,
. L, .
,
, .
.
-:
L- =
L- +=
L- -=
L- *=
L- /=
L- %=
L- >>=
L- <<=
L- &=
L- ^=
L- \!=
C=,
, L-.
,
.

.. , ..

199

E1 = E2, O -
, , ,
E1 = E1 (E2); E1
. += -= ,
() ,
. 15.4;
.

, .
-
.
,
. , 0 ,
.
15.15.
--: ,
, ,
.
.
. , , , ,
(. 15.1) (. 16.6), , ,
; ,
F(A,(T=3,T+2),C)
, 5.
16.
, C
;
, .
:
- -
;
.

.
-:
- -

200

.. , ..

-- -

, .
16.1.
: -:
AUTO
STATIC
EXTERN
REGISTER
TYPEDEF
TYPEDEF
; .
16.8. . 12.
AUTO, STATIC REGISTER
,
. EXTERN
(. 18) - ,
.
REGISTER AUTO
,
. .
,
; PDP-11 INT, CHAR .
:
&.
,
.
.
, ,
AUTO,
, EXTERN . :
.
16.2.
.
-:
CHAR

.. , ..

201

SHORT
INT
LONG
UNSIGNED
FLOAT
DOUBLE --- -
LONG, SHORT USIGNED ; :
SHORT INT
LONG INT
USIGNED INT
LONG FLOAT
, DOUBLE.
.
, , INT.
. 16.5;
TYPEDEF . 16.8.
16.3.

,
.
-: - , - -:
. 16.6.
, .
:
:

( )
*
()
[-
]
.
16.4.
,
, , ,

202

.. , ..

.
;
, .
,
, .
,
.
.

T

DI

T - ( INT ..), DI - . ,
,
...T, ... , DI ( X
INT X INT). , DI
*D
... T.
DI
D()
... , T.
DI
D[-]

D[ ]
... T.
,
INT. (
. 23). , ;
, ,
. ,
,
, .
, .
.
,
, (
).
,

.. , ..

203

, . :
, ,
, ;
, . , ,
.

INT I, *IP, F(), *FIP(), (*PFI)();
I, IP , F,
, FIP, , PFI ,
. .
*FIP() *(FIP()), ,
FIP
() . (*PFI)()
, , , ,
,
; .

FLOAT FA[17], *AFP[17];
FLOAT
FLOAT. ,
STATIC INT X3D[3][5][7];
3*5*7.
, X3D ;
;
. X3D, X3D[I], X3D[I][J]
X3D[I][J][K] .
, INT.
16.5.
- ,
. . -
,
. .
---
-- \( --\)

--
\(--\)

204

.. , ..

--
--:
STRUCT
UNION
--
:
--: - --
-:
- --
--:
-
-, --

.
. ;
.
-:
: :
,
.
, , ,
;
. , ,
; . ,
, .
PDP-11
.
, ,
, ,
.
0
. , ,
,
.
,
, -
. , INT
. PDP-11 .

.. , ..

205


&, .
,
0 ,
.
.
, ..
STRUCT \(--\)
UNION \(--\)
(
) , .
,
STRUCT
UNION
,
;
.
,
,
, .
.
.

; ,
,
. (
,
,
, ).
:
STRUCT TNODE \(
CHAR TWORD[20];
INT COUNT;
STRUCT TNODE *LEFT;
STRUCT TNODE *RIGHT;
\);
20 ,
. ,
STRUCT TNODE S, *SP;

206

.. , ..

, S , SP
.

SP->COUNT
COUNT , SP;

S.LEFT
S,
S.RIGHT->TWORD[0]
TWORD
S.
16.6.

.
, =.
:
=
= \(-\)
= \(-,\)
-:

-,-
\(-\)
,
, ,
. 23, , ,
.
,
.
,
0;
.
(
), ,
.

.. , ..

207

; ,
.
(
),
.

. , .
,
.
.
.
,

; , ,
.
, ;
, .

CHAR .
.
,
INT X[] = \(1,3,5\);
X ;
,
, , .
:
FLOAT *Y[4][3] = \(
( 1, 3, 5 ),
( 2, 4, 6 ),
( 3, 5, 7 ),
\);
1, 3 5 Y[0],
Y[0][0], Y[0][1] Y[0][2].
Y[1] Y[2]. ,
, Y[3] .
,
FLOAT Y[4][3] = \(
1, 3, 5, 2, 4, 6, 3, 5, 7
\);

208

.. , ..

Y ,
Y[0] . 3 .

Y[1] Y[2].
FLOAT Y[4][3] = \(
(1), (2), (3), (4)
\);
Y (
), .
,
CHAR MSG[] = SYNTAX ERROR ON LINE %S\N;

.
16.7.
(
SIZEOF)
. ,
,
.
:
- -
-:

(-)
*
- ()
- [
]
( )
, - .
-,
,
.
. ,
INT
INT *
INT *[3]
INT (*)[3]

.. , ..

209

INT *()
INT (*)()
, ,
, , ,
,
.
16.8. TYPEDEF
, TYPEDEF,
.
, ,
, .
--
TYPEDEF
,
, ,
,
. 16.4 . ,
TYPEDEF INT MILES, >KLICKSP;
TYPEDEF STRUCT ( DOUBLE RE, IM; ) COMPLEX;

MILES DISTANCE;
EXTERN KLICKSP METRICP;
COMPLEX Z, *ZP;
; DISTANCE
INT, METRICP - INT, Z -
ZP - .
TYPEDEF - ,
,
.
DISTANCE ,
, INT.
17.
,
.
17.1.
,

210

.. , ..

;
.
17.2. ( )

, ,
( ):
:
\(- -
\)
-:

-
-:

-
- - ,

.

.
( ) ;
. , .
,
.
17.3.
:
IF ()
IF () ELSE
, ,
. ,
, . ,
ELSE ELSE IF,
ELSE.
17.4. WHILE
WHILE

.. , ..

211

WHILE ()
,
.
.
17.5. DO
DO
DO WHILE ()
,
.
.
17.6. FOR
FOR
FOR (-1

; -2 ; -3

FOR
-1;
WHILE (-2) \(
-3
\)
, ;
, ,
,
; ,
.
. , WHILE
WHILE(1); .
17.7. SWITCH
SWITCH (),
, .

SWITCH ()

212

.. , ..

,
INT. .

CASE, :
CASE :
INT.

.
. 23.
,

DEFAULT:
SWITCH
.
, , .

DEFAULT, ,
.
DEFAULT , .
CASE DEFAULT ,
.
BREAK, . 17.8.
, , .
,
.
17.8. BREAK

BREAK;

WHILE, DO, FOR SWITCH;
, .
17.9. CONTINUE

CONTINUE;

.. , ..

213

WHILE, DO FOR;
. ,
WHILE(...) \(
DO \( FOR(...) \(
... ...
...
CONTIN: ; CONTIN: ;
CONTIN: ;
\) \) WHILE(...);
\)
CONTINUE GOTO CONTIN. (
CONTIN: ; . . 17.13.).
17.10.

RETURN,
RETURN;
RETURN ;
.
. ,
, ,
.
.
17.11. GOTO

GOTO 1
(. 9.12), .
17.12.

:
.
,
GOTO.
, ,
. . 19.
17.13.
:

214

.. , ..

;
,
\)
, WHILE.
18.
C-
.
EXTERN ( ), STATIC,
. (. 16.2)
; , INT.
,
, ,
.
, ,
.
18.1.

-:
-
-

,
-, EXTERN STATIC;
. 19.2.
, ..., ,
.
-:
(-
)
:

, -
-
-:
- -

. , ,
INT.

.. , ..

215

REGISTER; ,

, , .
:
INT MAX(A, B, C)
INT A, B, C;
\(
INT M;
M = (A>B) ? A:B;
RETURN((M>C) ? M:C);
\)
INT - -, MAX(A,B,C) - -, INT
A,B,C; - - , \( ... \) - ,
.
C FLOAT
DOUBLE, ,
FLOAT, DOUBLE. ,
(
) ,
...
: .... , ,
,
, (
, , ).
18.2.

-:

EXTERN ( ,
) STATIC, AUTO REGISTER.
19. ,
C- ;

.
,
.
: -, ,

216

.. , ..

,
,
; -, ,

,
.
19.1.
,
, ,
. ,
, ,
. ,
, .
, .

(. . 19.2),
;
,
.
, , ,
, , ,

.
(. 16.5), ,
, , ,
,
, ,
.
, . ,
TYPEDEF, ,
.
, :
TYPEDEF FLOAT DISTANCE;
...
\(
AUTO INT DISTANCE;
...
INT ,

DISTANCE (. : , .).

.. , ..

217

19.2.
, EXTERN,
- , ,
.
,
, ,
,
, ,
.
EBTERN
,
. ,
, EXTERN,
. ,
,
EXTERN.
, .
,
STATIC, .
STATIC.
20.
C ,
,
. , #,
. ;
(
) .
20.1.

#DEFINE -
( )
,
.
#DEFINE

(,...,)
(
, . -

218

.. , ..

,
(,
), .
, , . ,
; , , .
.
.

.
,
\ .

, , ,
#DEFINE TABSIZE 100
INT TABLE[TABSIZE];

#UNDEF
.
20.2.

#INCLUDE FILENAME

FILENAME.
, .

#INCLUDE <FILENAME>

.
#INCLUDE .
20.3.

.. , ..

219

#IF
, (. .
15).
#IF DEF
,
, ..
#DEFINE.
21.

.
.
, ,
, INT; ,
, AUTO.
, AUTO
( C
); , ...,
EXTERN.
,
( , ,
INT.
22.
,
.
22.1.
:
( ) (
&). ,
, .
, , - ,
.
. 15.1 ,
( . ->) ,
.
, . . L- ,
L- ,

220

.. , ..

. , , ->,
. , , .
, .
.
22.2.
:
. ,
,
. , ,

INT F();
...
G(F);
G :
G(FUNCP)
INT(*FUNCP)();
\(
...
(*FUNCP)();
...
\)
, F
, G(F) ( .
22.3. ,
, , ,
, . L-.
[] , E1[E2]
*((1)+(2)). , +, E1 - , 2 - ,
1[2] 2- 1.
.
.
N- I*J*...*K,
(N-1)-
J*...*K. * , , ,

.. , ..

221

,
(N-1)- , .
, ,
INT X[3][5];
X 3*5.
X 5 .
X[I], *(X+I), X
, ; I X,
I , ,
5 . ,
( 5 ),
.
, ;
.
, C (
)
,
, ,
.
22.4.
,
, .
; . . 15.2 16.7.
,
. INT LONG,
.
-, ,
. .

.
,
-.
.
,
,
. ,

, .
,
, ;

222

.. , ..

.
EXTERN CHAR *ALLOC();
DOUBLE *DP;
DP=(DOUBLE*) ALLOC(SIZEOF(DOUBLE));
*DP=22.0/7.0;
ALLOC (- ),

DOUBLE;
.
PDP-11 16-
. CHAR
; .
HONEYWELL 6000 36- ;
18
, . ,
2 16 ;
2 18 .
DOUBLE (0 2 19). IBM 370 INTERDATA 8/32
. ;
, ,
SHORT , INT FLOAT DOUBLE - .
, - .
23.
C ,
: CASE,
.
,
SIZEOF,
+ - * / . % & \! << >> == 1= <> <= >=

- \^
?:
,
.
( )
;

.. , ..

223

&
,
. &
, . ,
,
.
24.
C -.
, .
, ,
, ,
, .
. , , ( ) ,
, ,
.
- .
REGISTER,
, ,
.
;
.

. , , .
;
PDP-11 VAX-11 . , ,
.

INT, ,
. , ,
, , -.

PDP-11 VAX-11 .
,
(, , INT CHAR
),

224

.. , ..

.
, , . ,
PDP-11 ,
, , .
25.
C ,
.
,
, .
C =ON,
ON=, ,
X = -1
X , = -
, -1 X.
: ,
, ,
INT X = 1;

INT X 1;
-
INT F (1+2)
,
.
26.
C
.
26.1.
:
:
-
*
&

.. , ..

225

-
!
\^
++ L-
L-
L- ++
L-
SIZEOF
( )
-
? :
L- - ,
:

()
- ( )
- []
L- .
->
L-: - [] L . - -> *

(L-)

() []

->


.
*

&

\^

++

SIZEOF( )

, ,
, .
.
(. .: ;
1978 .)
:
:
*
+
>>
<

/
%
<<
> <=

>=

226

.. , ..

== !=
&
\^
\!
&&
\!\!
?:
.
:
=

+=

-=

*=

?=

%=

>>=

<<=

&=

\^=

\!=


.
26.2.
:
- -- ;

-:
- -

-- -

--:
AUTO
STATIC
EXTERN
REGISTER
TYPEDEF -:
CHAR
SHORT
INT
LONG
UNSIGNED
FLOAT
DOUBLE --- -
--:
-
-,
-- -

.. , ..

227

()
*
()
[
]
---:
STRUCT --
STRUCT \(--\)
STRUCT
UNION \(--\)
UNION \(--\)
UNION --:
-
- -- :
- --: -
-
-,-- -:

:
:-
:
=
= \(-\)
= \(-\)
:

-,-
\(-\)
-:
- - -:

\(-\)
* -
- ()
- [-
]
--:

228

.. , ..

26.3. -:
\(- -
\)
-:

-
-:

-
:

;
IF ()
IF () ELSE
WHILE ()
DO WHILE ();
FOR(-1
;-2 ;-3

SWITCH ()
CASE - :
DEFAULT:
BREAK;
CONTINUE;
RETURN;
RETURN ;
GOTO ; : ;

26.4. :
-
- -:
-
- -:
- - -

-:
(-
)

-:

, -
-:

.. , ..

229

-- -
-:
\(
-\)

:
EXTERN


;

STATIC


;
26.5.
#DEFINE -
#DEFINE
#DEFINE (,...,)
#UNDEF
#INCLUDE -
#INCLUDE <->
#IF -
#IFDEF
#IFNDEF
#ELSE
#ENDIF
#LINE
C (15 1978 .)
27.
,
.
. ,
, .
PDP-11
:
,
, .
,
, , ,
;
.

230

.. , ..

28.
, .
- 8.2.

-

-:
ENUM -
ENUM -
ENUM
c-:

-,
:

=

-
-;
. ,
ENUM COLOR \(RED, WHITE, BLACK, BLUE \);
. . .
ENUM COLOR *CP, COL;
COLOR ,
CP
, COL - .
-
, ( ) .
( =),
0 1
. = ;
.


.
,
, LINT
. PDP-11
,
INT.

.. , ..

231

29. C.

( ..) C,
.

**

\(
\)
\!
\
\^

** UNIX. C
,
.

232

.. , ..

.. , ..

: URL http://www.sch2.ru/kafedra/info/tutorial/kernigan.zip
.
.
28.05.2002
1 .

2002.

Оценить