运算符与表达式
建议先阅读:05_变量与数据类型
原理
表达式求值与副作用
C++ 中,大多数二元运算符不保证左右操作数的求值顺序。i++ + ++i 在同一表达式中对一个变量无序列点的多次修改导致未定义行为。C++17 起部分场景(如 a.b, a->b, a[b], a << b, a >> b)有保证的求值顺序。
短路求值
&& 和 || 保证从左到右求值且具备短路特性:
a && b:a 为 false 时 b 不被求值a || b:a 为 true 时 b 不被求值
编译器利用短路求值进行优化——可将 ptr != nullptr && *ptr > 0 编译为安全的分支代码。
位运算的底层意义
位运算符直接操作 CPU 的位操作指令(AND/OR/XOR/NOT/SHL/SHR),通常单周期完成。常用优化场景:
n & 1判断奇偶n << k等价于 n * 2n >> k等价于 n / 2n & (n - 1)清除最低位的 1,用于判断 2 的幂
整数除法的截断
C++11 规定整数除法向零截断:-7 / 2 = -3(而非 -4)。
语法
运算符分类
| 类别 | 运算符 |
|---|---|
| 算术 | + - * / % |
| 自增/自减 | ++(前) ++(后) --(前) --(后) |
| 关系 | > < >= <= == != |
| 逻辑 | && ` |
| 位运算 | & ` |
| 赋值 | = += -= *= /= %= &= ` |
| 三元 | ?: |
自增自减
int a = 5;
int b = ++a; // a=6, b=6 (先加后用)
int c = a++; // c=6, a=7 (先用后加)对基本类型无性能差异;对迭代器,++it 优于 it++(后缀需创建临时对象)。
三目运算符
int max = (a > b) ? a : b;
std::cout << (score >= 60 ? "及格" : "不及格") << '\n';优先级陷阱
| 优先级陷阱 | 错误写法 | 正确写法 |
|---|---|---|
| 位运算 vs 比较 | x & 1 == 0 | (x & 1) == 0 |
| 位移 vs 加法 | a + b << 2 | (a + b) << 2 |
| 逻辑与 vs 逻辑或 | `a |
位运算符
& ^ |优先级低于比较运算符== != < >——这是最易出错的陷阱。
位运算常用操作
n & 1 // 判断奇偶: 1=奇 0=偶
n & (n - 1) // 清除最低位的 1
n & -n // 获取最低位的 1
x ^= y; y ^= x; x ^= y; // 交换两数(不能用于同一变量)
// 位掩码权限系统
const int READ = 1 << 0; // 0001
const int WRITE = 1 << 1; // 0010
int perm = READ | WRITE; // 添加权限
perm &= ~WRITE; // 移除权限
bool canRead = perm & READ; // 检查权限实践
浮点数比较:
bool approxEqual(double a, double b) {
return std::abs(a - b) < 1e-9;
}力扣:
力扣: 简单计算与条件题 (条件+算术)
力扣: 闰年判断题 (逻辑运算符组合)
AI 自检提示:询问 AI “C++ 中位运算符 & 和比较运算符 == 的优先级关系,并举例说明一个常见陷阱”。