You are on page 1of 229

..

,
.. .


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

.
;

, , , .

, .
, "C" ,
.
, . ,
.

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

.
.

1.

12

1.1. H
1.2.
1.3. FOR
1.4.
1.5.
1.5.1.
1.5.2.
1.5.3.
1.5.4.
1.5.5.
1.6.
1.7.
1.8.
1.9.
1.10. :

13
15
19
20
21
21
21
23
25
26
28
30
32
33
36

2. ,

38

2.1.
2.2.
2.3.
2.3.1.
2.3.2.
2.3.3.
2.4.
2.5.
2.6.
2.7.
2.8.
2.9.
2.10.
2.11.
2.12.

38
38
39
40
40
41
41
42
43
44
48
50
52
54
55

3.

57

3.1.
3.2. IF ELSE
3.3. ELSE IF
3.4.
3.5. WHILE FOR
3.7. BREAK

57
57
59
60
62
67

3.8. CONTINUE
3.9. GOTO

68
68

4.

70

4.1.
4.2. ,
4.3.
4.4.
4.5. ,
4.5.1.
4.6.
4.7.
4.8.
4.9.
4.10.
4.11. "C"
4.11.1.
4.11.2.

70
74
76
77
81
81
86
87
87
88
90
92
92
93

5.

94

5.1.
5.2.
5.3.
5.4.
5.5.
5.6.
5.7.
5.8. ;
5.9.
5.10.
5.11.
5.12.

94
97
99
102
105
108
109
112
115
116
117
121

6.

125

6.1.
6.2.
6.3.
6.4.
6.5. , .
6.6.
6.7.
6.8.
6.9.

125
127
130
135
137
141
144
145
147

7.

149

7.1.
7.2. GETCHAR

PUTCHAR

149
150

7.3. PRINTF
7.4. SCANF
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.

152
154
156
157
160
161
163
163
163
163
164

8. UNIX

164


/ READ WRITE
, , (UNLINK)
SEEK LSEEK
FOPEN GETC

165
166
167
169
170
174
178

9. : 'C'

183

9.1.

183

10.

183

10.1.
10.2. ()
10.3.
10.4.
10.4.1.
10.4.2.
10.4.3.
10.4.4.
10.5.
10.6.

183
183
184
184
184
184
185
185
185
186

11.

186

12. ?

186

13. L-

187

8.1.
8.2.
8.3.
8.4.
8.5.
8.6.
8.7.

14.

188

14.1.
14.2. FLOAT DOUBLE
14.3.
14.4.
14.5.
14.6.

188
188
188
188
189
189

15.

189

15.1.
15.2.
15.3.
15.4.
15.5.
15.6.
15.7.
15.8. ''
15.9. ''
15.10. ''
15.11. ''
15.12. ''
15.13.
15.14.
15.15.

190
191
193
193
194
194
194
195
195
195
195
196
196
196
197

16.

197

16.1.
16.2.
16.3.
16.4.
16.5.
16.6.
16.7.
16.8. TYPEDEF

198
198
199
200
201
204
206
207

17.

207

17.1.
17.2. ( )
17.3.
17.4. WHILE
17.5. DO
17.6. FOR
17.7. SWITCH
17.8. BREAK
17.9. CONTINUE
17.10.
17.11. GOTO

207
208
208
209
209
209
209
210
210
211
211

17.12.
17.13.

211
211

18.

212

18.1.
18.2.

212
213

19. ,

213

19.1.
19.2.

214
214

20.

215

20.1.
20.2.
20.3.

215
216
216

21.

216

22.

217

22.1.
22.2.
22.3. ,
22.4.

217
217
218
218

23.

219

24.

220

25.

221

26.

221

26.1.
26.2.

222
223

27.

227

28.

227

29. "C".

229

.. , .. . .

"C" .
"UNIX",
"UNIX" "C". , ,
- ;
,
,
, .
"C" " ".
; , "C"
, , , , .

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

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

, 80
.
. ,
"C",

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

.. , .. . .

10

.
"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 .
, ,

, "C".
"C" ,
BCPL, .
BCPL "C" "B",
1970 "UNIX" PDP-7.
"C" BCPL ,
. BCPL "B" ""
; ,

. "C" ,
. ,
, , ,
, .
"C" ,
: ,
(IF), (WHILE, FOR) (DO)
(SWITCH). (
BCPL, ;

).
"C" .
,

. " ",
, , .
,
.

.. , .. . .

11

,
"", .. .
,
. "C"
.
, ,
, .
.
,

.
"C"
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 ,

.. , .. . .

12

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

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

.. , .. . .

13

,

.
. ,
, ,
2.

1.1. H

. , ,
: : HELLO, WORLD.
; ,
- , , ,
, .
, .
"HELLO, WORLD" "C" :
MAIN ()

PRINTF("HELLO, WORLD\N");
.
, "UNIX"
, ".C", , HELLO.C,

CC HELLO.C
- ,
,
.OUT .
A.OUT

HELLO, WORLD
;
.
1-1.
.

.
. "C"-,
, "",

.. , .. . .

14

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

. , ,
; IN ,
(). , ,
, DO-END PL/1 BEGIN-END ,
.. ,
.
CALL, PL/1.
, .
PRINTF("HELLO, WORLD\N");
,
PRINTF "HELLO, WORLD\N". PRINTF
,
( - ).
, .
,
"...", ' ' '
'.
PRINTF .
\N
"C" ' ',
. \N (
), ,
. \N
PRINTF;
-
PRINTF("HELLO, WORLD
");
"C"-
.
PRINTF ,

. , ,

.. , .. . .

15

MAIN()

PRINTF("HELLO, ");
PRINTF("WORLD");
PRINTF("\N");
, \N .
'', \N,
.
"C" : \ , \B
, \" \\
.
1-2.
, ,
, PRINTF \X, X
, .

1.2.

,

C = (5/9)*(F-32). 0
20

-17.8

-6.7

40

4.4

60

15.6

...

...

260

126.7

280

137.8

300

140.9
:

/* 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 */

16

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 */
, ,
. /* */ ;
.
,
.
"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.
, ,
, ;
.

.. , .. . .

17



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

.
(FAHR UPPER),
( , ).
, , .
( FAHR UPPER ),
, .
,
.
WHILE ,
, ,
, , ,
WHILE (I < J)
I = 2 * I;
, WHILE,
, ,
. .
"C" ,

. ()
. ; .
.
.
CELAIUS
CELSIUS = (5.0/9.0) * (FAHR-32.0);

.. , .. . .

18

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. ,
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
, , .. ;

.. , .. . .

19

;
.
, PRINTF "C";
"C" -.
PRINTF ; ,
, "C"-.
,
- 7. ,
. SCANF 7,
7.4. SCANF PRINTF,
, .
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.
,

.. , .. . .

20

WHILE . FOR ,
.
FAHR = 0
. , , :
FAHR <= 300
, ,
( 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 */

.. , .. . .

21

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
.
,
. , .
, ,
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 ,
-,
.
. :

.. , .. . .

22


WHILE ( )

, "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

#DEFINE EOF 0
EOF ,
GETCHAR , ,
.
'C' INT, CHAR,
, GETCHAR . 2,
INT,
EOF.
, "C",
. "C" ,
C = GETCHAR()

.. , .. . .

23

;
, . 'C'
WHILE,
:
MAIN() /* COPY INPUT TO OUTPUT; 2ND VERSION */

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


WHILE
WHILE


GETCHAR .
"C",
. ,
.
.
,
. != ,
=, ,
!= =. ,
C = GETCHAR() != EOF

C = (GETCHAR() != EOF)
, , , 'C'
0 1 , GETCHAR
. 2/.
1.5.3.
;
.
MAIN() /* COUNT CHARACTERS IN INPUT */

LONG NC;

.. , .. . .

24

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

++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 . ,
, ,
. , .

.. , .. . .

25

, ,
, WHILE FOR
GETCHAR, , ,
, .. . .
WHILE FOR ,
, .. . , , , .
, "
". 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' .

.. , .. . .

26

, '\N' ,
; "\N" ,
.
2.
1-6.
, .
1-7.
, ,
.
1.5.5.

, , ,
, ,
. / 'WC' 'UNIX'/
#DEFINE

YES 1

#DEFINE

NO 0

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.

.. , .. . .

27

YES NO 1 0,
. , ,
, ,
,
. ,
, .

NL = NW = NC = 0;
.
, ,

. , ,
NC = (NL = (NW = 0));
\!\! OR ,
IF( C==' ' \!\! C=='\N' \!\! C=='\T')
" , , -
..."./ \T /.
&& AND. ,
&& \!\!,
, ,
, ,
. , 'C' ,
,
'C' ,
.
, , ,
.
ELSE "C",
, , , IF,
.
:
IF ()
-2

-1

ELSE

,
IF-ELSE. , -1;
-2. .
, ELSE, IF,
.

.. , .. . .

28

1-9.
?
K ?
1-10.
, ,
.
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",

.. , .. . .

29

NWHITE, NOTHER);

INT NDIGIT[10];
, NDIGIT .
"C" /
1, PL/1/, NDIGIT[0], NDIGIT[1],..., 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;

.. , .. . .

30

IF ()
ELSE IF ()
ELSE

,
.
,
- ; '',
. /, ''
, /.
, '', 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,

.. , .. . .

31


POWER(M,N), N.
POWER(2,5) 32. , **,
,
,
.
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) /* RAISE X N-TH POWER; N > 0 */


