While relational operators

本文详细介绍了C++中逻辑运算符的使用方法,包括逻辑非(!)、逻辑与(&&)和逻辑或(||),并解释了短路评估的概念及如何正确地组合使用这些运算符。

While relational operators can be used to test whether a particular condition is true or false, they can only test one condition at a time. Often we need to know whether multiple conditions are true at once. For example, to check whether we’ve won the lottery, we have to compare whether all the numbers we picked match all of the winning numbers. In a lottery with 6 numbers, this would involve 6 comparisons, all of which have to be true. Other times, we need to know whether any one of multiple conditions is true. For example, we may decide to skip work today if we’re sick, if we’re too tired, or if won the lottery in our previous example. This would involve checking whether any of 3 comparisons is true.

Logical operators provide us with this capability.

C++ provides us with 3 logical operators, one of which you have already seen:

Operator Symbol Form Operation
Logical NOT ! !x true if x is false, or false if x is true
Logical AND && x && y true if both x and y are true, false otherwise
Logical OR || x || y true if either x or y are true, false otherwise

Logical NOT

You have already run across the logical NOT operator in the section on boolean values. We can summarize the effects of logical NOT like so:

Logical NOT (operator !)
Right operand Result
true false
false true

If logical NOT’s operand evaluates to true, logical NOT evalutes to false. If logical NOT’s operand evaluates to false, logical NOT evaluates to true. In other words, logical NOT flips a boolean value from true to false or vice-versa.

Logical not is often used in conditionals:

1
2
3
4
5
bool bTooLarge = (x > 100); // bTooLarge is true if x > 100
if (!bTooLarge)
    // do something with x
else
    // print an error

One thing to be wary of is that logical NOT has a very high level of precedence. New programmers often make the following mistake:

1
2
3
4
5
6
7
int x = 5;
int y = 7;
 
if (! x == y)
    cout << "x does not equal y";
else
    cout << "x equals y";

This program prints “x equals y”! But x does not equal y, so how is this possible? The answer is that because the logical NOT operator has higher precedence than the equality operator, the expression ! x == y actually evaluates as (!x) == y. Since x is 5, !x evaluates to 0, and 0 == y is false, so the else statement executes!

Note: any non-zero integer value evaluates to true when used in a boolean context. Since x is 5, x evaluates to true, and !x evaluates to false (0). Mixing integer and boolean operations like this can be very confusing, and should be avoided!

The correct way to write the above snippet is:

1
2
3
4
5
6
7
int x = 5;
int y = 7;
 
if (!(x == y))
    cout << "x does not equal y";
else
    cout << "x equals y";

This way, x == y will be evaluated first, and then logical NOT will flip the boolean result.

Rule: If logical NOT is intended to operate on the result of other operators, the other operators and their operands need to be enclosed in parenthesis.

Simple uses of logical NOT, such as if (!bValue) do not need parenthesis because precedence does not come into play.

Logical OR

The logical OR operator is used to test whether either of two conditions is true. If the left operand evaluates to true, or the right operand evaluates to true, the logical OR operator returns true. If both operands are true, then logical OR will return true as well.

Logical OR (operator ||)
Left operand Right operand Result
false false false
false true true
true false true
true true true

For example, consider the following program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
int main()
{
    using namespace std;
    cout << "Enter a number: ";
    int nValue;
    cin >> nValue;
 
    if (nValue == 0 || nValue == 1)
        cout << "You picked 0 or 1" << endl;
    else
        cout << "You did not pick 0 or 1" << endl;
    return 0;
}

In this case, we use the logical OR operator to test whether either the left condition (nValue == 0) or the right condition (nValue == 1) is true. If either (or both) are true, the logical OR operator evaluates to true, which means the if statement executes. If neither are true, the logical OR operator evaluates to false, which means the else statement executes.

You can string together many logical OR statements:

1
2
if (nValue == 0 || nValue == 1 || nValue == 2 || nValue == 3)
     cout << "You picked 0, 1, 2, or 3" << endl;

New programmers sometimes confuse the logical OR operator (||) with the bitwise OR operator (|). Even though they both have OR in the name, they perform different functions. Mixing them up can lead to incorrect results.

Logical AND

The logical AND operator is used to test whether both conditions are true. If both conditions are true, logical AND returns true. Otherwise, it returns false.

Logical AND (operator &&)
Left operand Right operand Result
false false false
false true false
true false false
true true true

For example, we might want to know if the value of variable x is between 10 and 20. This is actually two conditions: we need to know if x is greater than 10, and also whether x is less then 20.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
 
int main()
{
    using namespace std;
    cout << "Enter a number: ";
    int nValue;
    cin >> nValue;
 
    if (nValue > 10 && nValue < 20)
        cout << "Your value is between 10 and 20" << endl;
    else
        cout << "You value is not between 10 and 20" << endl;
    return 0;
}

In this case, we use the logical AND operator to test whether the left condition (nValue > 10) AND the right condition (nValue < 20) are both true. If both are true, the logical AND operator evaluates to true, and the if statement executes. If neither are true, or only one is true, the logical AND operator evaluates to false, and the else statement executes.

As with logical OR, you can string together many logical AND statements:

1
2
3
4
if (nValue1 == 0 && nValue2 == 1 && nValue3 == 4 && nValue4 == 6)
    // do something
else
    // do something else

If all of these conditions are true, the if statement will execute. If any of these conditions are false, the else statement will execute.

Short circuit evaluation

In order for logical AND to return true, both operands must evaluate to true. If the first operand evaluates to false, logical AND knows it must return false regardless of whether the second operand evaluates to true or false. In this case, the logical AND operator will go ahead and return false immediately without even evaluating the second operand! This is known as short circuit evaluation, and it is done primary for optimization purposes.

Similarly, if the first operand for logical OR is true, then the entire OR condition has to evaluate to true, and the second operand does not need to be evaluated.

Short circuit evaluation presents another opportunity to show why operators that cause side effects should not be used in compound expressions. Consider the following snippet:

1
2
if (x == 1 && y++ == 2)
    // do something

if x does not equal 1, y++ never gets evaluated! Thus, y will only be incremented if x evaluates to 1, which is probably not what the programmer intended!

New programmers sometimes confuse the logical AND operator (&&) with the bitwise AND operator (&). Even though they both have AND in the name, they perform different functions. Mixing them up can lead to incorrect results.

Mixing ANDs and ORs

Mixing logical AND and logical OR operators in the same expression often can not be avoided, but it is an area full of potential dangers.

Many programmers assume that logical AND and logical OR have the same precedence (or forget that they don't), just like addition/subtraction and multiplication/division do. However, logical AND has higher precedence than logical OR, thus logical AND operators will be evaluated ahead of logical OR operators (unless they have been parenthesized).

As a result of this, new programmers will often write expressions such as nValue1 || nValue2 && nValue3. Because logical AND has higher precedence, this evaluates as nValue1 || (nValue2 && nValue3), not (nValue1 || nValue2) && nValue3. Hopefully that's what the programmer wanted! If the programmer was assuming left to right evaluation (as happens with addition/subtraction, or multiplication/division), the programmer will get a result he or she was not expecting!

When mixing logical AND and logical OR in the same expression, it is a good idea to explicitly parenthesize each operator and it's operands. This helps prevent precedence mistakes, makes your code easier to read, and clearly defines how you intended the expression to evaluate. For example, rather than writing nValue1 && nValue2 || nValue3 && nValue4, it is better to write (nValue1 && nValue2) || (nValue3 && nValue4). This makes it clear at a glance how this expression will evaluate.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值