-
Notifications
You must be signed in to change notification settings - Fork 0
/
expressions.texi
1550 lines (1254 loc) · 45.3 KB
/
expressions.texi
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 ??? It might be a good idea to turn each example of an expression
@c into a small program that prints output and thus shows what
@c the expression does.
@c This is part of The GNU C Reference Manual
@c Copyright (C) 2007-2011 Free Software Foundation, Inc.
@c See the file gnu-c-manual.texi for copying conditions.
@node Expressions and Operators
@chapter Expressions and Operators
@menu
* Expressions::
* Assignment Operators::
* Incrementing and Decrementing::
* Arithmetic Operators::
* Complex Conjugation::
* Comparison Operators::
* Logical Operators::
* Bit Shifting::
* Bitwise Logical Operators::
* Pointer Operators::
* The sizeof Operator::
* Type Casts::
* Array Subscripts::
* Function Calls as Expressions::
* The Comma Operator::
* Member Access Expressions::
* Conditional Expressions::
* Statements and Declarations in Expressions::
* Operator Precedence::
* Order of Evaluation::
* Overflow::
@end menu
@node Expressions
@section Expressions
@cindex expressions
An @dfn{expression} consists of at least one operand and zero or more
operators. Operands typed objects such as constants, variables, and
function calls that return values. Here are some examples:
@example
@group
47
2 + 2
cosine(3.14159) /* @r{We presume this returns a floating point value.} */
@end group
@end example
Parentheses group subexpressions:
@example
( 2 * ( ( 3 + 10 ) - ( 2 * 6 ) ) )
@end example
@noindent
Innermost expressions are evaluated first. In the above example,
@code{3 + 10} and @code{2 * 6} evaluate to @code{13} and @code{12},
respectively. Then @code{12} is subtracted
from @code{13}, resulting in @code{1}. Finally, @code{1} is multiplied by
@code{2}, resulting in @code{2}. The outermost parentheses are completely
optional.
@cindex operators
An @dfn{operator} specifies an operation to be performed on its operand(s).
Operators may have one, two, or three operands, depending on the operator.
@node Assignment Operators
@section Assignment Operators
@cindex assignment operators
@cindex operators, assignment
Assignment operators store values in variables. C provides several
variations of assignment operators.
The standard assignment operator @code{=} simply stores the value of its
right operand in the variable specified by its left operand. As with
all assignment operators, the left operand (commonly referred to as the
``lvalue'') cannot be a literal or constant value.
@example
@group
int x = 10;
float y = 45.12 + 2.0;
int z = (2 * (3 + function () ));
struct foo @{
int bar;
int baz;
@} quux = @{3, 4, 5@};
@end group
@end example
@noindent
Note that, unlike the other assignment operators described below, you
can use the plain assignment operator to store values of a structure
type.
Compound assignment operators perform an operation involving
both the left and right operands, and then assign the resulting
expression to the left operand. Here is a list of the compound
assignment operators, and a brief description of what they do:
@itemize
@item
@code{+=}
Adds the two operands together, and then assign the result of
the addition to the left operand.
@item
@code{-=}
Subtract the right operand from the left operand, and
then assign the result of the subtraction to the left operand.
@item
@code{*=}
Multiply the two operands together, and then assign the
result of the multiplication to the left operand.
@item
@code{/=}
Divide the left operand by the right operand, and assign
the result of the division to the left operand.
@item
@code{%=}
Perform modular division on the two operands, and assign the
result of the division to the left operand.
@item
@code{<<=}
Perform a left shift operation on the left operand, shifting
by the number of bits specified by the right operand, and assign the
result of the shift to the left operand.
@item
@code{>>=}
Perform a right shift operation on the left operand,
shifting by the number of bits specified by the right operand, and assign
the result of the shift to the left operand.
@item
@code{&=}
Perform a bitwise conjunction operation on the two operands, and
assign the result of the operation to the left operand.
@item
@code{^=}
Performs a bitwise exclusive disjunction operation on the two operands,
and assign the result of the operation to the left operand.
@item
@code{|=}
Performs a bitwise inclusive disjunction operation on the two
operands, and assign the result of the operation to the left operand.
@end itemize
@comment __End of compound assignment operator list
Here is an example of using one of the compound assignment operators:
@example
x += y;
@end example
@noindent
Since there are no side effects wrought by evaluating the variable
@code{x} asn an lvalue, the above code produces the same result as:
@example
x = x + y;
@end example
@c GNU C Extension -- temporarily commented out for manual 0.1
@c @node Generalized Lvalues
@c @subsubsection Generalized Lvalues
@c @cindex compound expressions as lvalues
@c @cindex expressions, compound, as lvalues
@c @cindex conditional expressions as lvalues
@c index expressions, conditional, as lvalues
@c @cindex casts as lvalues
@c @cindex generalized lvalues
@c @cindex lvalues, generalized
@c @cindex extensions, @code{?:}
@c @cindex @code{?:} extensions
@c
@c Compound expressions, conditional expressions and casts are allowed as
@c lvalues provided their operands are lvalues. This means that you can take
@c their addresses or store values into them.
@c
@c For example, you can assign a value to a compound expression, provided the
@c last expression in the sequence is an lvalue. These two expressions are
@c equivalent:
@c
@c @example
@c (a, b) += 5
@c a, (b += 5)
@c @end example
@c
@c Similarly, you can take the address of a compound expression. So, these two
@c expressions are equivalent:
@c
@c @example
@c &(a, b)
@c a, &b
@c @end example
@c
@c A conditional expression is a valid lvalue if its type is not void and if
@c both the second and third operands are valid lvalues. For example, these two
@c expressions are equivalent:
@c
@c @example
@c (a ? b : c) = 5
@c (a ? b = 5 : (c = 5))
@c @end example
@c
@c A type cast is a valid lvalue if its operand is an lvalue. A simple
@c assignment whose left-hand side is a cast works by converting the
@c right-hand side first to the specified type, then to the type of the
@c inner left-hand side expression. After this is stored, the value is
@c converted back to the specified type to become the value of the
@c assignment. Thus, if @code{a} has type @code{char *}, the following two
@c expressions are equivalent:
@c
@c @example
@c (int)a = 5
@c (int)(a = (char *)(int)5)
@c @end example
@c
@c An assignment-with-arithmetic operation such as @code{+=} applied to a cast
@c performs the arithmetic using the type resulting from the cast, and then
@c continues as in the previous case. Therefore, these two expressions are
@c equivalent:
@c
@c @example
@c (int)a += 5
@c (int)(a = (char *)(int) ((int)a + 5))
@c @end example
@c You cannot take the address of an lvalue cast, because the use of its
@c address would not work out coherently. Suppose that @code{&(int)f} were
@c permitted, where @code{f} has type @code{float}. Then the following
@c statement would try to store an integer bit-pattern where a floating
@c point number belongs:
@c
@c @example
@c *&(int)f = 1;
@c @end example
@c
@c This is quite different from what @code{(int)f = 1} would do---that
@c would convert 1 to floating point and store it. Rather than cause this
@c inconsistency, we think it is better to prohibit use of @code{&} on a cast.
@c
@c If you really do want an @code{int *} pointer with the address of
@c @code{f}, you can simply write @code{(int *)&f}.
@node Incrementing and Decrementing
@section Incrementing and Decrementing
@cindex increment operator
@cindex decrement operator
@cindex operator, increment
@cindex operator, decrement
The increment operator @code{++} adds 1 to its operand. The operand must
be a either a variable of one of the primitive data types, a pointer, or an
enumeration variable. You can apply the increment operator either before or after
the operand. Here are some examples:
@example
@group
char w = '1';
int x = 5;
char y = 'B';
float z = 5.2;
int *p = &x;
x++; /* @r{@code{x} is now 6.} */
++y; /* @r{@code{y} is now `C' (on ASCII systems).} */
++w; /* @r{@code{y} is now the character `2' (not the value 2).} */
z++; /* @r{@code{z} is now 6.2.} */
++p; /* @r{@code{p} is now @code{&x} + @code{sizeof(int)}.} */
@end group
@end example
@noindent
(Note that incrementing a pointer only makes sense if you have reason to believe
that the new pointer value will be a valid memory address.)
A prefix increment adds 1 before the operand is evaluated. A postfix
increment adds 1 after the operand is evaluated. In the previous
examples, changing the position of the operator would make no difference.
However, there are cases where it does make a difference:
@example
@group
int x = 5;
printf ("%d \n", x++); /* @r{Print @code{x} and then increment it.} */
/* @r{@code{x} is now equal to 6.} */
printf ("%d \n", ++x); /* @r{Increment @code{x} and then print it.} */
@end group
@end example
@noindent
The output of the above example is:
@example
@group
5
7
@end group
@end example
Likewise, you can subtract 1 from an operand using the decrement operator:
@example
@group
int x = 5;
x--; /* @r{@code{x} is now 4.} */
@end group
@end example
@noindent
The concepts of prefix and postfix application apply here as with the
increment operator.
@node Arithmetic Operators
@section Arithmetic Operators
@cindex arithmetic operators
@cindex operators, arithmetic
C provides operators for standard arithmetic operations: addition, subtraction,
multiplication, and division, along with modular division and negation. Usage
of these operators is straightforward; here are some examples:
@example
@group
/* @r{Addition.} */
x = 5 + 3;
y = 10.23 + 37.332;
quux_pointer = foo_pointer + bar_pointer;
@end group
@end example
@example
@group
/* @r{Subtraction.} */
x = 5 - 3;
y = 57.223 - 10.903;
quux_pointer = foo_pointer - bar_pointer;
@end group
@end example
@noindent
You can add and subtract memory pointers, but you cannot multiply
or divide them.
@example
@group
/* @r{Multiplication.} */
x = 5 * 3;
y = 47.4 * 1.001;
@end group
@end example
@example
@group
/* @r{Division.} */
x = 5 / 3;
y = 940.0 / 20.2;
@end group
@end example
@noindent
Integer division of positive values truncates towards zero, so 5/3 is
1. However, if either operand is negative, the direction of rounding
is implementation-defined. @ref{Signed Integer Division} for
information about overflow in signed integer division.
@c We should state how GCC behaves if an operand is negative.
You use the modulus operator @code{%} to obtain the remainder produced
by dividing its two operands. You put the operands on either side of
the operator, and it does matter which operand goes on which
side: @code{3 % 5} and @code{5 % 3} do not have the same result.
The operands must be expressions of a primitive data type.
@example
@group
/* @r{Modular division.} */
x = 5 % 3;
y = 74 % 47;
@end group
@end example
@noindent
Modular division returns the remainder produced after performing
integer division on the two operands. The operands must be of a
primitive integer type.
@example
@group
/* @r{Negation.} */
int x = -5;
float y = -3.14159;
@end group
@end example
If the operand you use with the negative operator is of an unsigned data
type, then the result cannot negative, but rather is the
maximum value of the unsigned data type, minus the value of the operand.
Many systems use twos-complement arithmetic, and on such systems the
most negative value a signed type can hold is further away from zero
than the most positive value. For example, on one platform, this
program:
@example
@group
#include <limits.h>
#include <stdio.h>
int main (int argc, char *argv[])
@{
int x;
x = INT_MAX;
printf("INT_MAX = %d\n", x);
x = INT_MIN;
printf("INT_MIN = %d\n", x);
x = -x;
printf("-INT_MIN = %d\n", x);
return 0;
@}
@end group
@end example
Produces this output:
@example
@group
INT_MAX = 2147483647
INT_MIN = -2147483648
-INT_MIN = -2147483648
@end group
@end example
Trivially, you can also apply a positive operator to a numeric
expression:
@example
int x = +42;
@end example
@noindent
Numeric values are assumed to be positive unless explicitly made
negative, so this operator has no effect on program operation.
@node Complex Conjugation
@section Complex Conjugation
@cindex complex conjugation
@cindex conjugation
As a GNU extension, you can use the complex conjugation operator @code{~} to
perform complex conjugation on its operand --- that is, it reverses the sign of
its imaginary component. The operand must be an expression of a complex number
type. Here is an example:
@example
@group
__complex__ int x = 5 + 17i;
printf ("%d \n", (x * ~x));
@end group
@end example
Since an imaginary number @math{(a + bi)} multiplied by its conjugate is equal
to @math{a^2 + b^2}, the above @code{printf} statement will print 314, which
is equal to @math{25 + 289}.
@node Comparison Operators
@section Comparison Operators
@cindex comparison operators
@cindex operators, comparison
You use the comparison operators to determine how two operands relate to
each other: are they equal to each other, is one larger than the other,
is one smaller than the other, and so on. When you use any of the
comparison operators, the result is either 1 or 0, meaning true or false,
respectively.
(In the following code examples, the variables @code{x} and @code{y} stand
for any two expressions of arithmetic types, or pointers.)
The equal-to operator @code{==} tests its two operands for equality.
The result is 1 if the operands are equal, and 0 if the operands are not equal.
@example
@group
if (x == y)
puts (``x is equal to y'');
else
puts (``x is not equal to y'');
@end group
@end example
The not-equal-to operator @code{!=} tests its two operands for inequality.
The result is 1 if the operands are not equal, and 0 if the operands
@emph{are} equal.
@example
@group
if (x != y)
puts (``x is not equal to y'');
else
puts (``x is equal to y'');
@end group
@end example
Comparing floating-point values for exact equality or inequality can
produce unexpected results. @ref{Real Number Types} for more
information.
You can compare function pointers for equality or inequality; the
comparison tests if two function pointers point to the same function
or not.
Beyond equality and inequality, there are operators you can use to test
if one value is less than, greater than, less-than-or-equal-to, or
greater-than-or-equal-to another value. Here are some code samples that
exemplify usage of these operators:
@example
@group
if (x < y)
puts (``x is less than y'');
@end group
@end example
@example
@group
if (x <= y)
puts (``x is less than or equal to y'');
@end group
@end example
@example
@group
if (x > y)
puts (``x is greater than y'');
@end group
@end example
@example
@group
if (x >= y)
puts (``x is greater than or equal to y'');
@end group
@end example
@node Logical Operators
@section Logical Operators
@cindex logical operators
Logical operators test the truth value of a pair of operands. Any
nonzero expression is considered true in C, while an expression that
evaluates to zero is considered false.
The logical conjunction operator @code{&&} tests if two expressions
are both true. If the first expression is false, then the second
expression is not evaluated.
@example
@group
if ((x == 5) && (y == 10))
printf (``x is 5 and y is 10'');
@end group
@end example
The logical conjunction operator @code{||} tests if at least one of
two expressions it true. If the first expression is true, then the
second expression is not evaluated.
@example
@group
if ((x == 5) || (y == 10))
printf (``x is 5 or y is 10'');
@end group
@end example
You can prepend a logical expression with a negation operator
@code{!} to flip the truth value:
@example
@group
if (!(x == 5))
printf (``x is not 5'');
@end group
@end example
Since the second operand in a logical expression pair is not necessarily
evaluated, you can write code with perhaps unintuitive results:
@example
@group
if (foo && x++)
bar();
@end group
@end example
@noindent
If @code{foo} is ever zero, then not only would @code{bar} not be called,
but @code{x} would not be incremented. If you intend to increment @code{x}
regardless of the value of @code{foo}, you should do so outside of the
conjunction expression.
@node Bit Shifting
@section Bit Shifting
@cindex bit shifting
@cindex shifting
You use the left-shift operator @code{<<} to shift its first operand's bits
to the left. The second operand denotes the number of bit places to shift.
Bits shifted off the left side of the value are discarded; new bits added
on the right side will all be 0.
@example
@group
x = 47; /* @r{47 is 00101111 in binary.} */
x << 1; /* @r{00101111 << 1 is 01011110.} */
@end group
@end example
Similarly, you use the right-shift operator @code{>>} to shift its
first operand's bits to the right. Bits shifted off the right side are
discarded; new bits added on the left side are @emph{usually} 0, but
if the first operand is a signed negative value, then the added bits will
be either 0 @emph{or} whatever value was previously in the leftmost bit
position.
@example
@group
x = 47; /* @r{47 is 00101111 in binary.} */
x >> 1; /* @r{00101111 >> 1 is 00010111.} */
@end group
@end example
For both @code{<<} and @code{>>}, if the second operand is greater
than the bit-width of the first operand, or the second operand is
negative, the behavior is undefined.
You can use the shift operators to perform a variety of interesting
hacks. For example, given a date with the day of the month numbered
as @code{d}, the month numbered as @code{m}, and the year @code{y}, you
can store the entire date in a single number @code{x}:
@example
int d = 12;
int m = 6;
int y = 1983;
int x = ((y << 4) + m) << 5) + d;
@end example
@noindent
You can then extract the original day, month, and year out of @code{x}
using a combination of shift operators and modular division:
@example
d = x % 32;
m = (x >> 5) % 16;
y = x >> 9;
@end example
@node Bitwise Logical Operators
@section Bitwise Logical Operators
@cindex bitwise logical operators
@cindex logical operators, bitwise
C provides operators for performing bitwise conjunction, inclusive disjunction,
exclusive disjunction, and negation (complement).
Biwise conjunction examines each bit in its two operands, and when two
corresponding bits are both 1, the resulting bit is 1. All other resulting
bits are 0. Here is an example of how this works, using binary numbers:
@example
11001001 & 10011011 = 10001001
@end example
Bitwise inclusive disjunction examines each bit in its two operands,
and when two corresponding bits are both 0, the resulting bit is 0. All
other resulting bits are 1.
@example
11001001 | 10011011 = 11011011
@end example
Bitwise exclusive disjunction examines each bit in its two operands, and when
two corresponding bits are different, the resulting bit is 1. All other resulting
bits are 0.
@example
11001001 ^ 10011011 = 01010000
@end example
Bitwise negation reverses each bit in its operand:
@example
~11001001 = 00110110
@end example
In C, you can only use these operators with operands of an integer (or character)
type, and for maximum portability, you should only use the bitwise negation operator
with unsigned integer types. Here are some examples of using these operators in
C code:
@example
@group
unsigned int foo = 42;
unsigned int bar = 57;
unsigned int quux;
quux = foo & bar;
quux = foo | bar;
quux = foo ^ bar;
quux = ~foo;
@end group
@end example
@node Pointer Operators
@section Pointer Operators
@cindex pointer operators
You can use the address operator @code{&} to obtain the memory address of
an object.
@example
@group
int x = 5;
int *pointer_to_x = &x;
@end group
@end example
It is not necessary to use this operator to obtain the address of
a function, although you can:
@example
@group
extern int foo (void);
int (*fp1) (void) = foo; /* fp1 points to foo */
int (*fp2) (void) = &foo; /* fp1 also points to foo */
@end group
@end example
Function pointers and data pointers are not compatible, in the sense
that you cannot expect to store the address of a function into a data
pointer, and then copy that into a function pointer and call it
successfully. It might work on some systems, but it's not a portable
technique.
As a GNU extension to C89, you can also obtain the address of a label
with the label address operator @code{&&}. The result is a
@code{void*} pointer which can be used with @code{goto}. @xref{The
goto Statement}.
Given a memory address stored in a pointer, you can use the indirection
operator @code{*} to obtain the value stored at the address. (This is called
@dfn{dereferencing} the pointer.)
@example
@group
int x = 5;
int y;
int *ptr;
ptr = &x; /* @r{@code{ptr} now holds the address of @code{x}.} */
y = *ptr; /* @r{@code{y} gets the value stored at the address}
@r{stored in @code{ptr}.} */
@end group
@end example
@noindent
Avoid using dereferencing pointers that have not been initialized to
a known memory location.
@node The sizeof Operator
@section The sizeof Operator
@cindex sizeof operator
You can use the @code{sizeof} operator to obtain the size (in bytes)
of the data type of its operand. The operand may be an actual type
specifier (such as @code{int} or @code{float}), as well as any valid
expression. When the operand is a type name, it must be enclosed in
parentheses. Here are some examples:
@example
@group
size_t a = sizeof(int);
size_t b = sizeof(float);
size_t c = sizeof(5);
size_t d = sizeof(5.143);
size_t e = sizeof a;
@end group
@end example
The result of the @code{sizeof} operator is of a type called @code{size_t},
which is defined in the header file @code{<stddef.h>}. @code{size_t} is
an unsigned integer type, perhaps identical to @code{unsigned int} or
@code{unsigned long int}; it varies from system to system.
The @code{size_t} type is often a convenient type for a loop index,
since it is guaranteed to be able to hold the number of elements in
any array; this is not the case with @code{int}, for example.
The @code{sizeof} operator can be used to automatically compute the
number of elements in an array:
@example
@group
#include <stddef.h>
#include <stdio.h>
static const int values[] = @{ 1, 2, 48, 681 @};
#define ARRAYSIZE(x) (sizeof x/sizeof x[0])
int main (int argc, char *argv[])
@{
size_t i;
for (i = 0; i < ARRAYSIZE(values); i++)
@{
printf("%d\n", values[i]);
@}
return 0;
@}
@end group
@end example
There are two cases where this technique does not work. The first is
where the array element has zero size (GCC supports zero-sized
structures as a GNU extension). The second is where the array is in
fact a function parameter (@pxref{Function Parameters}).
@node Type Casts
@section Type Casts
@cindex type casts
@cindex casts
You can use a type cast to explicitly cause an expression to be of a specified
data type. A type cast consists of a type specifier enclosed in parentheses,
followed by an expression. To ensure proper casting, you should also enclose
the expression that follows the type specifier in parentheses. Here is
an example:
@example
@group
float x;
int y = 7;
int z = 3;
x = (float) (y / z);
@end group
@end example
In that example, since @code{y} and @code{z} are both integers, integer
division is performed, and even though @code{x} is a floating-point
variable, it receives the value 2. Explicitly casting the result
of the division to @code{float} does no good, because the computed
value of @code{y/z} is already 2.
To fix this problem, you need to convert one of the operands to a
floating-point type before the division takes place:
@example
@group
float x;
int y = 7;
int z = 3;
x = (y / (float)z);
@end group
@end example
@noindent Here, a floating-point value close to 2.333@dots{} is assigned to @code{x}.
Type casting only works with scalar types (that is, integer,
floating-point or pointer types). Therefore, this is not allowed:
@example
@group
struct fooTag @{ /* members ... */ @};
struct fooTag foo;
unsigned char byteArray[8];
foo = (struct fooType) byteArray; /* @r{Fail!} */
@end group
@end example
@node Array Subscripts
@section Array Subscripts
@cindex array subscripts
You can access array elements by specifying the name of the array, and the
array subscript (or index, or element number) enclosed in brackets. Here is
an example, supposing an integer array called @code{my_array}:
@example
@group
my_array[0] = 5;
@end group
@end example
The array subscript expression @code{A[i]} is defined as being
identical to the expression @code{(*((A)+(i)))}. This means that many
uses of an array name are equivalent to a pointer expression. It also
means that you cannot subscript an array having the @code{register}
storage class.
@node Function Calls as Expressions
@section Function Calls as Expressions
@cindex function calls, as expressions
A call to any function which returns a value is an expression.
@example
@group
int function(void);
@dots{}
a = 10 + function();
@end group
@end example
@node The Comma Operator
@section The Comma Operator
@cindex comma operator
You use the comma operator @code{,} to separate two (ostensibly related) expressions.
For instance, the first expression might produce a value that is used by the second
expression:
@c This works because there is a sequence point after the evaluation
@c of the left hand side.
@example
@group
x++, y = x * x;
@end group
@end example
More commonly, the comma operator is used in @code{for} statements, like
this:
@example
@group
/* @r{Using the comma operator in a @code{for} statement.} */
for (x = 1, y = 10; x <=10 && y >=1; x++, y--)
@{
@dots{}
@}
@end group
@end example
@noindent
This lets you conveniently set, monitor, and modify multiple control
expressions for the @code{for} statement.
A comma is also used to separate function parameters; however, this
is @emph{not} the comma operator in action. In fact, if the comma
operator is used as we have discussed here in a function call, then
the compiler will
interpret that as calling the function with an extra parameter.
If you want to use the comma operator in a function argument, you need
to put parentheses around it. That's because commas in a function
argument list have a different meaning: they separate arguments.
Thus,
@example
foo (x, y=47, x, z);
@end example
@noindent
is interpreted as a function call with four arguments, but