逻辑运算与逻辑表达式

一、关系运算符与关系表达式

关系运算用于比较两个值的大小,是逻辑运算中最基础的部分。C++ 提供的关系运算符按优先级从高到低排列如下:

< <= > >= == !=

其中,<、<=、>、>= 的优先级高于 == 和 !=。

用关系运算符将两个表达式连接起来,就构成关系表达式。关系表达式的结果类型为 bool,即 true 或 false。

示例:

a > b
c <= a + b
x + y == 3Code language: HTML, XML (xml)

注意:关系相等判断使用双等号 ==,不要与赋值运算符 = 混淆。例如 if (a = 5) 是将 5 赋给 a 并判断结果非零,而 if (a == 5) 才是判断 a 是否等于 5。

二、逻辑运算符

仅有关系比较不足以表达复杂的判断条件,还需要用逻辑运算符将多个关系表达式组合起来,构成逻辑表达式。逻辑运算只能用于布尔类型的值或表达式。

C++ 提供三种逻辑运算符:

运算符名称操作数个数说明
!逻辑非一元对操作数取反,true 变 false,false 变 true
&&逻辑与二元两个操作数都为 true 时结果为 true,否则为 false
||逻辑或二元两个操作数都为 false 时结果为 false,否则为 true

优先级顺序:! 最高,&& 次之,|| 最低。

三、逻辑运算规则

逻辑非(!):

!true 结果为 false

!false 结果为 true

逻辑与(&&):

操作数1操作数2结果
truetruetrue
truefalsefalse
falsetruefalse
falsefalsefalse

逻辑或(||):

操作数1操作数2结果
truetruetrue
truefalsetrue
falsetruetrue
falsefalsefalse

四、短路求值特性

逻辑与和逻辑或具有短路求值(short-circuit evaluation)特性,这是需要重点理解的内容。

对于逻辑或(||):如果第一个操作数的值为 true,则整个表达式的结果已经确定为 true,不再计算第二个操作数。

对于逻辑与(&&):如果第一个操作数的值为 false,则整个表达式的结果已经确定为 false,不再计算第二个操作数。

示例一:逻辑或的短路

bool a = false;
int c = 10;
bool result1 = (a == true || ++c > 12);
cout << c << endl;   // 输出 10Code language: JavaScript (javascript)

分析:a 的值为 false,所以 a == true 的结果为 false。对于 || 运算,第一个操作数为 false,还需要计算第二个操作数。++c > 12 中 c 先自增为 11,11 > 12 为 false。因此 result1 为 false,c 的值变为 11。

注意:原文中 cout << c << endl; 输出 10 的分析有误。实际上 a == true 为 false,|| 不会短路,第二个操作数 ++c > 12 会被执行,c 自增为 11。因此正确输出应为 11。

示例二:逻辑与的短路

bool a = false;
int d = 10;
bool result2 = (a == true && ++d > 12);
cout << d << endl;   // 输出 10Code language: JavaScript (javascript)

分析:a == true 的结果为 false。对于 && 运算,第一个操作数为 false,整个表达式结果已确定为 false,不再计算第二个操作数 ++d > 12。因此 d 的值保持 10 不变,输出 10。

五、代码示例

以下代码演示了关系表达式、逻辑表达式以及短路求值的行为:

#include <iostream>
using namespace std;

int main()
{
    int x = 5, y = 10, z = 15;

    // 关系表达式
    cout << "(x < y) = " << (x < y) << endl;       // 输出 1 (true)
    cout << "(x == y) = " << (x == y) << endl;     // 输出 0 (false)

    // 逻辑非
    bool flag = true;
    cout << "!flag = " << !flag << endl;            // 输出 0 (false)

    // 逻辑与
    cout << "(x < y && y < z) = " << (x < y && y < z) << endl;  // 输出 1 (true)

    // 逻辑或
    cout << "(x > y || y < z) = " << (x > y || y < z) << endl;  // 输出 1 (true)

    // 短路求值演示
    int c = 10;
    bool a = false;
    bool r1 = (a == true || ++c > 12);
    cout << "after || : c = " << c << endl;   // 输出 11,因为 || 未短路,++c 执行

    int d = 10;
    bool r2 = (a == true && ++d > 12);
    cout << "after && : d = " << d << endl;   // 输出 10,因为 && 短路,++d 未执行

    // 复合条件示例:判断年份是否为闰年
    int year = 2024;
    bool isLeap = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
    cout << year << " is leap year : " << isLeap << endl;   // 输出 1 (true)

    return 0;
}Code language: PHP (php)

六、小结

  • 关系表达式用于比较两个值,结果为 bool 类型。注意区分 == 和 =。
  • 逻辑运算符包括 !、&&、||,用于组合多个布尔值。
  • 逻辑与和逻辑或具有短路求值特性:|| 在第一个操作数为 true 时跳过第二个操作数;&& 在第一个操作数为 false 时跳过第二个操作数。
  • 短路求值可以避免不必要的计算,有时还能防止错误,如指针非空判断后再访问成员:(p != nullptr && p->value > 0)。
  • 书写条件表达式时,应将计算成本低、容易为假(对于 &&)或容易为真(对于 ||)的子表达式放在前面,以提高效率。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注