INT X,N;

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));

.. , .. . .

32

POWER, ,
,
. POWER(2,I) , 2 I. / ;
4/.
POWER ,
.
INT X,N;
.

;
. , 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

.. , .. . .

33

POWER(X,N) /* RAISE X N-TH POWER; N > 0;


VERSION 2 */
INT X,N;

INT P;
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
;
,
. ,

.. , .. . .

34

; , ,
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)

35

/* COPY S1 TO S2;
ASSUME S2 BIG ENOUGH */

CHAR S1[], S2[];

INT I;
I = 0;
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 ! O ! \N ! \0 !
% S , PRINTF ,
. COPY, ,
, \0,
S2. / , \0
/.
, , , ,
. ,
MAIN, ,

.. , .. . .

36

? GETLINE :
,
. , MAIN
, , ,
. .
GETLINE ,
. GETLINE
. 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). ,
.
, ,

.. , .. . .

37

,
, , , .
;
.
, ;
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;

.. , .. . .

38

LINE[I] = '\0'
RETURN(I)

2. ,
,
. ,
, , , .
, .
. .

2.1.
,
. ;
. "_" ;
.
; ""
, .
,
. ,
, ,
.
. , IF, ELSE, INT, FLOAT ..,
: . (
).
, ,
, ,
.

2.2.
"C" :
CHAR ,
.
INT ,
.
FLOAT .
DOUBLE .
,
INT: SHORT (), LONG () UNSIGNED ( ).
SHORT LONG .
2 N, N
INT; .
:
SHORT INT X;

.. , .. . .

39

LONG INT Y;
UNSIGNED INT Z;
C INT , .
, ;
.
1
!

INTERDATA

ASCII

DEC PDP-11 HONEYWELL IBM 370 6000 8/32 !


ASCII ASCII EBCDIC
CHAR

8-BITS

9-BITS

BITS 8 32

BITS !

INT 16 36 32

16

SHORT 16 36 16

32

LONG 32 36 32

32

FLOAT 32 36 32

64

!
!

DOUBLE 64 72 64
-----------------------------------

-----------

--------

, SHORT LONG
; INT
"" . ,
SHORT LONG
. , , , SHORT ,
LONG.

2.3.
INT FLOAT . ,

123.456-7,
""
0.123
FLOAT .
DOUBLE,
"E" FLOAT, DOUBLE.
123L. ,
INT, LONG.

.. , .. . .

40


: 0() INT
, 0X .
, 31 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;

.. , .. . .

41

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.
,
, .
, , , ,
INT LOWER, UPPER, STEP;
CHAR C, LINE[1000];

.. , .. . .

42

;

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
.
IF(YEAR % 4 == 0 && YEAR % 100 != 0 \!\! YEAR % 400 == 0)

.. , .. . .

43

ELSE

% FLOAT DOUBLE.
+ ,
*, / % ,
. . (

). +
;
, . , +(B+C)
(A+B)+C. - ,
,
.
, (..
),
.

2.6.

=> >

=< <

.
:
== !=
.
, I<LIM-1 I<(LIM1), .
&& \!\! . ,
&& \!\!, ,
,
.
. , ,
GETLINE,
1.

FOR(I=0;I<LIM-1 && (C=GETCHAR()) != '\N' && C != EOF; ++I)


S[I]=C;
, ,
S, I<LIM-1 .
, .
'C' EOF
GETCHAR : , .

.. , .. . .

44

&& , \!\!,
. ,
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.

. ATOI,
.

ATOI(S)
CHAR S[];

/* CONVERT S TO INTEGER */

.. , .. . .

45

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, ) CHAR,
1, (" ").

, .

.. , .. . .

46

"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 .. "" "
").
,
. , + *,
( ), ,
"" "" ""
. ,
.
- CHAR SHORT INT, FLOAT DOUBLE.
- , DOUBLE,
DOUBLE, DOUBLE.
- , LONG,
LONG, LONG.
- , UNSIGNED,
UNSIGNED UNSIGNED.

.. , .. . .

47

- 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).
,
( )

,
.
:
, . ,
SQRT DOUBLE
, - .
, N ,

.. , .. . .

48

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;
6. N 6.
;
=(I+J)++ .
, ,
, , ,
IF ( C == '\N' )
NL++;

.. , .. . .

49

. ,
. , , SQUEEZE(S,C),
'' S, , .
SQUEEZE(S,C)

/* DELETE ALL C FROM S */

CHAR S[];
INT C;

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 .

.. , .. . .

STRCAT(S,T)

50

/* CONCATENATE T TO END OF S */

CHAR S[], T[]; /* 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

.. , .. . .

51

'' N, . ''
OR :
C = X MASK
, MASK.
& ''
&& \!\!,
. , =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

.. , .. . .

52

N ; \^
N .
2-5.
GETBITS , .
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:

.. , .. . .

53

X *= Y + 1

X = X * (Y + 1)

X=X*Y+1
BITCOUNT,
1 .

BITCOUNT(N) /* COUNT 1 BITS IN N */


UNSIGNED 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.

.. , .. . .

54

X&(X-1)
1 X.(?)
BITCOUNT.

2.11.

IF (A > B)
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++)

.. , .. . .

55

PRINTF("% 6D% C",A[I],(I% 10==9 \!\! I==N-1)? '\N' : ' ')


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

2.12.

, , . ,
, ; . , , *, / %
, , + -.
OPERATOR
() [] -> .

ASSOCIATIVITY
LEFT TO RIGHT

! \^ ++ (TYPE) * & SIZEOF


* / %
+ << >>
< <= > >=

== !=

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

= += -= ETC.

RIGHT TO LEFT

, (CHAPTER 3)

LEFT TO RIGHT

RIGHT TO LEFT

.. , .. . .

56

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

), , .
;
, ,
.
"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++;

.. , .. . .

57

, I .

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

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,

.. , .. . .

58

