Logical Operators
So far we've seen two families of operators (besides the oddball conditional operator). First are the arithmetic operators +, -, *, /, and %. Second are the relational operators <, >, <=, >=, ==, and !=.
Let's examine a third family of operators, called logical operators. These operators allow you to logically combine Boolean variables (that is, variables of type bool, with true or false values). For example, today is a weekday has a Boolean value, since it's either true or false. Another Boolean expression is Maria took the car. We can connect these expressions logically: If today is a weekday, and Maria took the car, then I'll have to take the bus. The logical connection here is the word and, which provides a true or false value to the combination of the two phrases. Only if they are both true will I have to take the bus.
Logical AND Operator
Let's see how logical operators combine Boolean expressions in C++. Here's an example, advenand, that uses a logical operator to spruce up the adventure game from the adswitch example. We'll bury some treasure at coordinates (7,11) and see whether the player can find it.
// advenand.cpp // demonstrates AND logical operator #include <iostream> using namespace std; #include <process.h> //for exit() #include <conio.h> //for getche() int main() { char dir='a'; int x=10, y=10; while( dir != '\r' ) { cout << "\nYour location is " << x << ", " << y; cout << "\nEnter direction (n, s, e, w): "; dir = getche(); //get direction switch(dir) { case 'n': y--; break; //update coordinates case 's': y++; break; case 'e': x++; break; case 'w': x--; break; } if( x==7 && y==11 ) //if x is 7 and y is 11 { cout << "\nYou found the treasure!\n"; exit(0); //exit from program } } //end switch return 0; } //end main
The key to this program is the if statement
if( x==7 && y==11 )
The test expression will be true only if x is 7 and y is 11. The logical AND operator && joins the two relational expressions to achieve this result. (A relational expression is one that uses a relational operator.)
Notice that parentheses are not necessary around the relational expressions.
( (x==7) && (y==11) ) // inner parentheses not necessary
This is because the relational operators have higher precedence than the logical operators.
Here's some interaction as the user arrives at these coordinates:
Your location is 7, 10 Enter direction (n, s, e, w): s You found the treasure!
There are three logical operators in C++:
Operator |
Effect |
&& |
Logical AND |
|| |
Logical OR |
! |
Logical NOT |
There is no logical XOR (exclusive OR) operator in C++.
Let's look at examples of the || and ! operators.
Logical OR Operator
Suppose in the adventure game you decide there will be dragons if the user goes too far east or too far west. Here's an example, advenor, that uses the logical OR operator to implement this frightening impediment to free adventuring. It's a variation on the advenand program.
// advenor.cpp // demonstrates OR logical operator #include <iostream> using namespace std; #include <process.h> //for exit() #include <conio.h> //for getche() int main() { char dir='a'; int x=10, y=10; while( dir != '\r' ) //quit on Enter key { cout << "\n\nYour location is " << x << ", " << y; if( x<5 || x>15 ) //if x west of 5 OR east of 15 cout << "\nBeware: dragons lurk here"; cout << "\nEnter direction (n, s, e, w): "; dir = getche(); //get direction switch(dir) { case 'n': y--; break; //update coordinates case 's': y++; break; case 'e': x++; break; case 'w': x--; break; } //end switch } //end while return 0; } //end main()
The expression
x<5 || x>15
is true whenever either x is less than 5 (the player is too far west), or x is greater than 15 (the player is too far east). Again, the || operator has lower precedence than the relational operators < and >, so no parentheses are needed in this expression.
Logical NOT Operator
The logical NOT operator ! is a unary operator—that is, it takes only one operand. (Almost all the operators we've seen thus far are binary operators; they take two operands. The conditional operator is the only ternary operator in C++.) The effect of the ! is that the logical value of its operand is reversed: If something is true, ! makes it false; if it is false, ! makes it true. (It would be nice if life were so easily manipulated.)
For example, (x==7) is true if x is equal to 7, but !(x==7) is true if x is not equal to 7. (In this situation you could use the relational not equals operator, x != 7, to achieve the same effect.)
A True/False Value for Every Integer Variable
We may have given you the impression that for an expression to have a true/false value, it must involve a relational operator. But in fact, every integer expression has a true/false value, even if it is only a single variable. The expression x is true whenever x is not 0, and false when x is 0. Applying the ! operator to this situation, we can see that the !x is true whenever x is 0, since it reverses the truth value of x.
Let's put these ideas to work. Imagine in your adventure game that you want to place a mushroom on all the locations where both x and y are a multiple of 7. (As you probably know, mushrooms, when consumed by the player, confer magical powers.) The remainder when x is divided by 7, which can be calculated by x%7, is 0 only when x is a multiple of 7. So to specify the mushroom locations, we can write
if( x%7==0 && y%7==0 ) cout << "There's a mushroom here.\n";
However, remembering that expressions are true or false even if they don't involve relational operators, you can use the ! operator to provide a more concise format.
if( !(x%7) && !(y%7) ) // if not x%7 and not y%7
This has exactly the same effect.
We've said that the logical operators && and || have lower precedence than the relational operators. Why then do we need parentheses around x%7 and y%7? Because, even though it is a logical operator, ! is a unary operator, which has higher precedence than relational operators.