Section 5.2. Relational and Logical Operators


5.2. Relational and Logical Operators

Table 5.2. Relational and Logical Operators

Each of these operators yields bool

Operator

Function

Use

!

logical NOT

!expr

<

less than

expr < expr

<=

less than or equal

expr <= expr

>

greater than

expr > expr

>=

greater than or equal

expr >= expr

==

equality

expr == expr

!=

inequality

expr != expr

&&

logical AND

expr && expr

||

logical OR

expr || expr


The relational and logical operators take operands of arithmetic or pointer type and return values of type bool.

Logical AND and OR Operators

The logical operators treat their operands as conditions (Section 1.4.1, p. 12). The operand is evaluated; if the result is zero the condition is false, otherwise it is true. The overall result of the AND operator is TRue if and only if both its operands evaluate to TRue. The logical OR (||) operator evaluates to true if either of its operands evaluates to true. Given the forms

      expr1 && expr2 // logical AND      expr1 || expr2 // logical OR 

expr2 is evaluated if and only if expr1 does not by itself determine the result. In other words, we're guaranteed that expr2 will be evaluated if and only if

  • In a logical AND expression, expr1 evaluates to TRue. If expr1 is false, then the expression will be false regardless of the value of expr2. When expr1 is true, it is possible for the expression to be true if expr2 is also TRue.

  • In a logical OR expression, expr1 evaluates to false; if expr1 is false, then the expression depends on whether expr2 is true.

The logical AND and OR operators always evaluate their left operand before the right. The right operand is evaluated only if the left operand does not determine the result. This evaluation strategy is often referred to as "short-circuit evaluation."



A valuable use of the logical AND operator is to have expr1 evaluate to false in the presence of a boundary condition that would make the evaluation of expr2 dangerous. As an example, we might have a string that contains the characters in a sentence and we might want to make the first word in the sentence all uppercase. We could do so as follows:

      string s("Expressions in C++ are composed...");      string::iterator it = s.begin();      // convert first word in s to uppercase      while (it != s.end() && !isspace(*it)) {          *it = toupper(*it); // toupper covered in section 3.2.4 (p. 88)          ++it;      } 

In this case, we combine our two tests in the condition in the while. First we test whether it has reached the end of the string. If not, it refers to a character in s. Only if that test succeeds is the right-hand operand evaluated. We're guaranteed that it refers to an actual character before we test to see whether the character is a space or not. The loop ends either when a space is encountered or, if there are no spaces in s, when we reach the end of s.

Logical NOT Operator

The logical NOT operator (!) treats its operand as a condition. It yields a result that has the opposite truth value from its operand. If the operand evaluates as nonzero, then ! returns false. For example, we might determine that a vector has elements by applying the logical NOT operator to the value returned by empty:

      // assign value of first element in vec to x if there is one      int x = 0;      if (!vec.empty())          x = *vec.begin(); 

The subexpression

      !vec.empty() 

evaluates to TRue if the call to empty returns false.

The Relational Operators Do Not Chain Together

The relational operators (<, <=, >, <=) are left associative. The fact that they are left associative is rarely of any use because the relational operators return bool results. If we do chain these operators together, the result is likely to be surprising:

      // oops! this condition does not determine if the 3 values are unequal      if (i < j < k) { /* ... */ } 

As written, this expression will evaluate as true if k is greater than one! The reason is that the left operand of the second less-than operator is the TRue/ false result of the firstthat is, the condition compares k to the integer values of 0 or 1. To accomplish the test we intended, we must rewrite the expression as follows:

      if (i < j && j < k) { /* ... */ } 

Equality Tests and the bool Literals

As we'll see in Section 5.12.2 (p. 180) a bool can be converted to any arithmetic typethe bool value false converts to zero and true converts to one.

Because bool converts to one, is almost never right to write an equality test that tests against the bool literal TRue:


      if (val == true) { /* ... */ } 


Either val is itself a bool or it is a type to which a bool can be converted. If val is a bool, then this test is equivalent to writing

      if (val) { /* ... */ } 

which is shorter and more direct (although admittedly when first learning the language this kind of abbreviation can be perplexing).

More importantly, if val is not a bool, then comparing val with true is equivalent to writing

      if (val == 1) { /* ... */ } 

which is very different from

      // condition succeeds if val is any nonzero value      if (val) { /* ... */ } 

in which any nonzero value in val is true. If we write the comparison explicitly, then we are saying that the condition will succeed only for the specific value 1.

Exercises Section 5.2

Exercise 5.5:

Explain when operands are evaluated in the logical AND operator, logical OR operator, and equality operator.

Exercise 5.6:

Explain the behavior of the following while condition:

      char *cp = "Hello World";      while (cp && *cp) 

Exercise 5.7:

Write the condition for a while loop that would read ints from the standard input and stop when the value read is equal to 42.

Exercise 5.8:

Write an expression that tests four values, a, b, c, and d, and ensures that a is greater than b, which is greater than c, which is greater than d.




C++ Primer
C Primer Plus (5th Edition)
ISBN: 0672326965
EAN: 2147483647
Year: 2006
Pages: 223
Authors: Stephen Prata

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net