ELSE . ;
"" /.. /, 1. / /, ELSE,
-1 -2.
IF ,
.
IF ()
IF ( !=0)
,
.
, 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("...");

.. , .. . .

59

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, ,
.

3.3. ELSE IF

IF ()
ELSE

IF ()

ELSE

IF ()

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

.. , .. . .

60

"" .

, ,
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;
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++)

.. , .. . .

61

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++;
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
, , ,

.. , .. . .
.
. .

62

BREAK .
,
, ,
. BREAK RETURN
. , BREA
WHILE, FOR
DO.
, .
,
, ,
.
BREAK,
.
, .
, ,
.
BREAK (
DEFAULT), .
, ,
.
3-1.
EXPAND(S, T), S ,

, \N \. .

3.5. WHILE FOR


WHILE FOR.
WHILE ()
. ,
. ,
,
.

FOR ( 1; 2; 3)

1;
WHILE ( 2) 3;

.. , .. . .

63

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, , ,
,
.
FOR (I = 0; I < N; I++)
"C" N ,
DO PL/1. , , ,
,
,
. FOR
, .
FOR ,
, .

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

.. , .. . .

64

-

. ,
.
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);

, .
.
, , ,
.
.
,
.

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;

.. , .. . .

65

.
, 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;

, , ..,
.

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

.. , .. . .

66

WHILE ()
, .
, ..
, .
, DO-WHILE ,
WHILE FOR, . ,
, , , ITOA, ( ATOI).
, . ,
. , .

ITOA(N,S) /*CONVERT N TO CHARACTERS IN S */


CHAR S[];
INT N;

INT I, SIGN;
IF ((SIGN = N) < 0) /* RECORD SIGN */
N = -N;

/* MAKE N POSITIVE */

I = 0;
DO

/* GENERATE DIGITS IN REVERSE ORDER */

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


(SIGN < 0)

WHILE ((N /=10) > 0); /* DELETE IT */ IF

S[I++] = '-'
S[I] = '\0';
REVERSE(S);
DO-WHILE , , ,
N, S .
, DO-WHIL,
, , WHILE
WHILE.
3-3.
ITOA
, .. N A -2
-1, . . , .
3-4.

.. , .. . .

67

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)
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

.. , .. . .

68

&& (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 ,
, , ,
.
3-6.
, ,
. (
UNIQ UNIX).

3.9. GOTO
"C" GOTO,
, . GOTO
,
. GOTO .
, , GOTO
. ,
, ,

.. , .. . .

69

. 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;
/* DIDN'T FIND */
...
FOUND:
/* FOUND ONE AT POSITION I, J */
...
, GOTO,
, , ,
. , :
FOUND = 0;
FOR (I = 0; I < N && !FOUND; I++)
FOR (J = 0; J < M && !FOUND; J++)
FOUND = V[I][J] < 0;
IF (FOUND)

.. , .. . .

70

/* IT WAS AT I-1, J-1 */


...
ELSE
/* NOT FOUND */
...
, ,
GOTO, .

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

.. , .. . .

71

:
WHILE ( )
IF ( )

,
,
.
, ,

. , .
" " 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[];

.. , .. . .

72

INT LIM;

INT C, I;
I = 0;
WHILE(--LIM>0 && (C=GETCHAR()) != EOF && C != '\N')
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 ()
.

.. , .. . .

73

/
/.
- ,
; .
.

/ /; .
,
, ,
.
RETURN
, . RETURN
:
RETURN ()
,
. , 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.

.. , .. . .

74

RINDEX(S,T),
S -1, S T.

4.2. ,
-
. ,
, , ,
WHILE (GETLINE(LINE, MAXLINE) > 0)
, ,
,
. , ,
INT. CHAR INT,
, 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';

.. , .. . .

75

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 .

/ /,
, ,
, .
#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):

.. , .. . .

76

ATOI(S) /* CONVERT STRING S TO INTEGER */


CHAR S[];

DOUBLE ATOF();
RETURN(ATOF(S));
RETURN.

RETURN ()

. RETURN F,
DOUBLE, INT, ATOI
INT. ( 2,
INT ).
4-2.
ATOF ,
123.45-6
'E' ,
.

4.3.
1 ,
, ..
, . ,
.
,
, .
,
; .
, . ,
. 5 ,

.
,
. ,
,
, .
, , ,
, ,
MAX PL/1.

.. , .. . .

77

,
,
, . "C"
PRINTF . ,
.
PRINTF ,
, ,
.
.
,
, - ; , ,
( ) .

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

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

. ,
. .

.
;
. , , .
,
. ,
, ,

.. , .. . .

78


, .
.
, ,
. +,-,*,/ = ( ).

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

12-45+*=

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

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

LSE IF ( )



ELSE

, , ,
, . . .
MAIN
, .
MAIN , ;
.

.. , .. . .

79

, 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;

.. , .. . .

80

CASE '=':
PRINTF("\T%F\N",PUSH(POP()));
BREAK;
CASE 'C':
CLEAR();
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 */

.. , .. . .

81

SP=0;
/)
C CLEAR,
PUSH POP. GETOP
.
1, ,
. ,
PUSH, POP CLEAR,
. MAIN ,
. ,
=,
PUSH(POP());

, ,
.
, + * , ,
, , /
.
4-3.

. /% /
. "", .
. / ,
/.

4.5. ,
, "C"-,
;
,
. :
,
?
,
?
4.5.1.
,
. , ,
, ,
, , . .

.. , .. . .

82

,
, . , VAL, SP, PUSH,
POP CLEAR , , :
INT SP = 0;
DOUBLE VAL[MAXVAL];
DOUBLE PUSH(F) ...
DOUBLE POP() ...
CLEAR() ...
VAL SP PUSH, POP
CLEAR ; .
,
, , ,
, EXTERN.
.
/ , ../;
.
INT SP;
DOUBLE VAL[MAXVAL];
SP VAL,
.

EXTERN INT SP;
EXTERN DOUBLE VAL[];
SP INT, VAL
DOUBLE / /,
.
, ,
;
EXTERN . / EXTERN ,
/.
. ,
EXTERN .
,
VAL SP ,
PUSH, POP CLEAR .
:

.. , .. . .

83

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'


, ;
' 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')
;

.. , .. . .

84

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) /* NUMBER IS OK */


UNGETCH(C);
S[I] = '\0';
RETURN (NUMBER);
ELSE /* IT'S 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
,

.. , .. . .

85

. 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");
ELSE
BUF [BUFP++] = C;
,
, .

4-4.
UNGETS(S), .
UNGETS BUF BUFP
UNGETCH?
4-5.
, . GETCH
UNGETCH .
4-6.
GETCH UNGETCH
EOF . ,
, EOF, .

.. , .. . .

86

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() ...

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

.

,

. , GETCH UNGETCH ""
; BUF BUFP ,

.. , .. . .

87

. 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;
...
,
.
,
.
REGISTER .
( 5).
. , ,
PDP-11 REGISTER ,
INT, CHAR .

4.8.
"C" PL/1 ;
.
, ,
. ( )
, , , . , ,
, ,
.
IF (N > 0)
INT I; /* DECLARE A NEW I */

.. , .. . .

88

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;

...
F X ,
.

4.9.
, ,
. ,
, ,
.
,
;
().
( )
, :
INT X = 1;

.. , .. . .

89

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;
...
,
.
. ,
.
.
,
, .
1,

