* remove "\r" nonsense
[mascara-docs.git] / C / the.ansi.c.programming.language / c.programming.notes / sx3c.html
blob93d38aa4dc604beaa12aabe29aee555bb0b0b70b
1 <!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
2 <!-- This collection of hypertext pages is Copyright 1995, 1996 by Steve Summit. -->
3 <!-- This material may be freely redistributed and used -->
4 <!-- but may not be republished or sold without permission. -->
5 <html>
6 <head>
7 <link rev="owner" href="mailto:scs@eskimo.com">
8 <link rev="made" href="mailto:scs@eskimo.com">
9 <title>3.3 Boolean Expressions</title>
10 <link href="sx3b.html" rev=precedes>
11 <link href="sx3d.html" rel=precedes>
12 <link href="sx3.html" rev=subdocument>
13 </head>
14 <body>
15 <H2>3.3 Boolean Expressions</H2>
17 <p>An <TT>if</TT> statement like
18 <pre>
19 if(x &gt; max)
20 max = x;
21 </pre>
22 is perhaps deceptively simple.
23 Conceptually, we say that it checks whether the condition
24 <TT>x &gt; max</TT> is ``true'' or ``false''.
25 The mechanics underlying C's conception of ``true''
26 and ``false,'' however, deserve some explanation.
27 We need to understand how true and false values are represented,
28 and how they are interpreted by statements like <TT>if</TT>.
29 </p><p>As far as C is concerned,
30 a true/false condition can be represented as an integer.
31 (An integer can represent many values;
32 here we care about only two values:
33 ``true'' and ``false.''
34 The study of mathematics involving only two values is called
35 Boolean algebra, after George Boole, a mathematician who
36 refined this study.)
37 In C, ``false'' is represented by a value of 0 (zero),
38 and ``true'' is represented by any value that is nonzero.
39 Since there are many nonzero values (at least 65,534, for
40 values of type <TT>int</TT>),
41 when we have to pick a specific value for ``true,''
42 we'll pick 1.
43 </p><p>The <dfn>relational operators</dfn> such as
44 <TT>&lt;</TT>, <TT>&lt;=</TT>, <TT>&gt;</TT>, and <TT>&gt;=</TT>
45 are in fact operators, just like <TT>+</TT>, <TT>-</TT>, <TT>*</TT>,
46 and <TT>/</TT>.
47 The relational operators take two values, look at them, and
48 ``return'' a value of 1 or 0 depending on whether the
49 tested relation was true or false.
50 The complete set of relational operators in C is:
51 <br>
52 <br>
53 <pre>
54 <TT>&lt;</TT> less than
55 <TT>&lt;=</TT> less than or equal
56 <TT>&gt;</TT> greater than
57 <TT>&gt;=</TT> greater than or equal
58 <TT>==</TT> equal
59 <TT>!=</TT> not equal
60 </pre>
61 <br>
62 <br>
63 For example,
64 <TT>1 &lt; 2</TT> is 1,
65 <TT>3 &gt; 4</TT> is 0,
66 <TT>5 == 5</TT> is 1,
67 and
68 <TT>6 != 6</TT> is 0.
69 </p><p>We've now encountered perhaps the most easy-to-stumble-on
70 ``gotcha!'' in C:
71 the equality-testing operator is <TT>==</TT>,
72 not a single <TT>=</TT>, which is assignment.
73 If you accidentally write
74 <pre>
75 if(a = 0)
76 </pre>
77 (and you probably will at some point;
78 everybody
79 makes this mistake),
80 it will <em>not</em> test whether <TT>a</TT> is zero,
81 as you probably intended.
82 Instead, it will <em>assign</em> 0 to <TT>a</TT>,
83 and then perform the ``true'' branch
84 of the <TT>if</TT> statement if <TT>a</TT> is <em>non</em>zero.
85 But <TT>a</TT> will have just been assigned the value 0,
86 so the ``true'' branch will never be taken!
87 (This could drive you crazy while debugging--you
88 wanted to do something if <TT>a</TT> was 0,
89 and after the test, <TT>a</TT> <em>is</em> 0,
90 whether it was supposed to be or not,
91 but the ``true'' branch is nevertheless not taken.)
92 </p><p>The relational operators work with arbitrary numbers
93 and generate true/false values.
94 You can
95 also
96 combine true/false values by using the
97 <dfn>Boolean operators</dfn>,
98 which take true/false values as operands
99 and compute new true/false values.
100 The three Boolean operators are:
101 <br>
102 <br>
103 <pre>
104 <TT>&amp;&amp;</TT> and
105 <TT>||</TT> or
106 <TT>!</TT> not (takes one operand; ``<dfn>unary</dfn>'')
107 </pre>
108 <br>
109 <br>
110 The <TT>&amp;&amp;</TT> (``and'') operator
111 takes two true/false values
112 and produces a true (1) result if both operands are true
113 (that is, if the left-hand side is true <B>and</B>
114 the right-hand side is true).
115 The <TT>||</TT> (``or'') operator
116 takes two true/false values
117 and produces a true (1) result if either operand is true.
118 The <TT>!</TT> (``not'') operator
119 takes a single true/false value and negates it,
120 turning false to true and true to false
121 (0 to 1 and nonzero to 0).
122 </p><p>For example, to test whether the variable <TT>i</TT> lies
123 between 1 and 10, you might use
124 <pre>
125 if(1 &lt; i &amp;&amp; i &lt; 10)
127 </pre>
128 Here we're expressing the
129 relation
131 ``<TT>i</TT> is between 1 and 10''
133 ``1 is less than <TT>i</TT> <B>and</B>
134 <TT>i</TT> is less than 10.''
135 </p><p>It's important to understand why the more obvious
136 expression
138 <pre>
139 if(1 &lt; i &lt; 10) /* WRONG */
140 </pre>
141 would not work.
142 The expression
143 <TT>1 &lt; i &lt; 10</TT>
144 is parsed by the compiler analogously to
145 <TT>1 + i + 10</TT>.
146 The expression <TT>1 + i + 10</TT>
147 is parsed as <TT>(1 + i) + 10</TT>
149 means ``add 1 to <TT>i</TT>, and then add the result to 10.''
150 Similarly,
151 the expression
152 <TT>1 &lt; i &lt; 10</TT>
153 is parsed as <TT>(1 &lt; i) &lt; 10</TT>
155 means ``see if 1 is less than <TT>i</TT>,
156 and then see if the result is less than 10.''
157 But in this case, ``the result'' is 1 or 0, depending
158 on whether <TT>i</TT> is greater than 1.
159 Since both 0 and 1 are less than 10, the expression
160 <TT>1 &lt; i &lt; 10</TT>
161 would <em>always</em> be true in C,
162 regardless of the value of <TT>i</TT>!
163 </p><p>Relational and Boolean expressions are usually used
164 in contexts such as an <TT>if</TT> statement, where something is
165 to be done or not done depending on some condition.
166 In these cases
167 what's actually checked is whether the expression representing
168 the condition has a zero or nonzero value.
169 As long as the expression is a relational or Boolean expression,
170 the interpretation is just what we want.
171 For example,
172 when we wrote
173 <pre>
174 if(x &gt; max)
175 </pre>
176 the <TT>&gt;</TT> operator produced a 1
177 if <TT>x</TT> was greater than <TT>max</TT>,
178 and a 0 otherwise.
179 The <TT>if</TT> statement interprets 0 as false and 1
180 (or any nonzero value)
181 as true.
182 </p><p>But what if the expression is not a relational or Boolean expression?
183 As far as C is concerned,
184 the controlling expression
185 (of conditional statements like <TT>if</TT>)
187 in fact
188 be <em>any</em> expression:
189 it doesn't have to ``look like'' a Boolean expression;
190 it doesn't have to contain relational or logical operators.
191 All C looks at
192 (when it's evaluating an <TT>if</TT> statement,
193 or anywhere else where it needs a true/false value)
194 is whether the expression evaluates to 0 or nonzero.
195 For example,
196 if you have
197 a variable <TT>x</TT>,
198 and you want to do something if <TT>x</TT> is nonzero,
199 it's possible to write
200 <pre>
201 if(x)
202 <I>statement</I>
203 </pre>
204 and the statement will be executed if <TT>x</TT> is nonzero
205 (since nonzero means ``true'').
206 </p><p>This possibility
207 (that the controlling expression of an <TT>if</TT> statement
208 doesn't have to ``look like'' a Boolean expression)
209 is both useful and potentially confusing.
210 It's useful when you have a variable or a function that is
211 ``conceptually Boolean,''
212 that is,
214 that you consider to hold
215 a true or false (actually nonzero or zero) value.
216 For example, if you have a variable <TT>verbose</TT>
217 which contains a nonzero value when your program should run in
218 verbose mode and zero when it should be quiet,
219 you can write things like
220 <pre>
221 if(verbose)
222 printf("Starting first pass\n");
223 </pre>
224 and this code is both legal and readable,
225 besides which it does what you want.
227 The standard library contains a function <TT>isupper()</TT>
228 which tests whether a character is an upper-case letter,
229 so if <TT>c</TT> is a character,
230 you might write
231 <pre>
232 if(isupper(c))
234 </pre>
235 Both of these examples (<TT>verbose</TT> and <TT>isupper()</TT>)
236 are useful and readable.
237 </p><p>However, you will eventually come across code like
238 <pre>
239 if(n)
240 average = sum / n;
241 </pre>
242 where <TT>n</TT> is just a number.
243 Here, the programmer wants to compute the average only if
244 <TT>n</TT> is nonzero
245 (otherwise, of course, the code would divide by 0),
246 and the code works,
247 because, in the context of the <TT>if</TT> statement,
248 the trivial expression <TT>n</TT> is
249 (as always)
250 interpreted as ``true'' if it is nonzero,
251 and ``false'' if it is zero.
252 </p><p>``Coding shortcuts''
253 like these
255 seem cryptic,
256 but they're also quite common,
257 so you'll need to be able to recognize them
258 even if you don't choose to write them in your own code.
259 Whenever you see code like
260 <pre>
261 if(x)
262 </pre>
264 <pre>
265 if(f())
266 </pre>
267 where <TT>x</TT> or <TT>f()</TT>
268 do not have obvious ``Boolean'' names,
269 you can read them as ``if <TT>x</TT> is nonzero''
271 ``if <TT>f()</TT> returns nonzero.''
272 </p><hr>
274 Read sequentially:
275 <a href="sx3b.html" rev=precedes>prev</a>
276 <a href="sx3d.html" rel=precedes>next</a>
277 <a href="sx3.html" rev=subdocument>up</a>
278 <a href="top.html">top</a>
279 </p>
281 This page by <a href="http://www.eskimo.com/~scs/">Steve Summit</a>
282 // <a href="copyright.html">Copyright</a> 1995, 1996
283 // <a href="mailto:scs@eskimo.com">mail feedback</a>
284 </p>
285 </body>
286 </html>