2.2 运算符与表达式
运算符(Operator)是对数据进行操作的符号,表达式(Expression)是由变量、常量和运算符组合而成的计算式。C++ 提供了丰富的运算符,本节按类别逐一介绍。
用于基本的数学计算:
| 运算符 | 含义 | 示例 | 结果 |
|---|---|---|---|
+ | 加法 | 5 + 3 | 8 |
- | 减法 | 5 - 3 | 2 |
* | 乘法 | 5 * 3 | 15 |
/ | 除法 | 5 / 3 | 1 |
% | 取余(模) | 5 % 3 | 2 |
关于除法需要特别注意:当两个操作数都是整数时,执行的是整数除法(Integer Division),结果会截断小数部分:
int a = 5 / 3; // 结果是 1,不是 1.666...double b = 5.0 / 3; // 结果是 1.666...(其中一个操作数是浮点数)double c = 5 / 3; // 结果是 1.0(先做整数除法得到 1,再转为 double)取余运算符 % 只能用于整数类型,不能用于浮点数。
最基本的赋值运算符是 =,将右侧的值赋给左侧的变量:
int x = 10;x = 20; // 将 x 的值更新为 20C++ 还提供了复合赋值运算符,将算术运算与赋值合并:
| 运算符 | 等价写法 | 示例 |
|---|---|---|
+= | x = x + y | x += 5; |
-= | x = x - y | x -= 3; |
*= | x = x * y | x *= 2; |
/= | x = x / y | x /= 4; |
%= | x = x % y | x %= 3; |
++ 和 -- 分别将变量的值加 1 和减 1。它们有前置和后置两种形式:
int a = 5;int b = ++a; // 前置自增:先将 a 加 1(a 变为 6),再将 a 的值赋给 b(b 为 6)int c = a++; // 后置自增:先将 a 的值赋给 c(c 为 6),再将 a 加 1(a 变为 7)在不需要使用表达式的值时(例如单独一行 i++;),前置和后置效果相同。但在表达式中使用时,需要注意求值顺序的差异。
{% hint style=“info” %} 对于内置类型,前置和后置的性能没有区别。但对于自定义类型(如迭代器),前置版本通常更高效,因为后置版本需要创建临时副本。养成优先使用前置形式的习惯是个好选择。 {% endhint %}
用于比较两个值,结果为 bool 类型(true 或 false):
| 运算符 | 含义 | 示例 | 结果 |
|---|---|---|---|
== | 等于 | 5 == 3 | false |
!= | 不等于 | 5 != 3 | true |
< | 小于 | 5 < 3 | false |
> | 大于 | 5 > 3 | true |
<= | 小于等于 | 5 <= 5 | true |
>= | 大于等于 | 3 >= 5 | false |
{% hint style=“warning” %}
注意区分赋值运算符 = 和相等比较运算符 ==。将 == 误写为 = 是初学者最常见的错误之一,而且编译器不一定会报错。
{% endhint %}
用于组合多个布尔表达式:
| 运算符 | 含义 | 示例 | 结果 |
|---|---|---|---|
&& | 逻辑与(AND) | true && false | false |
|| | 逻辑或(OR) | true || false | true |
! | 逻辑非(NOT) | !true | false |
逻辑与和逻辑或具有短路求值(Short-circuit Evaluation)特性:
&&:如果左侧为false,右侧不会被求值(因为结果必然是false)||:如果左侧为true,右侧不会被求值(因为结果必然是true)
int x = 0;if (x != 0 && 10 / x > 1) { // 当 x 为 0 时,10 / x 不会被执行,避免了除零错误}直接操作数据的二进制位,主要用于底层编程和性能优化场景:
| 运算符 | 含义 | 示例 | 结果 |
|---|---|---|---|
& | 按位与 | 0b1010 & 0b1100 | 0b1000 |
| | 按位或 | 0b1010 | 0b1100 | 0b1110 |
^ | 按位异或 | 0b1010 ^ 0b1100 | 0b0110 |
~ | 按位取反 | ~0b1010 | 所有位翻转 |
<< | 左移 | 1 << 3 | 8 |
>> | 右移 | 16 >> 2 | 4 |
初学阶段不需要深入掌握位运算,但应了解它们的存在。左移 n 位相当于乘以 2^n,右移 n 位相当于除以 2^n。
运算符优先级
Section titled “运算符优先级”当一个表达式中包含多个运算符时,C++ 按照优先级(Precedence)决定运算顺序。以下列出常用运算符的优先级(从高到低):
| 优先级 | 运算符 | 结合方向 |
|---|---|---|
| 1 | () | 左到右 |
| 2 | ++ --(后置)、!、~ | 右到左 |
| 3 | * / % | 左到右 |
| 4 | + - | 左到右 |
| 5 | << >> | 左到右 |
| 6 | < <= > >= | 左到右 |
| 7 | == != | 左到右 |
| 8 | & | 左到右 |
| 9 | ^ | 左到右 |
| 10 | | | 左到右 |
| 11 | && | 左到右 |
| 12 | || | 左到右 |
| 13 | = += -= 等 | 右到左 |
不必记住全部优先级。当不确定运算顺序时,使用括号明确优先级是最安全的做法:
// 不清楚优先级时,用括号消除歧义int result = (a + b) * (c - d);bool check = (x > 0) && (y < 10);