Research V6 release
[unix-history] / usr / doc / ctut / ct8
CommitLineData
b3f974bf
BK
1.NH
2Bit Operators
3.PP
4C has several operators for logical bit-operations.
5For example,
6.E1
7x = x & 0177;
8.E2
9forms the bit-wise
10.UC AND
11of
12.UL x
13and 0177,
14effectively retaining only the last seven bits of
15.UL x\*.
16Other operators are
17.E1
18.ft R
19\(or inclusive OR
20^ (circumflex) exclusive OR
21.tr+~
22+ (tilde) 1's complement
23.tr++
24! logical NOT
25<< left shift (as in x<<2)
26>> right shift (arithmetic on PDP\(hy11; logical on H6070, IBM360)
27.E2
28.NH
29Assignment Operators
30.PP
31An unusual feature of C
32is that the normal binary operators like
33`+', `\(mi', etc.
34can be combined with the assignment operator `='
35to form new assignment operators.
36For example,
37.E1
38x =- 10;
39.E2
40uses the assignment operator `=\(mi' to decrement
41.UL x
42by 10,
43and
44.E1
45x =& 0177
46.E2
47forms the
48.UC AND
49of
50.UL x
51and 0177.
52This convention is a useful notational shortcut,
53particularly if
54.UL x
55is a complicated expression.
56The classic example is summing an array:
57.E1
58for( sum=i=0; i<n; i\*+ )
59 sum =+ array[i];
60.E2
61But the spaces around the operator are critical!
62For instance,
63.E1
64x = -10;
65.E2
66sets
67.UL x
68to
69\(mi10, while
70.E1
71x =- 10;
72.E2
73subtracts 10 from
74.UL x\*.
75When no space is present,
76.E1
77x=-10;
78.E2
79also decreases
80.UL x
81by 10.
82This is quite contrary to the experience of most programmers.
83In particular, watch out for things like
84.E1
85c=\**s\*+;
86y=&x[0];
87.E2
88both of which are almost certainly not what you wanted.
89Newer versions of various compilers are courteous enough to warn you about the ambiguity.
90.PP
91Because all other operators in an expression are evaluated
92before the assignment operator,
93the order of evaluation should be watched carefully:
94.E1
95x = x<<y | z;
96.E2
97means
98``shift
99.UL x
100left
101.UL y
102places,
103then
104.UC OR
105with
106.UL z,
107and store in
108.UL x\*.''
109But
110.E1
111x =<< y | z;
112.E2
113means
114``shift
115.UL x
116left by
117.UL y|z
118places'',
119which is rather different.
120.NH
121Floating Point
122.PP
123We've skipped over floating point so far,
124and the treatment here will be hasty.
125C has single and double precision numbers
126(where the precision depends on the machine at hand).
127For example,
128.E1
129 double sum;
130 float avg, y[10];
131 sum = 0\*.0;
132 for( i=0; i<n; i\*+ )
133 sum =+ y[i];
134 avg = sum/n;
135.E2
136forms the sum and average of the array
137.UL y\*.
138.PP
139All floating arithmetic is done in double precision.
140Mixed mode arithmetic is legal;
141if an arithmetic operator in an expression
142has both operands
143.UL int
144or
145.UL char,
146the arithmetic done is integer, but
147if one operand is
148.UL int
149or
150.UL char
151and the other is
152.UL float
153or
154.UL double,
155both operands are converted to
156.UL double\*.
157Thus if
158.UL i
159and
160.UL j
161are
162.UL int
163and
164.UL x
165is
166.UL float,
167.E1
168(x+i)/j converts i and j to float
169x + i/j does i/j integer, then converts
170.E2
171Type conversion
172may be made by assignment;
173for instance,
174.E1
175 int m, n;
176 float x, y;
177 m = x;
178 y = n;
179.E2
180converts
181.UL x
182to integer
183(truncating toward zero),
184and
185.UL n
186to floating point.
187.PP
188Floating constants are just like those in Fortran or PL/I,
189except that the exponent letter is `e' instead of `E'.
190Thus:
191.E1
192 pi = 3\*.14159;
193 large = 1\*.23456789e10;
194.E2
195.PP
196.UL printf
197will format floating point numbers:
198.UL ``%w\*.df''
199in the format string will print the corresponding variable
200in a field
201.UL w
202digits wide, with
203.UL d
204decimal places.
205An
206.UL e
207instead of an
208.UL f
209will produce exponential notation.
210.NH
211Horrors! goto's and labels
212.PP
213C has
214a
215.UL goto
216statement and labels, so you can branch about
217the way you used to.
218But most of the time
219.UL goto's
220aren't needed.
221(How many have we used up to this point?)
222The code can almost always be more clearly expressed by
223.UL for/while,
224.UL if/else,
225and compound statements.
226.PP
227One use of
228.UL goto's
229with some legitimacy is in a program
230which
231contains a long loop,
232where a
233.UL while(1)
234would be too extended.
235Then you might write
236.E1
237 mainloop:
238 \*.\*.\*.
239 goto mainloop;
240.E2
241Another use is to implement a
242.UL break
243out of more than one level of
244.UL for
245or
246.UL while\*.
247.UL goto's
248can only branch to labels within the same function.
249.NH
250Acknowledgements
251.PP
252I am indebted to a veritable host of readers who made
253valuable criticisms on several drafts of this tutorial.
254They ranged in experience from complete beginners
255through several implementors of C compilers
256to the C language designer himself.
257Needless to say, this is a wide enough spectrum of opinion
258that no one is satisfied (including me);
259comments and suggestions are still welcome,
260so that some future version might be improved.