C++逻辑运算符 #

一、逻辑运算符概述 #

逻辑运算符用于组合或修改布尔表达式,返回布尔值。

1.1 运算符列表 #

运算符 名称 示例 说明
&& 逻辑与 a && b 两者都为true时为true
|| 逻辑或 a || b 任一为true时为true
! 逻辑非 !a 取反

1.2 基本使用 #

cpp
#include <iostream>

int main() {
    bool a = true;
    bool b = false;
    
    std::cout << std::boolalpha;
    
    std::cout << "a && b: " << (a && b) << std::endl;  // false
    std::cout << "a || b: " << (a || b) << std::endl;  // true
    std::cout << "!a: " << (!a) << std::endl;          // false
    std::cout << "!b: " << (!b) << std::endl;          // true
    
    return 0;
}

二、逻辑与运算符 && #

2.1 真值表 #

a b a && b
true true true
true false false
false true false
false false false

2.2 基本用法 #

cpp
int age = 25;
bool hasLicense = true;

// 检查是否可以开车
if (age >= 18 && hasLicense) {
    std::cout << "可以开车" << std::endl;
}

2.3 多条件组合 #

cpp
int score = 85;
int attendance = 90;

// 检查是否获得奖学金
if (score >= 80 && attendance >= 80 && score <= 100) {
    std::cout << "获得奖学金" << std::endl;
}

2.4 短路求值 #

cpp
// 短路求值:如果左边为false,右边不会执行
int x = 5;

if (x > 10 && ++x > 0) {
    // 不会执行
}
// x仍然是5,因为++x没有执行

if (x > 0 && ++x > 0) {
    // 会执行
}
// x变成6

2.5 安全检查 #

cpp
int* ptr = nullptr;
int size = 10;

// 安全访问数组
if (ptr != nullptr && size > 0) {
    // 只有ptr不为空时才访问
    std::cout << ptr[0] << std::endl;
}

// 常见模式:先检查指针,再使用
if (ptr && *ptr > 0) {
    // 安全
}

三、逻辑或运算符 || #

3.1 真值表 #

a b a || b
true true true
true false true
false true true
false false false

3.2 基本用法 #

cpp
int day = 6;  // 星期六

// 检查是否是周末
if (day == 6 || day == 7) {
    std::cout << "周末" << std::endl;
}

3.3 多条件组合 #

cpp
char grade = 'A';

// 检查是否是优秀
if (grade == 'A' || grade == 'B') {
    std::cout << "优秀" << std::endl;
}

3.4 短路求值 #

cpp
// 短路求值:如果左边为true,右边不会执行
int x = 5;

if (x > 0 || ++x > 0) {
    // 会执行
}
// x仍然是5,因为++x没有执行

if (x < 0 || ++x > 0) {
    // 会执行
}
// x变成6

3.5 默认值设置 #

cpp
int userInput = 0;
int defaultValue = 10;

// 使用用户输入或默认值
int value = userInput || defaultValue;  // 如果userInput为0,使用defaultValue

// 更清晰的写法
int value = (userInput != 0) ? userInput : defaultValue;

四、逻辑非运算符 ! #

4.1 真值表 #

a !a
true false
false true

4.2 基本用法 #

cpp
bool isLoggedIn = false;

if (!isLoggedIn) {
    std::cout << "请先登录" << std::endl;
}

4.3 与比较运算符结合 #

cpp
int x = 10;

// 检查x不等于5
if (!(x == 5)) {
    std::cout << "x不是5" << std::endl;
}

// 等价于
if (x != 5) {
    std::cout << "x不是5" << std::endl;
}

4.4 检查空指针 #

cpp
int* ptr = nullptr;

// 使用!
if (!ptr) {
    std::cout << "空指针" << std::endl;
}

// 等价于
if (ptr == nullptr) {
    std::cout << "空指针" << std::endl;
}

4.5 双重否定 #

cpp
int x = 5;

// 双重否定:转换为布尔值
bool isNonZero = !!x;  // true

// 等价于
bool isNonZero = (x != 0);

五、运算符优先级 #

5.1 逻辑运算符优先级 #

cpp
// 优先级:! > && > ||
bool a = true, b = false, c = true;

bool r1 = a || b && c;   // 等价于 a || (b && c) = true || false = true
bool r2 = !a && b;       // 等价于 (!a) && b = false && false = false
bool r3 = !a || b;       // 等价于 (!a) || b = false || false = false

5.2 与其他运算符的关系 #

cpp
int x = 5, y = 10;

// 关系运算符优先级高于逻辑运算符
bool r1 = x > 0 && y > 0;    // 等价于 (x > 0) && (y > 0)
bool r2 = x > 0 || y < 0;    // 等价于 (x > 0) || (y < 0)

// 赋值运算符优先级最低
bool r3 = x > 0 && y = 10;   // 错误!需要括号
bool r4 = x > 0 && (y = 10); // 正确但不推荐

5.3 优先级表 #

优先级 运算符
!
关系运算符
&&
||

5.4 使用括号 #

