5.11 Logical Operators

The if, ifelse, while, dowhile and for statements each require a condition to determine how to continue a program’s flow of control. So far, we’ve studied only simple conditions, such as count <= 10, number != sentinelValue and total > 1000. Simple conditions are expressed in terms of the relational operators >, <, >= and <= and the equality operators == and !=, and each expression tests only one condition. To test multiple conditions in the process of making a decision, we performed these tests in separate statements or in nested if or ifelse statements. Sometimes control statements require more complex conditions to determine a program’s flow of control.

C++’s logical operators enable you to form more complex conditions by combining simple conditions. The logical operators are && (logical AND), || (logical OR) and ! (logical negation).

5.11.1 Logical AND (&&) Operator

Suppose we wish to ensure at some point in a program that two conditions are both true before we choose a certain path of execution. In this case, we can use the && (logical AND) operator, as follows:


if (gender == FEMALE && age >= 65) {
   ++seniorFemales;
}

This if statement contains two simple conditions. The condition gender == FEMALE compares variable gender to the constant FEMALE to determine whether a person is female. The condition age >= 65 might be evaluated to determine whether a person is a senior citizen. The if statement considers the combined condition


gender == FEMALE && age >= 65

which is true if and only if both simple conditions are true. In this case, the if statement’s body increments seniorFemales by 1. If either or both of the simple conditions are false, the program skips the increment. Some programmers find that the preceding combined condition is more readable when redundant parentheses are added, as in


(gender == FEMALE) && (age >= 65)

The table in Fig. 5.15 summarizes the && operator. The table shows all four possible combinations of the bool values false and true values for expression1 and expression2. Such tables are called truth tables. C++ evaluates to zero (false) or nonzero (true) all expressions that include relational operators, equality operators or logical operators.

Fig. 5.15 && (logical AND) operator truth table.

expression1 expression2 expression1 && expression2
false false false
false true false
true false false
true true true

5.11.2 Logical OR (||) Operator

Now suppose we wish to ensure that either or both of two conditions are true before we choose a certain path of execution. In this case, we use the || (logical OR) operator, as in the following program segment:


if ((semesterAverage >= 90) || (finalExam >= 90)) {
   cout << "Student grade is A
";
}

This statement also contains two simple conditions. The condition semesterAverage >= 90 evaluates to determine whether the student deserves an A in the course because of a solid performance throughout the semester. The condition finalExam >= 90 evaluates to determine whether the student deserves an A in the course because of an outstanding performance on the final exam. The if statement then considers the combined condition


(semesterAverage >= 90) || (finalExam >= 90)

and awards the student an A if either or both of the simple conditions are true. The only time the message "Student grade is A" is not printed is when both of the simple conditions are false. Figure 5.16 is a truth table for the operator logical OR (||). Operator && has a higher precedence than operator ||. Both operators associate from left to right.

Fig. 5.16 || (logical OR) operator truth table.

expression1 expression2 expression1 || expression2
false false false
false true true
true false true
true true true

5.11.3 Short-Circuit Evaluation

The parts of an expression containing && or || operators are evaluated only until it’s known whether the condition is true or false. Thus, evaluation of the expression

(gender == FEMALE) && (age >= 65)

stops immediately if gender is not equal to FEMALE (i.e., the entire expression is false) and continues if gender is equal to FEMALE (i.e., the entire expression could still be true if the condition age >= 65 is true). This feature of logical AND and logical OR expressions is called short-circuit evaluation.

Common Programming Error 5.8

In expressions using operator &&, a condition—we’ll call this the dependent condition—may require another condition to be true for the evaluation of the dependent condition to be meaningful. In this case, the dependent condition should be placed after the && operator to prevent errors. Consider the expression (i != 0) && (10 / i == 2). The dependent condition (10 / i== 2) must appear after the && operator to prevent the possibility of division by zero.

5.11.4 Logical Negation (!) Operator

The ! (logical negation, also called logical NOT or logical complement) operator “reverses” the meaning of a condition. Unlike the logical operators && and ||, which are binary operators that combine two conditions, the logical negation operator is a unary operator that has only one condition as an operand. To execute code only when a condition is false, place the logical negation operator before the original condition, as in the program segment


if (!(grade == sentinelValue)) {
   cout << "The next grade is " << grade << "
";
}

which executes the body statement only if grade is not equal to sentinelValue. The parentheses around the condition grade == sentinelValue are needed because the logical negation operator has a higher precedence than the equality operator.

In most cases, you can avoid using logical negation by expressing the condition differently with an appropriate relational or equality operator. For example, the previous statement may also be written as follows:


if (grade != sentinelValue) {
   cout << "The next grade is " << grade << "
";
}

This flexibility can help you express a condition in a more convenient manner. Figure 5.17 is a truth table for the logical negation operator.

Fig. 5.17 ! (logical negation) operator truth table.

expression !expression
false true
true false

5.11.5 Logical Operators Example

Figure 5.18 uses logical operators to produce the truth tables discussed in this section. The output shows each expression that’s evaluated and its bool result. By default, bool values true and false are displayed by cout and the stream insertion operator as 1 and 0, respectively. We use stream manipulator boolalpha (a sticky manipulator) in line 8 to specify that the value of each bool expression should be displayed as either the word “true” or the word “false.” Lines 8–12 produce the truth table for &&. Lines 15–19 produce the truth table for ||. Lines 22–24 produce the truth table for !.

Fig. 5.18 Logical operators.

Alternate View

 1   // Fig. 5.18: LogicalOperators.cpp
 2   // Logical operators.
 3   #include <iostream>
 4   using namespace std;
 5
 6   int main() {
 7      // create truth table for && (logical AND) operator
 8      cout << boolalpha << "Logical AND (&&)"
 9         << "
false && false: " << (false && false)
10         << "
false && true: " << (false && true)
11         << "
true && false: " << (true && false)
12         << "
true && true: " << (true && true) << "

";
13
14      // create truth table for || (logical OR) operator
15      cout << "Logical OR (||)"
16         << "
false || false: " << (false || false)
17         << "
false || true: " << (false || true)
18         << "
true || false: " << (true || false)
19         << "
true || true: " << (true || true) << "

";
20
21      // create truth table for ! (logical negation) operator
22      cout << "Logical negation (!)"
23         << "
!false: " << (!false)
24         << "
!true: " << (!true) << endl;
25   }

Logical AND (&&)
false && false: false
false && true: false
true && false: false
true && true: true

Logical OR (||)
false || false: false
false || true: true
true || false: true
true || true: true

Logical negation (!)
!false: true
!true: false

Precedence and Associativity of the Operators Presented So Far

Figure 5.19 shows the precedence and associativity of the C++ operators introduced so far. The operators are shown from top to bottom in decreasing order of precedence.

Fig. 5.19 Operator precedence and associativity.

Operators Associativity Type
:: ()         left to right [See caution in Fig. 2.10 regarding grouping parentheses.] primary
++ -- static_cast<type>() left to right postfix
++ -- + - !   right to left unary (prefix)
* / %       left to right multiplicative
+ -         left to right additive
<< >>         left to right insertion/extraction
< <= > >=     left to right relational
== !=         left to right equality
&&           left to right logical AND
||           left to right logical OR
?:           right to left conditional
= += -= *= /= %= right to left assignment
,           left to right comma
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset