The if
, if
…else
, while
, do
…while
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 if
…else
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).
&&
) OperatorSuppose 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.
&&
(logical AND) operator truth table.expression1 | expression2 | expression1 && expression2 |
---|---|---|
false |
false |
false |
false |
true |
false |
true |
false |
false |
true |
true |
true |
||
) OperatorNow 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.
||
(logical OR) operator truth table.expression1 | expression2 | expression1 || expression2 |
---|---|---|
false |
false |
false |
false |
true |
true |
true |
false |
true |
true |
true |
true |
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.
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.
!
) OperatorThe !
(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.
!
(logical negation) operator truth table.expression | ! expression |
---|---|
false |
true |
true |
false |
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 !
.
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.
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 |