cpp
// 不清晰
bool result = a || b && c || d;

// 清晰
bool result = a || (b && c) || d;

六、德摩根定律 #

6.1 定律内容 #

text
!(a && b) = !a || !b
!(a || b) = !a && !b

6.2 应用示例 #

cpp
int x = 5;

// 原始条件
if (!(x > 0 && x < 10)) {
    std::cout << "x不在0到10之间" << std::endl;
}

// 应用德摩根定律
if (x <= 0 || x >= 10) {
    std::cout << "x不在0到10之间" << std::endl;
}

6.3 复杂条件简化 #

cpp
// 复杂条件
if (!(a > 0 && b > 0 && c > 0)) {
    // ...
}

// 简化后
if (a <= 0 || b <= 0 || c <= 0) {
    // ...
}

七、实际应用 #

7.1 输入验证 #

cpp
int age;
std::cout << "请输入年龄: ";
std::cin >> age;

// 验证年龄范围
if (age >= 0 && age <= 120) {
    std::cout << "有效年龄" << std::endl;
} else {
    std::cout << "无效年龄" << std::endl;
}

7.2 权限检查 #

cpp
bool isAdmin = true;
bool hasPermission = false;

// 检查是否有权限
if (isAdmin || hasPermission) {
    std::cout << "允许访问" << std::endl;
}

7.3 条件组合 #

cpp
int score = 85;
int attendance = 90;
bool isMember = true;

// 复杂条件
if ((score >= 80 && attendance >= 80) || isMember) {
    std::cout << "获得奖励" << std::endl;
}

7.4 游戏状态检查 #

cpp
int health = 50;
int shield = 30;
bool isInvincible = false;

// 检查是否存活
if (health > 0 || shield > 0 || isInvincible) {
    std::cout << "角色存活" << std::endl;
}

八、位运算符 vs 逻辑运算符 #

8.1 区别 #

cpp
// 逻辑运算符:返回布尔值,短路求值
bool a = true, b = false;
bool r1 = a && b;   // false
bool r2 = a || b;   // true

// 位运算符:对每一位进行运算,不短路
int x = 5, y = 3;   // x = 0101, y = 0011
int r3 = x & y;     // 0001 = 1
int r4 = x | y;     // 0111 = 7

8.2 常见错误 #

cpp
int x = 5;

// 错误:使用位运算符
if (x & 1) {  // 正确但容易混淆
    std::cout << "奇数" << std::endl;
}

// 正确:使用逻辑运算符
if (x && 1) {  // 不正确!应该是 x & 1 或 x % 2 != 0
    std::cout << "奇数" << std::endl;
}

// 正确的奇偶判断
if (x % 2 != 0) {
    std::cout << "奇数" << std::endl;
}

九、三元运算符与逻辑运算 #

9.1 替代简单if-else #

cpp
int x = 10;

// 使用if-else
std::string result1;
if (x > 0) {
    result1 = "正数";
} else {
    result1 = "非正数";
}

// 使用三元运算符
std::string result2 = (x > 0) ? "正数" : "非正数";

9.2 与逻辑运算符结合 #

cpp
int score = 75;

// 复杂条件
std::string grade = (score >= 90) ? "A" :
                    (score >= 80) ? "B" :
                    (score >= 70) ? "C" :
                    (score >= 60) ? "D" : "F";

十、最佳实践 #

10.1 使用括号明确优先级 #

cpp
// 不推荐
if (a || b && c)

// 推荐
if (a || (b && c))

10.2 利用短路求值 #

cpp
// 安全访问
if (ptr != nullptr && ptr->isValid()) {
    // 安全
}

// 避免不必要的计算
if (simpleCondition || expensiveCondition()) {
    // 如果simpleCondition为true,不会调用expensiveCondition()
}

10.3 避免复杂表达式 #

cpp
// 不推荐:过于复杂
if ((a && b) || (c && d) || (e && f)) {
    // ...
}

// 推荐:分解为有意义的变量
bool condition1 = a && b;
bool condition2 = c && d;
bool condition3 = e && f;

if (condition1 || condition2 || condition3) {
    // ...
}

10.4 使用有意义的变量名 #

cpp
// 不推荐
if (age >= 18 && age <= 65 && hasLicense && !hasAccident) {
    // ...
}

// 推荐
bool isWorkingAge = age >= 18 && age <= 65;
bool canDrive = hasLicense && !hasAccident;

if (isWorkingAge && canDrive) {
    // ...
}

十一、总结 #

逻辑运算符一览 #

运算符 名称 说明
&& 逻辑与 两者都为true时为true
|| 逻辑或 任一为true时为true
! 逻辑非 取反

短路求值规则 #

运算符 短路条件
&& 左边为false时,不计算右边
|| 左边为true时,不计算右边

注意事项 #

  1. 注意运算符优先级
  2. 利用短路求值提高效率和安全
  3. 使用括号明确意图
  4. 避免过于复杂的表达式
  5. 区分 &/|&&/||

下一步,让我们学习位运算符!

最后更新:2026-03-26