MAIN()
(

/* COUNT DIGITS, WHITE SPACE, OTHERS */

.. , .. . .

90

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";
, :
CHAR PATTERN[] = 'T', 'H', 'E', '\0' ;
, ,
.
( \0).

4.10.
"C" ; ,
.
. ,

.. , .. . .

91

:
, .
. ,
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) /* PRINT N IN DECIMAL (RECURSIVE)*/
INT N;
(
INT I;
IF (N < 0)
PUTCHAR('-');
N = -N;

IF ((I = N/10) != 0)
PRINTD(I);
PUTCHAR(N % 10 + '0');

.. , .. . .

92

)
,
,
. , 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"
FILENAME. ( ).
,
#DEFINE EXTERN
. #INCLUDE.
#INCLUDE
. ,
, , ,
. , -TO
,
.

.. , .. . .

93

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
,
. ,
, MAX :
#DEFINE MAX(A, B) ((A) > (B)? (A) : (B))

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

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

.. , .. . .

94

MAX ,
.
, MAX,
. ; ,
, , ,
.
,
. (
#DEFINE SQUARE(X) X * X
, SQUARE(Z+1)).
:
, ,
.
.
7 -,
GETCHAR PUTCHAR ( PUTCHAR
),
.

.
4-9.
SWAP(X, Y),
INT. ( ).

5.
, .
"C". ,
, ,
, ,
.
GOTO,
, .
, ;
, - . ,
,
. .

5.1.
, ""
. , ,
, INT, , .
& ,

.. , .. . .

95

= &;
; , "" .
& , &(-1)
&3 . .
*
, . , Y
INT,
Y = *;
Y , .
= &;
Y = *;
Y ,
Y = X;
, :
INT X, Y;
INT *PX;
X Y .
INT *PX;
; ,
*PX INT. , PX *PX,
INT. , .
, .
,
DOUBLE ATOF(), *DP;
, ATOF() *DP DOUBLE.
, ,
.
. , PX
X, *PX , X.

Y = *PX + 1

.. , .. . .

96

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 ,
*PX += 1
,
(*PX)++
; ,
, * ++, ,
PX, , .
, ,
, . PY
INT,
PY = PX
PX PY, PY
, PX.

.. , .. . .

97

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
A. SWAP
.
SWAP(PX, PY)
INT *PX, *PY;

INT TEMP;
TEMP = *PX;
*PX = *PY;
*PY = TEMP;

/* INTERCHANGE *PX AND *PY */

.. , .. . .

98

,
. ( , 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;

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();

.. , .. . .

99

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]
, PA A; ,
PA A[0].
X = *PA
A[0] X.
PA A,
PA+1 , PA-I
, I , PA, PA+I ,
I . , PA A[0],

.. , .. . .

100

*(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 .
,
.
, ,
, .. ,
.
STRLEN, .
STRLEN(S)

/* RETURN LENGTH OF STRING S */

CHAR *S;

INT N;
FOR (N = 0; *S != '\0'; S++)
N++;
RETURN(N);

.. , .. . .

101

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[];

...

F(ARR)
INT *ARR;

...
F, ,
, .

.. , .. . .

102

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.
, ,
. , ..
, 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 */

.. , .. . .

103

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, ..
.
,
STATIC CHAR *ALLOCP = &ALLOCBUF[0];
, .

IF (ALLOCP + N <= ALLOCBUF + ALLOCSIZE)


, , N
. , ALLOCP ,
ALLOCBUF. ,
ALLOC (
). , ALLOC ,
, . "C" ,
,
,

.. , .. . .

104

. , , 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. , 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);

.. , .. . .

105

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.
, , ,
"I AM A STRING"
.
\0,
. ,
.
-
, , ,

PRINTF ("HELLO, WORLD\N");


, , ,
; PRINTF
.
, .
MESSAGE

.. , .. . .

106

CHAR *MESSAGE;

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

/* COPY T TO S */

CHAR S[], T[];

INT I;
I = 0;
WHILE ((S[I] = T[I]) != '\0')
I++;
STRCPY .
STRCPY(S, T) /* COPY T TO S; POINTER VERSION 1 */
CHAR *S, *T;

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


S++;
T++;

, STRCPY
S T , .

.. , .. . .

107

, , ,
S T \0.
STRCPY , .
:
STRCPY(S, T) /* COPY T TO S; POINTER VERSION 2 */
CHAR *S, *T;

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


;
S T . *T++
, T ; ++
T, .
S, S .
, , \0, T S.
, \0
,
STRCPY(S, T) /* COPY T TO S; POINTER VERSION 3 */
CHAR *S, *T;

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;
I = 0;
WHILE (S[I] == T[I])

.. , .. . .

108

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.
, , ""-
. ,
,

.. , .. . .

109

;
. ,
, ,
,
- . , ,
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-
.

.. , .. . .

110

: DAY_OF_YEAR , MONTH_DAY
.
, :
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)
INT YEAR, MONTH, DAY;

/* SET DAY OF YEAR */


/* 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, .

.. , .. . .

111

DAY_TAB ,
. "C"
, .

DAY_TAB[I][J]
DAY_TAB [I, J]
.
, . ,
.. .
,
;
. 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 .

.. , .. . .

112

5.8. ;
,
. .
,
SORT UNIX.
3 ,
. ,
, , ,
.
,
.
.
(, ,
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 */

.. , .. . .

113

IF ((NLINES = READLINES(LINEPTR, LINES)) >= 0) \( SORT(LINEPTR,


NLINES); WRITELINES(LINEPTR, NLINES);
\)
ELSE
PRINTF("INPUT TOO BIG TO SORT\N");
\)
#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]);
\)

.. , .. . .

114


CHAR *LINEPTR[LINES];
, LINEPTR LINES ,
CHAR. , LINEPTR[I]
, *LINEPTR[I] .
LINEPTR ,
WRITELINES, ,
. :
WRITELINES(LINEPTR, NLINES) /* WRITE OUTPUT LINES */
CHAR *LINEPTR[];
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) \(

.. , .. . .

115

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. ,
, ""
. , -, ,
.
,
, , .
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;
\(

.. , .. . .

116

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]);
\)
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
. ,

.. , .. . .

117


. :
, ,
. , B
10 ;
, ,
.
, ,
,
MONTH_NAME, .
5-6.

.

DAY_OF_YEAR

MONTH_DAY,

5.11.
, "",

. MAIN ,
. ( 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++)

.. , .. . .

118

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 -, ,
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;

.. , .. . .

119

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);
\)
,
. ,
. : "
, ", : "
".
""- , ,
, .
, , , -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
:

.. , .. . .

120

#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:
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 . ,

.. , .. . .

121

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 ,
M. ( )
.
5-10.
TAIL, N
. N 10,
,
TAIL -N
N . ,
N. ,
: ,
SORT, .

5.12.
"" ,
, ,
, .. ,
,

.. , .. . .

122

-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;
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);

NLINES,

STRCMP,

\) ELSE
PRINTF("INPUT TOO BIG TO SORT\N");
\)

SWAP);

