-
Notifications
You must be signed in to change notification settings - Fork 80
/
c.refman
executable file
·2292 lines (1858 loc) · 82.9 KB
/
c.refman
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
C Reference Manual
2 March 1977
Dennis M. Ritchie
Bell Telephone Laboratories
Murray Hill, New Jersey 07974
Alan Snyder
Laboratory for Computer Science
Massachusetts Institute of Technology
1. Introduction
C is a computer language based on the earlier language B [1],
itself a descendant of BCPL [3]. C differs from B and BCPL
primarily by the introduction of types, along with the
appropriate extra syntax and semantics.
Most of the software for the UNIX time-sharing system [4] is
written in C, as is the operating system itself. In addition to
the UNIX C compiler, there exist C compilers for the HIS 6000 and
the IBM System/370 [2]. This manual describes the C programming
language as implemented by the portable C compiler [6]. It is a
revision by the second author of the original C Reference Manual
(contained in [5]), which describes the UNIX C compiler.
Differences with respect to the UNIX C compiler and undesirable
limitations of the current portable C compiler are described in
footnotes to this document.
The report ``The C Programming Language'' [5] contains a
tutorial introduction to C and a description of a set of portable
I/O routines, concerned primarily with I/O.
2. Lexical conventions
There are six kinds of tokens: identifiers, keywords,
constants, strings, expression operators, and other separators.
In general blanks, tabs, newlines, and comments as described
below are ignored except as they serve to separate tokens. At
least one of these characters is required to separate otherwise
adjacent identifiers, constants, and certain operator-pairs.
If the input stream has been parsed into tokens up to a given
character, the next token is taken to include the longest string
of characters which could possibly constitute a token.
2.1 Comments
The characters /* introduce a comment, which terminates with
the characters */. Comments thus may not be nested.
C Reference Manual - 2
2.2 Identifiers (Names)
An identifier is a sequence of letters and digits; the first
character must be alphabetic. The underscore ``_'' counts as
alphabetic. Upper and lower case letters are not distinguished.
There is no limit placed on the length of identifiers; all
characters of internal identifiers are significant. However, the
number of significant characters in external identifiers (i.e.,
function names and names of external variables) may be limited by
1
the operating system to as few as the first five characters.
This limitation on external identifiers can be circumvented, to
some extent, by using the token replacement facility (described
in section 12.1).
2.3 Keywords
The following identifiers are reserved for use as keywords, and
may not be used otherwise:
int break
char continue
float if
double else
long goto
short return
unsigned entry
struct for
auto do
extern while
register switch
static case
sizeof default
typedef
The entry keyword is not currently implemented by any compiler
but is reserved for future use.
2.3 Constants
There are several kinds of constants, as follows:
2.3.1 Integer constants
An integer constant is a sequence of digits. An integer is
taken to be octal if it begins with 0, hexadecimal if it begins
with 0x (or 0X), and decimal otherwise. The digits 8 and 9 have
octal value 10 and 11 respectively. An integer constant
_________________________
1
The UNIX C compiler distinguishes upper and lower case in all
identifiers and accepts keywords only in lower case. In
addition, the UNIX C compiler treats only the first eight
characters of internal identifiers and the first seven characters
of external identifiers as significant.
C Reference Manual - 3
2
immediately followed by l or L is a long integer constant.
2.3.2 Character constants
3
A character constant consists of a single ASCII character
enclosed in single quotes `` ' ''. Within a character constant a
single quote must be preceded by a back-slash ``\''. Certain
non-graphic characters, and ``\'' itself, may be escaped
4
according to the following table:
BS \b
NL \n
CR \r
HT \t
VT \v
FF \p
ddd \ddd
\ \\
The escape ``\ddd'' consists of the backslash followed by 1, 2,
or 3 octal digits which are taken to specify the value of the
desired character. A special case of this construction is ``\0''
(not followed by a digit) which indicates a null character.
Character constants behave exactly like integers whose value is
5
the corresponding ASCII code. They do not behave like objects
of character type.
2.3.3 Floating constants
A floating constant consists of an integer part, a decimal
point, a fraction part, an e (or E), and an optionally signed
integer exponent. The integer and fraction parts both consist of
a sequence of digits. Either the integer part or the fraction
part (not both) may be missing; either the decimal point or the e
and the exponent (not both) may be missing. Every floating
constant is taken to be double-precision.
_________________________
2
A long integer constant is equivalent to an integer constant
in the portable C compiler.
3
The UNIX C compiler allows 2 characters in character
constants. Other compilers may allow as many characters as can
be packed into a machine word. The order of packed characters in
a machine word is machine-dependent.
4
The UNIX C compiler does not recognize \v or \p.
5
On UNIX, character constants range in value from -128 to 127.
C Reference Manual - 4
2.4 Strings
A string is a sequence of characters surrounded by double
quotes `` " ''. A string has the type array-of-characters (see
below) and refers to an area of storage initialized with the
given characters. The compiler places a null byte ( \0 ) at the
end of each string so that programs which scan the string can
find its end. In a string, the character `` " '' must be
preceded by a ``\'' ; in addition, the same escapes as described
for character constants may be used.
String constants are constant, i.e., they may not be modified.
3. Syntax notation
In the syntax notation used in this manual, syntactic
categories are indicated by italic type, and literal words and
characters in gothic. Alternatives are listed on separate lines.
An optional terminal or non-terminal symbol is indicated by the
subscript ``opt,'' so that
{ expression }
opt
would indicate an optional expression in braces.
4. What's in a Name?
C bases the interpretation of an identifier upon two attributes
of the identifier: its storage class and its type. The storage
class determines the location and lifetime of the storage
associated with an identifier; the type determines the meaning of
the values found in the identifier's storage.
There are four declarable storage classes: automatic, static,
external, and register. Automatic variables are created upon
each invocation of the function in which they are defined, and
are discarded on return. Static variables are local to a
function or to a group of functions defined in one source file,
but retain their values independently of function invocations.
External variables are independent of any function and accessible
by separately-compiled functions. Register variables are stored
(if possible) in the fast registers of the machine; like
automatic variables they are local to each function and disappear
on return.
C supports four fundamental types of objects: characters,
integers, single-, and double-precision floating-point numbers.
Characters (declared, and hereinafter called, char) are
chosen from the ASCII set; they occupy the right-most seven
bits in a machine-dependent unit of storage called a byte.
Integers (int) are represented in 2's complement notation in
a machine-dependent unit of storage called a word. Integers
C Reference Manual - 5
1
should be at least 16 bits long.
The precision and range of single precision floating point
(float) quantities and double-precision floating-point
(double, or long float) quantities are machine-dependent.
Besides the four fundamental types there is a conceptually
infinite class of derived types constructed from the fundamental
types in the following ways:
arrays of objects of most types;
functions which return objects of a given type;
pointers to objects of a given type;
structures containing objects of various types.
In general these methods of constructing objects can be applied
recursively.
5. Objects and lvalues
An object is a manipulatable region of storage; an lvalue is an
expression referring to an object. An obvious example of an
lvalue expression is an identifier. There are operators which
yield lvalues: for example, if E is an expression of pointer
type, then *E is an lvalue expression referring to the object to
which E points. The name ``lvalue'' comes from the assignment
expression ``E1 = E2'' in which the left operand E1 must be an
lvalue expression. The discussion of each operator below
indicates whether it expects lvalue operands and whether it
yields an lvalue.
6. Conversions
A number of operators may, depending on their operands, cause
conversion of the value of an operand from one type to another.
This section explains the result to be expected from such
conversions.
6.1 Characters and integers
A char object may be used anywhere an int may be. In all cases
the char is converted to an int by extending the character value
2
with high-order zero bits.
_________________________
1
The UNIX C compiler implements a longer variety of integer
(declared as long or long int) and unsigned integers (declared as
unsigned or unsigned int), for which most int operations are
applicable. The portable C compiler treats long int, short int,
and unsigned int as synonymous with int.
2
On the PDP-11, a character is converted to an integer by
propagating its sign through the upper 8 bits of the resultant
integer. Thus, it is possible to have (non-ASCII) characters
with negative values.
C Reference Manual - 6
6.2 Float and double
All floating arithmetic in C is carried out in
double-precision. Whenever a float appears in an expression, it
is lengthened to double by zero-padding its fraction. When a
double must be converted to float, for example by an assignment,
the double is rounded before truncation to float length.
6.3 Float and double; integer and character
Ints and chars may be converted to float or double; truncation
may occur for some values. Conversion of float or double to int
1
or char takes place with rounding. Again, erroneous results are
possible for some values.
6.4 Pointers and integers
Integers may be added to pointers; in such cases the int is
converted as specified in the discussion of the addition
operator.
Two pointers to objects of the same type may be subtracted; in
this case the result is converted to an integer as specified in
the discussion of the subtraction operator.
7. Expressions
The precedence of expression operators is the same as the order
of the major subsections of this section (highest precedence
first). Thus the expressions referred to as the operands of +
(section 7.4) are those expressions defined in sections 7.1-7.3.
Within each subsection, the operators have the same precedence.
Left- or right-associativity is specified in each subsection for
the operators discussed therein. The precedence and
associativity of all the expression operators is summarized in an
appendix.
Unless otherwise noted, the order of evaluation of expressions
is undefined. In particular the compiler considers itself free
to compute subexpressions in the order it believes most
efficient, even if the subexpressions involve side effects.
7.1 Primary expressions
Primary expressions involving . , ->, subscripting, and
function calls group left to right.
7.1.1 identifier
An identifier is a primary expression, provided it has been
suitably declared as discussed below. Its type is specified by
its declaration. However, if the type of the identifier is
``array of . . .'', then the value of the identifier-expression
is a pointer to the first object in the array, and the type of
the expression is ``pointer to . . .''. Moreover, an array
identifier is not an lvalue expression.
Likewise, an identifier which is declared ``function returning
_________________________
1
On UNIX, this conversion involves truncation towards 0.
C Reference Manual - 7
. . .'', when used except in the function-name position of a
call, is converted to ``pointer to function returning . . .''.
7.1.2 constant
A decimal, octal, character, or floating constant is a primary
expression. Its type is int in the first three cases, double in
the last.
7.1.3 string
A string is a primary expression. Its type is originally
``array of char''; but following the same rule as in section
7.1.1 for identifiers, this is modified to ``pointer to char''
and the result is a pointer to the first character in the string.
7.1.4 ( expression )
A parenthesized expression is a primary expression whose type
and value are identical to those of the unadorned expression.
The presence of parentheses does not affect whether the
expression is an lvalue.
7.1.5 primary-expression [ expression ]
A primary expression followed by an expression in square
brackets is a primary expression. The intuitive meaning is that
of a subscript. Usually, the primary expression has type
``pointer to . . .'', the subscript expression is int, and the
type of the result is `` . . . ''. The expression ``E1[E2]'' is
identical (by definition) to ``* (( E1 ) + ( E2 )) ''. All the
clues needed to understand this notation are contained in this
section together with the discussions in sections 7.1.1, 7.2.1,
and 7.4.1 on identifiers, *, and + respectively; section 14.3
below summarizes the implications.
7.1.6 primary-expression ( expression-list )
opt
A function call is a primary expression followed by parentheses
containing a possibly empty, comma-separated list of expressions
which constitute the actual arguments to the function. The
primary expression must be of type ``function returning . . .'',
and the result of the function call is of type `` . . . ''. As
indicated below, a hitherto unseen identifier followed
immediately by a left parenthesis is contextually declared to
represent a function returning an integer; thus in the most
common case, integer-valued functions need not be declared.
Any actual arguments of type float are converted to double
before the call; any of type char are converted to int.
In preparing for the call to a function, a copy is made of each
actual parameter; thus, all argument-passing in C is strictly by
value. A function may change the values of its formal
parameters, but these changes cannot possibly affect the values
of the actual parameters. On the other hand, it is perfectly
possible to pass a pointer on the understanding that the function
may change the value of the object to which the pointer points.
Note that the order of evaluation of function arguments is not
defined.
Recursive calls to any function are permissible.
C Reference Manual - 8
7.1.7 primary-lvalue . member-of-structure
An lvalue expression followed by a dot followed by the name of
a member of a structure is a primary expression. The object
referred to by the lvalue must be of a structure type, and the
1
member-of-structure must be a member of that structure. The
result of the expression is an lvalue appropriately offset from
the origin of the given lvalue whose type is that of the named
structure member.
Structures are discussed in section 8.5.
7.1.8 primary-expression -> member-of-structure
The primary-expression must be a pointer to a structure and the
2
member-of-structure must be a member of that structure type.
The result is an lvalue appropriately offset from the origin of
the pointed-to structure whose type is that of the named
structure member.
The expression ``E1->MOS'' is exactly equivalent to
``(*E1).MOS''.
7.2 Unary operators
Expressions with unary operators group right-to-left.
7.2.1 * expression
The unary * operator means indirection: the expression must be
a pointer, and the result is an lvalue referring to the object to
which the expression points. If the type of the expression is
``pointer to . . .'', the type of the result is `` . . . ''.
7.2.2 & lvalue-expression
The result of the unary & operator is a pointer to the object
referred to by the lvalue-expression. If the type of the
lvalue-expression is `` . . . '', the type of the result is
``pointer to . . .''.
7.2.3 - expression
The result is the negative of the expression. The type of the
expression must be char, int, float, or double. The type of the
3
result is int or double.
_________________________
1
The UNIX C compiler allows any primary-lvalue and assumes it
to have the same form as the structure containing the named
structure member.
2
The UNIX C compiler allows any primary-lvalue and assumes it
to be a pointer which points to an object of the same form as the
structure of which the member-of-structure is a part.
3
The UNIX C compiler defines the type of the result to be the
same as the type of the operand.
C Reference Manual - 9
7.2.4 ! expression
The result of the logical negation operator ! is 1 if the value
of the expression is zero, 0 if the value of the expression is
non-zero. The type of the result is int. The allowable
1
expressions are those allowed by the if statement (section 9.3).
7.2.5 ~ expression
The ~ operator yields the one's complement of its operand. The
type of the expression must be int or char, and the result is
int.
7.2.6 ++ lvalue-expression
The object referred to by the lvalue expression is incremented.
The value is the new value of the lvalue expression and the type
is the type of the lvalue. If the expression is of a fundamental
2
type, it is incremented by 1; if it is a pointer to an object,
it is incremented by the length of the object.
7.2.7 -- lvalue-expression
The object referred to by the lvalue expression is decremented
analogously to the ++ operator.
7.2.8 lvalue-expression ++
The result is the value of the object referred to by the lvalue
expression. After the result is noted, the object referred to by
the lvalue is incremented in the same manner as for the prefix ++
3
operator: by 1 for an object of fundamental type, by the length
of the pointed-to object for a pointer. The type of the result
is the same as the type of the lvalue-expression.
7.2.9 lvalue-expression --
The result of the expression is the value of the object
referred to by the the lvalue expression. After the result is
noted, the object referred to by the lvalue expression is
decremented in a way analogous to the postfix ++ operator.
7.2.10 sizeof expression
The sizeof operator yields the size, in bytes, of its operand.
When applied to an array, the result is the total number of bytes
in the array. The size is determined from the declarations of
the objects in the expression. The major use of sizeof is in
_________________________
1
The UNIX C compiler does not allow float or double operands.
2
The portable C compiler does not allow float or double
operands.
3
The portable C compiler does not allow float or double
operands.
C Reference Manual - 10
communication with routines like storage allocators and I/O
1
systems.
7.3 Multiplicative operators
The multiplicative operators *, /, and % group left-to-right.
7.3.1 expression * expression
The binary * operator indicates multiplication. If both
operands are int or char, the result is int; if one is int or
char and one float or double, the former is converted to double,
and the result is double; if both are float or double, the result
is double. No other combinations are allowed.
7.3.2 expression / expression
The binary / operator indicates division. The same type
considerations as for multiplication apply.
7.3.3 expression % expression
The binary % operator yields the remainder from the division of
the first expression by the second. Both operands must be int or
char, and the result is int. The use of this operation is not
recommended for negative operands.
7.4 Additive operators
The additive operators + and - group left-to-right.
7.4.1 expression + expression
The result is the sum of the expressions. If both operands are
int or char, the result is int. If both are float or double, the
result is double. If one is char or int and one is float or
double, the former is converted to double and the result is
double. If an int or char is added to a pointer, the former is
converted by multiplying it by the length of the object to which
the pointer points and the result is a pointer of the same type
as the original pointer. Thus if P is a pointer to an object,
the expression ``P+1'' is a pointer to another object of the same
type as the first and immediately following it in storage.
No other type combinations are allowed.
7.4.2 expression - expression
The result is the difference of the operands. If both operands
are int, char, float, or double, the same type considerations as
for + apply. If an int or char is subtracted from a pointer, the
former is converted in the same way as explained under + above.
If two pointers to objects of the same type are subtracted, the
result is converted (by division by the length of the object) to
an int representing the number of objects separating the
pointed-to objects. This conversion will in general give
_________________________
1
The UNIX C compiler allows this expression anywhere that a
constant is required.
C Reference Manual - 11
unexpected results unless the pointers point to objects in the
same array, since pointers, even to objects of the same type, do
not necessarily differ by a multiple of the object-length.
7.5 Shift operators
The shift operators << and >> group left-to-right.
7.5.1 expression << expression
7.5.2 expression >> expression
Both operands must be int or char, and the result is int. The
second operand should be non-negative. The value of ``E1<<E2''
is E1 (interpreted as a bit pattern) left-shifted E2 bits;
vacated bits are 0-filled. The value of ``E1>>E2'' is E1
(interpreted as a bit pattern) logically right-shifted E2 bit
1
positions. Vacated bits are filled by 0 bits.
7.6 Relational operators
The relational operators group left-to-right, but this fact is
not very useful; ``a<b<c'' does not mean what it seems.
7.6.1 expression < expression
7.6.2 expression > expression
7.6.3 expression <= expression
7.6.4 expression >= expression
The operators < (less than), > (greater than), <= (less than or
equal to) and >= (greater than or equal to) all yield 0 if the
specified relation is false and 1 if it is true. For non-pointer
operands, operand conversion is exactly the same as for the +
operator. In addition, pointers of any kind can to be compared.
The result in this case depends on the relative locations in
2
storage of the pointed-to objects.
7.7 Equality operators
7.7.1 expression == expression
7.7.2 expression != expression
The == (equal to) and the != (not equal to) operators are
exactly analogous to the relational operators except for their
lower precedence. (Thus ``a<b == c<d'' is 1 whenever a<b and c<d
have the same truth-value). In addition, pointers may be tested
3
for equality or inequality with zero.
_________________________
1
On UNIX, arithmetic shifting is used, where the vacated bits
are filled with a copy of the sign bit.
2
The UNIX C compiler also allows pointers to be compared to
ints and chars; however, the int or char is first multiplied by
the length of the pointed-to object.
3
As with the relational operators, the UNIX C compiler allows
comparison between pointers and arbitrary integers and
characters.
C Reference Manual - 12
7.8 expression & expression
The & operator groups left-to-right. Both operands must be int
or char; the result is an int which is the bit-wise logical and
function of the operands.
7.9 Inclusive and exclusive OR
7.9.1 expression | expression
7.9.2 expression ^ expression
The | and ^ operators group left-to-right. The operands must
be int or char; the result is an int which is the bit-wise
inclusive (|) or exclusive (^) or function of its operands.
7.10 expression && expression
The && operator returns 1 if both its operands are non-zero, 0
otherwise. Unlike &, && guarantees left-to-right evaluation;
moreover the second operand is not evaluated if the first operand
is 0. The allowable expressions are those allowed by the if
statement (section 9.3).
7.11 expression || expression
The || operator returns 1 if either of its operands is
non-zero, and 0 otherwise. Unlike |, || guarantees left-to-right
evaluation; moreover, the second operand is not evaluated if the
value of the first operand is non-zero. The allowable
expressions are those allowed by the if statement (section 9.3).
7.12 expression ? expression : expression
Conditional expressions group left-to-right. The first
expression is evaluated (as by the if statement), and if it is
non-zero, the result is the value of the second expression,
otherwise that of third expression. If the types of the second
and third operand are the same, the result has their common type;
otherwise the same conversion rules as for + apply. Only one of
the second and third expressions is evaluated.
7.13 Assignment operators
There are a number of assignment operators, all of which group
right-to-left. All require an lvalue as their left operand, and
the type of an assignment expression is that of its left operand.
The value is the value stored in the left operand after the
assignment has taken place.
7.13.1 lvalue = expression
The value of the expression replaces that of the object
referred to by the lvalue. The operands need not have the same
type, but both must be int, char, float, double, or pointer. The
expression on the right is converted to the type of the lvalue if
necessary. The conversion from a pointer type to int is simply
to copy the value; thus, it is required that ints be of
sufficient length to hold any legitimate pointer value. The
conversion from int to pointer is defined so that the expression
"p = i = p" (where p is a pointer and i is an int) leaves p with
the same pointer value. The reverse, "i = p = i," is not
C Reference Manual - 13
1
guaranteed to preserve the integer value of i. Some integers
and pointers may convert to pointers which will cause addressing
exceptions when used.
7.13.2 lvalue += expression
lvalue =+ expression
7.13.3 lvalue -= expression
lvalue =- expression
7.13.4 lvalue *= expression
lvalue =* expression
7.13.5 lvalue /= expression
lvalue =/ expression
7.13.6 lvalue %= expression
lvalue =% expression
7.13.7 lvalue >>= expression
lvalue =>> expression
7.13.8 lvalue <<= expression
lvalue =<< expression
7.13.9 lvalue &= expression
lvalue =& expression
7.13.10 lvalue ^= expression
lvalue =^ expression
7.13.11 lvalue |= expression
lvalue =| expression
The behavior of an expression of the form ``E1 op= E2'' or
``E1 =op E2'' may be inferred by taking it as equivalent to
``E1 = E1 op E2''; however, E1 is evaluated only once.
Moreover, expressions like ``i += p'' in which a pointer is
added to an integer, are forbidden. The "op=" form is preferred
over the "=op" form, because it eliminates ambiguities possible
in expressions such as ``x=-1''.
7.14 expression , expression
A pair of expressions separated by a comma is evaluated
left-to-right and the value of the left expression is discarded.
The type and value of the result are the type and value of the
right operand. This operator groups left-to-right. It should be
avoided in situations where comma is given a special meaning, for
example in actual arguments to function calls (section 7.1.6) and
lists of initializers (section 10.2).
8. Declarations
Declarations are used within function definitions to specify
the interpretation which C gives to each identifier; they do not
necessarily reserve storage associated with the identifier.
Declarations have the forms
_________________________
1
On UNIX, no conversion is necessary among different pointer
types and integers. Thus, the value of i in this example would
be preserved.
C Reference Manual - 14
declaration:
decl-specifiers init-declarator-list ;
type-specifier ;
The declarators in the init-declarator-list contain the
identifiers being declared. The decl-specifiers consist of at
most one type-specifier and at most one storage class specifier.
decl-specifiers:
type-specifier
sc-specifier
type-specifier sc-specifier
sc-specifier type-specifier
The second form of declaration is used to define structures
(section 8.5).
8.1 Storage class specifiers
The sc-specifiers are:
sc-specifier:
auto
static
extern
register
The auto, static, and register declarations also serve as
definitions in that they cause an appropriate amount of storage
to be reserved. In the extern case there must be an external
definition (see below) for the given identifiers somewhere
outside the function in which they are declared.
Identifiers declared to be of class register may not be used as
the operand of the address-of operator &. In addition, each
implementation will have its own restrictions on the number and
types of register identifiers which can be supported in any
function. When these restrictions are violated, the offending
1
identifiers are treated as auto.
If the sc-specifier is missing from a declaration, it is
generally taken to be auto.
8.2 Type specifiers
The type-specifiers are
_________________________
1
The portable C compiler treats register as synonymous with
auto.
C Reference Manual - 15
type-specifier:
int
char
float
double
long
long int
short
short int
unsigned
unsigned int
long float
struct { type-decl-list }
struct identifier { type-decl-list }
struct identifier
The struct specifier is discussed in section 8.5. If the
type-specifier is missing from a declaration, it is generally
1
taken to be int.
8.3 Declarators
The init-declarator-list appearing in a declaration is a
comma-separated sequence of declarators, each of which may be
followed by an initializer for the declarator (initialization is
discussed in section 10.3).
init-declarator-list:
init-declarator
init-declarator , init-declarator-list
init-declarator:
declarator initializer
opt
The specifiers in the declaration indicate the type and storage
class of the objects to which the declarators refer. Declarators
have the syntax:
declarator:
identifier
* declarator
declarator ( )
declarator [ constant-expression ]
opt
( declarator )
The grouping in this definition is the same as in expressions.
_________________________
1
The UNIX C compiler implements a facility whereby identifiers
can be equated to types. Such identifiers can be used as
type-specifiers. The portable C compiler only partially
implements this facility.
C Reference Manual - 16
8.4 Meaning of declarators
Each declarator is taken to be an assertion that when a
construction of the same form as the declarator appears in an
expression, it yields an object of the indicated type and storage
class. Each declarator contains exactly one identifier; it is
this identifier that is declared.
If an unadorned identifier appears as a declarator, then it has
the type indicated by the specifier heading the declaration.
If a declarator has the form
* D
for D a declarator, then the contained identifier has the type
``. . . pointer to X'', where `` . . . X'' is the type which the
identifier would have had if the declarator had been simply D.
If a declarator has the form
D ( )
then the contained identifier has the type ``. . . function
returning X'', where `` . . . X'' is the type which the
identifier would have had if the declarator had been simply D.
A declarator may have the form
D[constant-expression]
or
D[ ]
In the first case the constant expression is an expression whose
value is determinable at compile time, and whose type is int. in
the second the constant 1 is used. (Constant expressions are
defined precisely in section 15.) Such a declarator makes the
contained identifier have type ``. . . array of X'', where
`` . . . X'' is the type which the identifier would have had if
the declarator had been simply D. The constant specifies the
number of elements in the array.
An array may be constructed from one of the basic types, from a
pointer, from a structure, or from another array (to generate a
multi-dimensional array).
Finally, parentheses in declarators do not alter the type of
the contained identifier except insofar as they alter the binding
of the components of the declarator.
Not all the possibilities allowed by the syntax above are
actually permitted. The restrictions are as follows: functions
may not return arrays, structures or functions, although they may
return pointers to such things; there are no arrays of functions,
although there may be arrays of pointers to functions. Likewise
a structure may not contain a function, but it may contain a
pointer to a function.
As an example, the declaration
int i, *ip, f(), *fip(), (*pfi)();
declares an integer i, a pointer ip to an integer, a function f
returning an integer, a function fip returning a pointer to an
C Reference Manual - 17
integer, and a pointer pfi to a function which returns an
integer. Also
float fa[17], *afp[17];
declares an array of float numbers and an array of pointers to
float numbers. Finally,
static int x3d[3][5][7];
declares a static three-dimensional array of integers, with rank
3x5x7. In complete detail, x3d is an array of three items: each
item is an array of five arrays; each of the latter arrays is an
array of seven integers. Any of the expressions ``x3d'',
``x3d [ i ]'', ``x3d [ i ] [ j ]'', ``x3d [ i ] [ j ] [ k ]'' may
reasonably appear in an expression. The first three have type
``array'', the last has type int.
8.5 Structure declarations
Recall that one of the forms for a structure specifier is
struct { type-decl-list }
The type-decl-list is a sequence of type declarations for the
members of the structure:
type-decl-list:
type-declaration
type-declaration type-decl-list
A type declaration is just a declaration which does not mention a
storage class (the storage class ``member of structure'' here
being understood by context) or include an initializer.
type-declaration:
type-specifier declarator-list ;
Within the structure, the objects declared have addresses which
increase as their declarations are read left-to-right. Each
component of a structure begins on an addressing boundary
appropriate to its type. Therefore, there may be unnamed holes
1
in a structure.
Another form of structure specifier is
struct identifier { type-decl-list }
This form is the same as the one just discussed, except that the
identifier is remembered as the structure tag of the structure
_________________________
1
The UNIX C compiler forces all structures to have an even
length in bytes and be aligned on word boundaries.
C Reference Manual - 18
specified by the list. A declaration may then be given using the
structure tag but without the list, as in the third form of
structure specifier:
struct identifier
Structure tags allow definition of self-referential and
mutually-recursive structures (forward references to structure
type names must be within the same group of definitions and be a
pointed-to or returned type); they also permit the long part of
the declaration to be given once and used several times. It is
however absurd to declare a structure which contains an instance
of itself, as distinct from a pointer to an instance of itself.
A simple example of a structure declaration, taken from section
16.2 where its use is illustrated more fully, is
struct tnode {
char tword[20];
int count;
struct tnode *left;
struct tnode *right;
};
which contains an array of 20 characters, an integer, and two
pointers to similar structures. Once this declaration has been
given, the following declaration makes sense:
struct tnode s, *sp;
which declares s to be a structure of the given sort and sp to be
a pointer to a structure of the given sort.
The names of structure members and structure tags may be the
same as ordinary variables, since a distinction can be made by
context. All of the members of a structure must have unique
names. However, a single member name may be used in many