Copyright © Curt Hill The C++ IF Statement More important details More fun Part 3
Copyright © Curt Hill Boolean Variables Recall that bool is a reserved word It indicates a type that may only have two values: true, false –true and false are constant values Use whenever only two values are possible: bool ismanager, isfemale, ismember; Variables of type boolean often start with the word is, because it indicates type
Copyright © Curt Hill Comparisons Again Comparison operators are not boolean operators Recall that an integer operator like % takes two integers and produces an integer A comparison may compare two integers and produce a boolean A boolean operator does a logical operation on two booleans
Copyright © Curt Hill Boolean Operators Boolean operators are the AND, OR and NOT C operators: – && || ! The single & and | are bit string operators not booleans AND, OR, and NOT have the same meaning as is commonly used in English AND/OR have lower precedence than comparisons
Copyright © Curt Hill C Operator Truth Table PQP && QP || Q!P true false truefalse truefalse truefalsetrue false true
Copyright © Curt Hill Boolean Comparisons A sure sign of a novice is to compare a boolean with a truth value: bool b; if(b == true) // or if(b == false) // or if(b != true) A boolean is already suitable for comparison Use one of these two: if(b) // or if(!b)
Copyright © Curt Hill Comparing Real Values The whole issue of roundoff makes comparisons of real numbers problematic Consider the following: double d = 1.0, e = 10.0; double f = d/e; … if(f*10 == d) … This condition can never be true!
Copyright © Curt Hill Why not? Our normal understanding is that they should be equal and the comparison true We usually think algebraically, that is with infinite precision The decimal 0.1 is a repeating fraction in binary –It cannot be represented in a finite number of digits The comparison then becomes something like this: if(1 == )
However This kind of comparison is chancy but aided by the ways a Pentium does arithmetic It always uses one more digit of arithmetic The default mode is to then round that into the right size That rounding bails us out in certain cases Copyright © Curt Hill
So what do we do? We never compare floats or doubles for equality or inequality! –In general, equality is never true when we want it to be and inequality is always true We have to be satisfied that the two values are close, even if they are not quite equal
Copyright © Curt Hill Real Comparisons Suppose that we want to compare two doubles a and b for equality Round-off error makes them close but not equal, so use: if(abs(a-b) < ) This is true only if the difference between the two is less than 1E-5 The is the fuzz factor –Needs to be larger than the expected round-off error, but smaller than actual differerences
Alternative Names The C standard allows for some alternatives to some of the symbols Allows a symbol to have a reserved word: –not for ! –not_eq for != –and for && –or for || –Among others Copyright © Curt Hill
Precedence Again (postfix) (prefix) + - (unary) casts ! * / % + - >= <= == != && || = *= += -= /= %=
Copyright © Curt Hill Booleans Revisited For about 20 years C did not have a type bool It had the if, it had comparisons and it even had boolean operators So what did it do? It had a convention
Copyright © Curt Hill The C Boolean Convention Any type could function as a boolean If the value was zero it meant false If the value was not zero it meant true Thus a character, integer, float could pass for a bool C++ has maintained this –Java did not
Copyright © Curt Hill Examples Given int a = 2, b = 0, c = -5; if(a) // true … if(b) // false … if(c) // true … All these work and do not generate syntax errors
Copyright © Curt Hill The tricky one The reason this works: if (a = b) The value assigned to a is returned as the result This will be interpreted as false if zero and true otherwise Allows us to both assign and drive an if at the same time However, it is usually a mistake, a left out =
Compilers The: if(a = b)… is legal and actually good C/C++ It allows a common mistake Borland/Codegear/Embarcadero compilers give a warning –Like all warnings it may be ignored Microsoft Visual Studio does not Copyright © Curt Hill
What do comparison operators do Whenever a comparison is done a 0/1 is always produced This is usually cast as a bool but not always int a = b>5; will produce 0 or 1 in a –But no error
Copyright © Curt Hill The Real Tricky One Suppose that int a = 5, b= 4, c=9; The comparison: if(a<b<c) will be true Why? 5 0 // false 0 1 // true Always use (a<b && b<c)
Copyright © Curt Hill Evaluation of the condition There are states in the truth table where we do not care about the second operand –TRUE OR TRUE is the same as TRUE OR FALSE –The second operand does not matter –TRUE OR ? is TRUE Similarly FALSE AND ? is FALSE
Copyright © Curt Hill Short Circuit Evaluation The compiler knows this When ever it knows what the answer will be it stops evaluating Example: if(a!=0 && b/a>12) should always work When a == 0 then the compiler knows that FALSE AND ? is FALSE so does not need to evaluate the b/a>12 –Avoids the zero division exception
A Problem Suppose I have a truly ugly condition: if(a+2>5 && b-3<c*2) I want to do nothing if this is true and several things in a compound statement if it is false Copyright © Curt Hill
Reversing Conditions Sometimes we have difficulty with these types of conditions A complicated condition may be difficult to reverse There are three solutions: –Negation –Do nothing then –DeMorgan’s Law Copyright © Curt Hill
Negation One possibility is negating the entire expression Introduce one more pair of parentheses and insert the negation operator ! Try this: if(!(a+2>5 && b-3<c*2)) {…} Copyright © Curt Hill
Empty statement An empty statement is just a semicolon It says “do nothing” Try this: if(a+2>5 && b-3<c*2) ; // The empty stmt else {…}
DeMorgan’s Laws Any And may be reversed by negating the conditions and reversing the And to an OR –!(a>b && c d Any Or may be reversed by negating the conditions and reversing the Or to an And !(a==b || c>=d) becomes a!=b && c<d Copyright © Curt Hill
DeMorgan’s Solution Applying this we can solve the problem of the previous if: if(a+2>5 && b-3<c*2) Try this instead: if(a+2 =c*2) {…} Copyright © Curt Hill
Readability The compiler ignores white space! People do not ignore white space! Use indentation to improve the readability of your programs Indent the statements controlled by an If or any other flow of control statement The change in left margin is a powerful visual clue to the reader
Copyright © Curt Hill Example of Readability Use: if(a>b){ x = a*b; y += 5; } cin >> s; Do not: if(a>b){ x = a*b; y += 5;} cin >> s; Use: if(a==c){ x = a*b; y += 5;... else { y *= 2;... Do not: if(a==c){ x = a*b; y += 5;... else { y *= 2;...