WRITELINES(LINEPTR,

.. , .. . .

123

STRCMP, NIMCMP SWAP ; ,


, & ,
. .
SORT:
SORT(V, N, COMP, EXCH) /* SORT STRINGS V[0] ... V[N-1] */ CHAR *V[];
INCREASING ORDER */

/* INTO

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 , , ,
, .
COMP
IF (*COMP)(V[J], V[J+GAP]) <= 0)
: COMP , *COMP
,
(*COMP)(V[J], V[J+GAP])
- .
.

.. , .. . .

124

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,
() . , -R
-N.
5-12.
-F,
, :

.. , .. . .

125

, ''
'' ,
.
5-13.
-D (" "),
, . ,
-F.
5-14.
,
.
. (
-DF -N ).

6.
,
, . (
, , "").
:
"" , , ,
(...), , , .. : ... ,
, .

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

6.1.
5.
, , , , , ,
. :
STRUCT DATE \(
INT

DAY;

INT

MONTH;

INT

YEAR;

INT

YEARDAY;

CHAR MON_NAME[4];
\);
,
, STRUCT. STRUCT

.. , .. . .

126

, ( DAT).

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

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;

.. , .. . .

127


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

D.MON_NAME[0] = LOWER(D.MON_NAME[0]);
;
:
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" .
, ,
,
& . ,
,
. (
). ,
. ,
, ,
;
.

.. , .. . .

128

,
, .
,
,
.

DAY_OF_YEAR, 5:
D.YEARDAY = DAY_OF_YEAR(D.YEAR, D.MONTH, D.DAY);
.
HIREDATE
STRUCT 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->

.. , .. . .

129

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

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

, * . , "->" ".", ,

P->Q->MEMB

(P->Q)->MEMB

EMP.BIRTHDATE.MONTH

(EMP.BIRTHDATE).MONTH

, 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;

.. , .. . .

130

++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:
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 ,
.

.. , .. . .

131


:
STRUCT KEY \(
CHAR *KEYWORD;
INT KEYCOUNT; \) KEYTAB[] =\(
"BREAK", 0,
"CASE", 0,
"CHAR", 0,
"CONTINUE", 0,
"DEFAULT", 0,
/* ... */
"UNSIGNED", 0,
"WHILE", 0
\);
.
""
:
\( "BREAK", 0 \),
\( "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)

.. , .. . .

132

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;
ELSE
RETURN (MID);
\)
RETURN(-1);
\)
GETWORD; ,
LETTER , ,
.
NKEYS KEYTAB .
, ,
, .

KEYTAB, .
,
, .

.. , .. . .

133

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 */
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);

.. , .. . .

134

\)
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 LETTER 'A'
#DEFINE DIGIT '0'
GETWORD , TYPE
TYPE[ ].
"C" ISALPHA ISDIGIT,
.
6-1.
GETWORD ,
.
6-2.

.

TYPE,

6-3.
,
.

.. , .. . .

135

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;
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);

.. , .. . .

136

\)
, . -,
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
. , ,
-
"".
, , .
, , ,
STRUCT KEY *BINARY(WORD, TAB, N)
T , .
:
STRUCT KEY *
BINARY(WORD, TAB, N)
; , ,
.

.. , .. . .

137

6.5. , .
, ,
.
,
.
, , ;
. ( ,
). ,
?
,
,
. O ,
, .
, .
"" ; :




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

, .
,
.
.
, ,
:
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 */
\);
"" ,
. ,

.. , .. . .

138

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
, .
- , (
),
, . 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

.. , .. . .

139

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 ; ,
.
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);
\)
\)
: "" -
, ,
. , ,

.. , .. . .

140

. , 2-3
AVL , " ",
.
,
. ,
,
.

CHAR STRUCT TNODE,
. :
,
(,
)? : ,
, ALLOC
?

,
, ,
,
. , PDP-11 , ALLOC
,
.
. . ,
ALLOC ,
. ALLOC 5
; 8 ,
.
ALLOC ,
. "C"
, ALLOC CHAR,
.
, P
CHAR *P;
(STRUCT TNODE *) P

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

.. , .. . .

141

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

, .
6-6.
, ,
.
.

6.6.

,
.
. ,
, #DEFINE "C".
#DEFINE YES

YES 1 . , YES

INWORD = YES;
O 1.
,
. INSTALL(S,T) S
T ; S T . LOOKUP(S)
S , ,
NULL, .

,
.
, , .
,
NULL.
,
, .
.
STRUCT NLIST \( /* BASIC TABLE ENTRY */
CHAR *NAME;

.. , .. . .

142

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);
\)

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 ,
; ,
.

.. , .. . .

143

. - ,
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 , ,
, ALLOC.
5. ALLOC FREE
,
ALLOC 5 ; 7 8.
6-7.
, ,
LOOKUP INSTALL.
6-8.
, ,
#DEFINE, "C". GETCHAR
UNGETCH.

.. , .. . .

144

6.7.
,

;
, .
,
.
,
.
, , ,
/ ..
CHAR INT.
, , "",
,
#DEFINE KEYWORD 01
#DEFINE EXTERNAL 02
#DEFINE STATIC

04

( ).
" " ,
, 2.
:
FLAGS \!= EXTERNAL \! STATIC;
EXTERNAL STATIC FLAGS,
FLAGS &= \^(XTERNAL \! STATIC);
,
IF ((FLAGS & (EXTERNAL \! STATIC)) == 0) ...
, .
, "C"

, .
INT.
. ,
#DEFINE, ,
:
STRUCT \(
UNSIGNED IS_KEYWORD : 1;
UNSIGNED IS_EXTERN : 1;

.. , .. . .

145

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.
,
. - ,
,
, . ,
,

, .
, : ;
INT (, ,
UNSIGNED); ; ,
&.

6.8.
O ,
,
.
,
- .
, , ,
INT, FLOAT .

.. , .. . .

146


, ,

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

:
.

->
, . ,
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);

.. , .. . .

147

.
( )
, . ,
,
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
,
. , " " ,
, .
, ,
,
; ,
.
, .
, 8, ,
,
.

6.9.
"C" , TYPEDEF
. ,
TYPEDEF INT LENGTH;
LENGTH INT. "" LENGTH
, ..

.. , .. . .

148

, INT:
LENGTH LEN, MAXLEN;
LENGTH *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()
\(
CHAR *ALLOC();
RETURN((TREEPTR) ALLOC(SIZEOF(TREENODE)));
\)
, TYPEDEF
- ;
. :
, ,
. TYPEDEF #DEFINE
,
, "C". ,

.. , .. . .

149

TYPEDEF INT (*PFI) ();


PFI " , INT",
5

PFI STRCMP, NUMCMP, SWAP;

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

7.
/ "",
.
,
. "
/", ,
/ ""- .
, ,
.
,
" ",
. , , "" ,
,
"", ,
, ,
.
/;
, ""-,
.

7.1.
,
,

.. , .. . .

150

#INCLUDE <STDIO.H>
STDIO.H ,
/.

,
( UNIX LUSRLINELUDE).
,
; PDP-11 UNIX, ,
:
CC .. -LS
-LS .

7.2. GETCHAR
PUTCHAR

" ", ,
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),
'' " ", .

.. , .. . .

151

> : PROG
PUTCHAR,
PROG>OUTFILE
OUTFILE,
. UNIX .

PROG \! ANOTHERPROG
PROG ANOTHERPROG.
PROG .
, PRINTF,
, PUTCHAR PRINTF .

;
GETCHAR, PUTCHAR PRINTF
. ,

. , , 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

.. , .. . .

152

,
. ( CAT
).
, / ""
GETCHAR PUTCHAR .
.
8 , .

7.3. PRINTF
: PRINTF SCANF ( )
E
. .
PRINTF;
.
PRINTF(CONTROL, ARG1, ARG2, ...)
,
CONTROL.
: ,
, ,
PRINTF.

% . %
:
- ,
.
- , .
, ,
. ,
, ( ,
) .
,
, (
).
- , .
- (), ,
,
FLOAT DOUBLE.
- L, ,
LONG, INT.
:
D .
O
( ).

.. , .. . .

153

X (
0X).
U .
C .
S : ,
,
.
E , FLOAT
DOUBLE,
[-]M.NNNNNNE[+-]XX, N
. 6.
F , FLOAT
DOUBLE,
[-]MMM.NNNNN, N
. 6. ,
F
.
G % E % F, ;
.
% ,
; , % , %% .

. ,
.
"HELLO, WORLD" (12 ).
,
.
:% 10S:

:HELLO, WORLD:

:% 10-S:

:HELLO, WORLD:

:% 20S:

:% -20S:

:HELLO, WORLD

:% 20.10S:

:% -20.10S:

:HELLO, WOR

:% .10S:

:HELLO, WOR:

HELLO, WORLD:
:

HELLO, WOR:
:

: PRINTF
.
,
.
7-1.

.. , .. . .

154

,
.
( )
.

7.4. SCANF
SCANF PRINTF
.

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


,
, CONTROL,
.
; , , ,
.
,
.
:
- , (" "),
.
- ( % ),
.
- , %,
*, ,
.

. ,
. , , *
,
. ,
;
, ,
. , , SCANF
,
.
;
""
.
: D ;
.
O ( );
.

.. , .. . .

155

X ( 0X );
.
H SHORT;
SHORT.
C ;
;
.
; ,
, % 1S.
S ;
, ,
\0.
F ;
FLOAT.
E F.
FLOAT , ,
, E,
, .
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);

.. , .. . .

156

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 ,
,
.

.

.
EOF; , 0,

. SCANF
.
: SCANF
.
SCANF("%D", N);

SCANF("%D", &N);

7.5.
SCANF PRINTF SSCANF SPRINTF,
, , .
:
SPRINTF(STRING, CONTROL, ARG1, ARG2, ...)

.. , .. . .

157

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.

7.6.

, ,
.
- ,
, . ,
, CAT,
.
CAT
,
. ,
CAT X.C.Y.C
X.C Y.C .
, , ..,
, ,
.
.
, FOPEN
. FOPEN ( X.C Y.C),

.. , .. . .

158


( ) ,

.
, " ",
, ,
, ,
. ,
-,
STDIO.H, FILE.
:
FILE *FOPEN(), *FP;
, FP FILE FOPEN
FILE. O , FILE ,
INT, ; TYPEDEF. ( ,
UNIX, 8).
FOPEN :
FP=FOPEN(NAME,MODE);
FOPEN "" ,
. MODE ("")
, , .
: ("R"), ("W") ("A").
, , ,
(
).
. .
(,
, ). -
NULL (
STDIO.H).
,
. , GETC PUTC
.
GETC ; ,
, . ,
C=GETC(FP)
"C" , FP, EOF,
.
PUTC, GETC,

.. , .. . .

159

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 .
:
, . ,
.
, .
#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:CAN'T OPEN %\N",*ARGV);
BREAK;
\) ELSE \(
FILECOPY(FP);
FCLOSE(FP);

.. , .. . .

160

\)
\)
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
).

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
FILECOPY(STDIN);

ARGS;

161

COPY

STANDARD

INPUT*/

ELSE
WHILE (--ARGC >
PRINTF(STDERR,

0)

IF((FP=FOPEN(*++ARGV,"R#))==NULL)

\(

"CAT: CAN'T OPEN,% S\N", ARGV);


EXIT(1);
\) ELSE \(
FILECOPY(FP);
\)
EXIT(0);
\)
. ,
FPRINTF, STDERR , ,
, (PIPELINE) .
EXIT ,
.
EXIT , ,
, . 0
, ,
.
EXIT FCLOSE
, ,
_EXIT. _EXIT
- ; ,
.

7.8.
FGETS,
GETLINE, .

FGETS(LINE, MAXLINE, FP)
( ) FP
LINE; MAXLINE_1 .
\ 0. FGETS
LINE; NULL. ( GETLINE
,
- ).
FPUTS (
) :

.. , .. . .

162

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*/
REGISTER CHAR *S;
REGISTER FILE *IOP;
\(
REGISTER INT C;
WHILE (C = *S++)
PUTC(C,IOP);
\)
7-3.
,
, .
7-4.
5
,
, , .
?
7-5.

.. , .. . .

163

,

.

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" .
7.9.2. UNGETC

UNGETCH, 4; UNGETC.

UNGETC(C,FP)
"C" FP.
. UNGETC

SCANF, GETC GETCHAR.
7.9.3.
SYSTEM(S) , S,
. S

.. , .. . .

164

. , ,
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.

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

"C".
: /,
.
UNIX.

.. , .. . .

165

7 ,
.
-,
.

UNIX ,
.

8.1.
UNIX
, ,
, .
,
.

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

.
("SHELL") , ,
, ,
0, 1 2 .
,
0 1 2,
,
.
,
SHELL "<" ">" :
PROG <INFILE>OUTFILE
SHELL
0 1 .
2 , . ,
. ,
SHELL, . ,
0 1 2 , ,
.

.. , .. . .

166

8.2. / READ WRITE


/ UNIX , - ;
.
: READ WRITE.
. ,
.
. :
N_READ=READ(FD,BUF,N);
N_WRITTEN=WRITE(FD,BUF,N);
,
.
, .
, "-1" - .
;
, , .
, ,
. "1",
(.. ),
"512",
. ,
.
,
, , 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,
.

.. , .. . .

167

#DEFINE CMASK 0377 /*FOR MAKING CHAR'S > 0*/


GETCHAR() /*UNBUFFERED SINGLE CHARACTER INPUT*/
\(
CHAR C;
RETURN((READ(0,&C,1)>0 7 & CMASK : EOF);
\)
"C" CHAR, READ
.
0377 ;
. ( 0377 PDP11, ).
GETCHAR ,
.
#DEFINE CMASK 0377 /*FOR MAKING CHAR'S>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*/
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);

.. , .. . .

168

FOPEN, NAME ,
. ,
, : RWMODE : 0 , 1 , 2
. - , OPEN "-1";
.
, , .
CREAT .

FD=CREAT(NAME,PMODE);
,
NAME, "-1" . , CREAT
; , ,
.
, CREAT
, PMODE. UNIX
,
, ,
. ,
. ,
0755 ,
.

, CP UNIX. (
,
).
#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:CAN'T OPEN % S", ARGV[1]);
IF ((F2=CREAT(ARGV[2],PMODE))== -1)
ERROR("CP: CAN'T CREATE % S", ARGV[2]);
WHILE ((N=READ(F1,BUF,BUFSIZE))>0)

.. , .. . .

169

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 .
.

8.4. SEEK LSEEK


:
READ WRITE
, .

. LSEEK
, .
LSEEK(FD,OFFSET,ORIGIN);
FD
OFFSET (), ,
ORIGIN ( ).
.
OFFSET LONG; FD ORIGIN INT.

.. , .. . .

170

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));
\)
, 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
,
.

.. , .. . .

171

,
, .
, :
, ; ,
; ;
, ..; .
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

/*NUMBER OF CHARACTERS LEFT*/

_CNT;

CHAR *_BASE;

/*LOCATION OF BUFFER*/

INT

_FLAG;

/*MODE OF FILE ACCESS*/

INT

_FD;

/*FILE DESCRIPTOR*/

) FILE;
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 \

.. , .. . .

172

? *(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;
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);

.. , .. . .

173

LSEEK(FD,OL,2);
\) ELSE
FD=OPEN(NAME,0);
IF(FD==-1) /*COULDN'T 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*/
IF(FP->_FLAG & _UNBUF) /*UNBUFFERED*/ FP->_BASE=&SMALLBUF[FP->_FD];
ELSE IF((FP->_BASE=CALLOC(_BUFSIZE,1))==NULL)
FP->_FLAG \!=_UNBUF; /*CAN'T GET BIG BUF*/
ELSE
FP->_FLAG \!=_BIGBUF; /*GOT BIG ONE*/
>_BASE; FP->_CNT=READ(FP->_FD, FP->_PTR,

FP->_PTR=FP-

FP->_FLAG & _UNBUF? 1 : _BUFSIZE); FF(--FP->_CNT<0) \(


IF(FP->_CNT== -1)
FP->_FLAG \! = _EOF;
ELSE
FP->_FLAG \! = _ ERR;
FP->_CNT = 0;

.. , .. . .

174

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.
8-5.

FSEEK(FP, OFFSET, ORIGIN)
LSEEK, , FP ,
. FSEEK. , FSEEK
, .

8.6.

, , .
LS (" ") UNIX.

.. , .. . .

175

, , ,
, ..
, , 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 UNSIGNED,
, :
. TYPEDEF.
"" SYS/TUPES.H.
STAT I-
( -1, ). ,

STRUCT STAT STBUF;


CHAR *NAME;
STAT(NAME,&STBUF);
STBUF I-
NAME. ,
STAT , SYS/STAT.H :

.. , .. . .

176

STRUCT STAT /*STRUCTURE RETURNED BY STAT*/


\(
DEV_T

ST_DEV;

/* DEVICE OF INODE */

INO_T

ST_INO;

/* INODE NUMBER */

SHORT

ST_MODE

/* MODE BITS */

SHORT

ST_NLINK;

/ *NUMBER OF LINKS TO FILE */

SHORT

ST_UID;

/* OWNER'S USER ID */

SHORT

ST_GID;

/* OWNER'S GROUP ID */

DEV_T

ST_RDEV;

/* FOR SPECIAL FILES */

OFF_T

ST_SIZE;

/* FILE SIZE IN CHARACTERS */

TIME_T ST_ATIME; /* TIME LAST ACCESSED */


TIME_T ST_MTIME; /* TIME LAST MODIFIED */
TIME_T ST_CTIME; /* TIME ORIGINALLY CREATED */
\)
. ST.MODE
, ;
SYS/STAT.H.

#DEFINE S_IFMT

0160000 /* TYPE OF FILE */

#DEFINE S_IFDIR 0040000 /* DIRECTORY */


#DEFINE S_IFCHR 0020000 /* CHARACTER SPECIAL */
#DEFINE S_IFBLK 0060000 /* BLOCK SPECIAL */
#DEFINE S_IFREG 0100000 /* REGULAR */
#DEFINE S_ISUID 04000 /* SET USER ID ON EXECUTION */ #DEFINE S_ISGID
02000 /* SET GROUP ID ON EXECUTION */
#DEFINE S_ISVTX 01000 /*SAVE SWAPPED TEXT AFTER USE*/ #DEFINE S_IREAD
0400 /* READ PERMISSION */
#DEFINE S_IWRITE 0200

/* WRITE PERMISSION */

#DEFINE S_IEXEC 0100

/* EXECUTE PERMISSION */

FSIZE.
STAT , ,
.
,
; ,
.
,
; FSIZE .
#INCLUDE <STDIO.H.>

.. , .. . .

177

#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)==
%S\N",NAME); RETURN;

-1)

\(

FPRINTF(STDERR,"FSIZE:CAN'T FIND

\)
IF((STBUF.ST_MODE & S_IFMT)==S_IFDIR)
DIRECTORY(NAME);
PRINTF("% 8LD % S\N",STBUF.ST_SIZE,NAME);
\)
DIRECTORY .
,
.
DIRECTORY(NAME)
CHAR *NAME;
(

/*FSIZE FOR ALL FILES IN NAME*/

.. , .. . .

178

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, ,
.

8.7.
5 ALLOC. ,
, :
ALLOC FREE ; ,
ALLOC . ,
,

.. , .. . .

179

, -
- , ,
TYPEDEF.
,
, ALLOC
.
, , ALLOC,
.
. ,
. ,
( ) ,
.
,
.
, .
, ,
, .
, ,
; .

.
-
, ,
. ,
.
, 5,
, ALLOC
, . , ,
,
, .
, IBM 360/370,HONEYWELL 6000
, DOUBLE;
PDP-11 INT.
,
;
.
, .
,
:
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*/ \);

.. , .. . .

180

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));
\)
IF(P==ALLOCP) /*WRAPPED AROUND FREE LIST*/
IF((P=MORECORE(NUNITS))==NULL)
RETURN(NULL); /*NONE LEFT*/
\)
\)

.. , .. . .

181

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));
RETURN(ALLOCP);
\)
, SBRK
"-1", NULL . "-1"
INT.

.. , .. . .

182

() ,
.
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
).

.
, .
8-6.
CALLOC(N,SIZE)
"N" SIZE,
. CALLOC, ALLOC
, , .

.. , .. . .

183

8-7.
ALLOC ,
; FREE , ,
, .
, .
8-8.
BFREE(P,N), "P" "N"
, ALLOC FREE.
BFREE
.

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

.. , .. . .

184

HONEYWELL 6000

6 , 1

IBM 360/370

7 , 1

INTERDATA 8/32

8 , 2

10.3.

:
INT
CHAR
FLOAT

EXTERN
REGISTER
TYPEDEF

ELSE
FOR
DO

DOUBLE

STATIC

STRUCT

GOTO

SWITCH

RETURN

CASE

UNION
LONG
SHORT

SIZEOF
BREAK

UNSIGNED
*AUTO

WHILE

DEFAULT
ENTRY

CONTINUE
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 (-),
. ,
.

.. , .. . .

185

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,
.
" \; ,
, .
, \,
, .

.. , .. . .

186

10.6.

, .
, ,
.
1
DEC PDP-11

HONEYWELL

IBM 370

INTERDATA

ASCII

ASCII

EBCDIC

ASCII

CHAR 8 BITS

9 BITS

8 BITS

8 BITS

INT 16

36

32

32

SHORT 16

36

16

16

LONG 32

36

32

32

FLOAT 32

36

32

32

DOUBLE 64

72

64

64 -76/+76

RANGE -38/+38

38/+38

-76/+76

8/32

11.

(. .:
),
.
. , ,
"",
\(
--------- \)
,
18.

12. ?
"C"
: .
, ;
, , .
: , ,
.
.
,
, .

, . ( )

.. , .. . .

187

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

, .
CHAR INT . FLOAT
DOUBLE .

,
:

, ;

, .

, .

13. L-
; L-
, . L-
. , L; , , E , *E
L-, E. "L-"
E1=E2,
L-.
, L- L-.

.. , .. . .

188

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.

-;
. ,
.

. ,
.

14.4.

; ,
.
;
,
.

.. , .. . .

189

14.5.
, ,
.
, (
2** ).
.
LONG,
. ,
.

14.6.

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

15.

,
. , , ,
+ (.15.4), , ..15.1-15.3.
.
.

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

-. "C"

.. , .. . .

190

; 0

.

15.1.
,
, .

.,

->,

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

-,
,
, .
. , , " ...",
, ,
, " ...".
, L-.
, ", ...", ,
, " , ...".
.
INT, LONG DOUBLE.
. "
"; ,
, " ",
. (
; . . 16.6.)
,
.
, L- .
, ,
. , .
" ...",
INT, "...". E1[E2]
* ((E1) + (E2)). ,
,

; ,

* + .. 15.1, 15.2 15.4
; . 22.3.
,
,
, .

.. , .. . .

191

", ...",
"...". ,
,
, , ,
; ,
, .
FLOAT
DOUBLE, CHAR SHORT INT, ,
, .
; ,
.
, (CAST); . .. 15.2, 16.7.

; , "C"
.
, .
,
, .
; ,
.
.
, ,
. L-,
,
. L-,
.
, (
>) , .
,
. L-,
,
.
, E1->MOS ,
(*E1).MOS. . 16.5.
,
. . . 22.1.

15.2.
.
-:
*
& L-
-

\^
++ L-
--

L-

.. , .. . .

192

L- ++
L- -(-)
SIZEOF
SIZEOF -
* :
, L-, ,
. " ...",
"...".
& ,
L-. L- "...",
" ...".
() ,
. UNSIGNED
2**N ( N), N- 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).
.
.

.. , .. . .

193

, . , ,
- .
SIZEOF
.
.
SIZEOF () ,
SIZEOF () 2 (SIZEOF ()9 2.

15.3.
*, /, %
.

-:

*
/ %

* . * ,

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

15.4.
+ .
.
, .
-:

+ .
.
,
.
, ,
,
. , P ,
P+1 .
.
+ ,
.

.. , .. . .

194

.
. ,
, ,
, .
,
( ) INT,
, .
, , ,
,
, .

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.
-:

!=

==

== () != ( ) ,
, . (

.. , .. . .

195

A<B==C<D 1 , A<B C<D


).
, , 0. ,
, 0,
0; .

15.8. ''
-: &
& , &
.

;
'' .
.

15.9. ''
--:
^
^ , ^
.

;
'' .
.

15.10. ''
--:
\!
\! , \!
.

;
'' .
.

15.11. ''
--:

&&

&& . 1,
, 0 . & &&
; , 0,
.
,
, . ITN.

.. , .. . .

196

15.12. ''
--:

\!\!

\!\! . 1,
, 0 . \!
\!\! ; ,
, .
,
, . INT.

15.13.
-:
? :
.
, ,
; .
, , ,
; ,
,
; ,
0, .
.

15.14.
,
. L-,
.
, ,
.
.
-:
L- =
L- +=
L- -=
L- *=
L- /=
L- % =
L- >>=
L- <<=
L- &=
L- ^=
L- \!=

.. , .. . .

197

C'=',
, L-.
,
.
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"
; ,
.
:
- -
;
.

.
-:

.. , .. . .

198

- -

-- -

, .

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
SHORT
INT

.. , .. . .

199

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.
, .
:
:

( )
*
()
[-
]
.

.. , .. . .

200

16.4.
,
, , ,
.
; ,
.
, ,
.
,
.
.

T

DI

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

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

.. , .. . .

201

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

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.
, .
. ,
.
. ---
-- \( --\)

--

\(--\)

.. , .. . .

202

--
--:
STRUCT
UNION
--
:

--: - --
-:
- --
--:
-
-, --

.
. ;
.
-:
:

,
. ,
, ,
; . ,
, ;
. , ,
. PDP-11
.
, ,
, ,
.
0
. , " "
, ,
.
, ,
- .
, INT . PDP-11
.
&,
.

.. , .. . .

203

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

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

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

.. , .. . .

204

, S , SP
.
SP->COUNT
COUNT , SP;
S.LEFT
S,
S.RIGHT->TWORD[0]
TWORD
S.

16.6.
.

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

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

.. , .. . .

205

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

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
\);
Y ,
Y[0] . 3 .
Y[1] Y[2].

.. , .. . .

206

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]

.. , .. . .

207

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.

.. , .. . .

208

;

.

17.2. ( )
,
,
( ""):
:
\(-

\)
-:

-
-:

-
- - ,

.

.
( ) ;
.
, .
,

.

17.3.
:
IF ()
IF () ELSE
, ,
. , ,

"ELSE"

ELSE IF, ELSE.

.. , .. . .

209

17.4. WHILE
WHILE
WHILE ()
,
. .

17.5. DO
DO
DO WHILE ()
,
. .

17.6. FOR
FOR
(-1 ; -2 ; -3 )

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

.

17.7. SWITCH
SWITCH (),
, .

SWITCH ()

.. , .. . .

210

,
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;

WHILE, DO FOR; .
,

.. , .. . .

WHILE(...) \(

DO \(

...

...

CONTIN: ;
\)

211

FOR(...) \(
...

CONTIN: ;
\) WHILE(...);

CONTIN: ;
\)

CONTINUE GOTO CONTIN. ( CONTIN:


; . . 17.13.).

17.10.

RETURN,
RETURN;
RETURN ;
.
. ,
, ,
. .

17.11. GOTO

GOTO 1
(. 9.12),
.

17.12.

:
.
,
GOTO. ,
, .
. 19.

17.13.
:
;

.. , .. . .

212

,
\)
, WHILE.

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

18.1.

-:
- -
-

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

, -
-
-:
- -

. , ,
INT.
REGISTER; ,

.. , .. . .

213

,
, .
:
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- ;

.
,
.
: -, ,

,
, "
"; -, ,

.. , .. . .

214

,
.

19.1.
,
, ,
.

, , . , ,
.
, .

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

DISTANCE (. : , .).

19.2.
, EXTERN, -
, ,
. ,
,
, ,
,
, .

.. , .. . .

215

EBTERN ,
.
,
, EXTERN,
. ,
,
EXTERN. , .
, STATIC,
. STATIC.

20.
"C" ,
, .
, #, .
;
( )
.

20.1.

#DEFINE -
( ) ,

.
#DEFINE

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

.
,
\ .

.. , .. . .

216

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

#UNDEF
.

20.2.

#INCLUDE "FILENAME"
FILENAME.
,
.
#INCLUDE <FILENAME>

.
#INCLUDE .

20.3.

#IF
, (. . 15).

#IF DEF
, ,
.. #DEFINE.

21.

.
.
, ,
, INT; ,
, AUTO.

.. , .. . .

217

, AUTO
( "C"
); ", ...",
EXTERN.
,
(, ",
INT".

22.
,
.

22.1.
:
( ) (
&). ,
, . ,
, - , .
. 15.1 , (
. ->) ,
.
, .
'.' L- , L-
, .
, , '->',
. , ,
.
,
.
.

22.2.
: .
,
, .
, ,
INT F();
...
G(F);
G :
G(FUNCP)
INT(*FUNCP)();

.. , .. . .

218

\(
...
(*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. *
, , , ,
(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.

.. , .. . .

219

,
. INT LONG,
. , ,
. .

.
, -.
.
,
, . ,
,
.
,
, ;
.
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,

.. , .. . .

220

+ * / . % & \! << >> == 1= <> <= >=



- \^
?:
,
.
( ) ;

&
, .
& ,
. ,
,
.

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

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

INT, ,
. , , ,
,
-.

.. , .. . .

221


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

. ,
PDP-11 ,
, , .

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

INT X 1;
-
INT F (1+2)
,
.

26.
"C"
.

.. , .. . .

222

26.1.
:
:
-
*
&
-
!
\^
++ L-
-- L-
L- ++
L-
SIZEOF
( )
-
? :
L-

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

[]
L-
.

-
->
*
(L-)

() [] . ->

.. , .. . .

223

.
* & ! \^ ++ SIZEOF( )
, ,
, .
. (. .:
; 1978
.) :
:
* / %
+ >> <<
< > <= >=
== !=
&
\^
\!
&&
\!\!
?:

.
:
= += -= *= ?= % = >>= <<= &= \^= \!=
.

26.2.
:
- -- ;
---------------------------------------------------------:
- -

-- -

--:

.. , .. . .

224

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

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

--

-
- -- :

.. , .. . .
-

225

--:

--

-
-,-- -:

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

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

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

26.3. -:
-

\(-

\)

-:

-
-:

-
:

;

.. , .. . .

226

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

;-2

;-3

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

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

- -

-:
(-

-:

, -
-:
-- -
-:
\(

-\)

:
EXTERN

.. , .. . .

227

STATIC



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

27.
,
.
. , ,
.
PDP-11
:
,
, .
, ,
, , ;
.

28.
, .
- 8.2.

.. , .. . .

228

-:
ENUM -
ENUM -
ENUM
c-:

-,
:

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

COLOR ,
CP , COL
.
-
, ( ) .
( =), 0
1 .
=
;
.


.
,
, LINT
. PDP-11
, INT.

.. , .. . .

229

29.
"C".
(
..) "C",
.
**

\(

\)

\!

\'

\^

UNIX.
"C" ,
.

You might also like