C++ 运算符优先级
下表列出了 C++ 运算符的优先级和结合性。 运算符从上到下,按优先级降序排列。 a、b 和 c 是操作数。
优先级 | 运算符 | 描述 | 结合性 |
---|---|---|---|
1 | a::b | 作用域解析 | 从左到右 → |
2 | a++ a-- | 后缀/后置 递增和递减 | |
type (a) type {a} |
函数式转型 | ||
a() | 函数调用 | ||
a[] | 下标 | ||
a.b a->b | 成员访问 | ||
3 | ++a --a | 前缀/前置 递增和递减 | 从右到左 ← |
+a -a | 一元 加号和减号 | ||
!a ~a | 逻辑非 和 按位非 | ||
(type )a
|
C 风格转型 | ||
*a | 间接引用(解引用) | ||
&a | 取地址 | ||
sizeof
|
Size-of[注 1] | ||
co_await | await 表达式 (C++20) | ||
new – new[] |
动态内存分配 | ||
delete – delete[] |
动态内存释放 | ||
4 | a.*b a->*b | 指向成员的指针 | 从左到右 → |
5 | a * b a / b a % b | 乘法、除法和取余 | |
6 | a + b a - b | 加法和减法 | |
7 | a << b a >> b | 按位 左移和右移 | |
8 | a <=> b | 三路比较运算符 (自 C++20 起) | |
9 | a < b a <= b a > b a >= b | 用于 关系运算符 < 和 <= 以及 > 和 >= 分别 | |
10 | a == b a != b | 用于 相等运算符 = 和 != 分别 | |
11 | a & b | 按位与 | |
12 | a ^ b | 按位异或(互斥或) | |
13 | a | b | 按位或(包含或) | |
14 | a && b | 逻辑与 | |
15 | a || b | 逻辑或 | |
16 | a ? b : c | 三元条件[注 2] | 从右到左 ← |
throw
|
throw 运算符 | ||
co_yield | yield 表达式 (C++20) | ||
a = b | 直接赋值(C++ 类默认提供) | ||
a += b a -= b | 复合赋值(加法和减法) | ||
a *= b a /= b a %= b | 复合赋值(乘积、商和余数) | ||
a <<= b a >>= b | 复合赋值(按位左移和右移) | ||
a &= b a ^= b a |= b | 复合赋值(按位与、异或和或) | ||
17 | a, b | 逗号 | 从左到右 → |
- ↑ sizeof 的操作数不能是 C 风格类型转型:表达式 sizeof (int) * p 被明确地解释为 (sizeof(int)) * p,而不是 sizeof((int)*p)。
- ↑ 条件运算符中间的表达式(在
?
和:
之间)被解析为如同带括号:它相对于?:
的优先级被忽略。
当解析表达式时,优先级表中某一行列出的运算符将比优先级较低的、更低行列出的任何运算符更紧密地(如同用括号括起来一样)绑定到其参数。 例如,表达式 std::cout << a & b 和 *p++ 被解析为 (std::cout << a) & b 和 *(p++),而不是 std::cout << (a & b) 或 (*p)++。
具有相同优先级的运算符按照其结合性的方向绑定到其参数。 例如,表达式 a = b = c 被解析为 a = (b = c),而不是 (a = b) = c,因为赋值运算符具有从右到左的结合性;但 a + b - c 被解析为 (a + b) - c,而不是 a + (b - c),因为加法和减法运算符具有从左到右的结合性。
结合性规范对于一元运算符是多余的,仅为完整性而显示:一元前缀运算符始终从右到左结合(delete ++*p 是 delete(++(*p))),一元后缀运算符始终从左到右结合(a[1][2]++ 是 ((a[1])[2])++)。 请注意,结合性对于成员访问运算符是有意义的,即使它们与一元后缀运算符分组在一起:a.b++ 被解析为 (a.b)++,而不是 a.(b++)。
运算符优先级不受 运算符重载 的影响。 例如,std::cout << a ? b : c; 解析为 (std::cout << a) ? b : c;,因为算术左移的优先级高于条件运算符。
[编辑] 注释
优先级和结合性是编译时概念,独立于 求值顺序,后者是运行时概念。
标准本身没有指定优先级级别。 它们是从语法中派生出来的。
const_cast
、static_cast
、dynamic_cast
、reinterpret_cast
、typeid
、sizeof...
、noexcept
和 alignof
未包含在内,因为它们永远不会引起歧义。
某些运算符具有替代拼写(例如,and 代表 &&,or 代表 ||,not 代表 ! 等)。
在 C 语言中,三元条件运算符的优先级高于赋值运算符。 因此,表达式 e = a < d ? a++ : a = d 在 C++ 中被解析为 e = ((a < d) ? (a++) : (a = d)),但在 C 语言中由于语法或语义约束而编译失败。 有关详细信息,请参阅相应的 C 语言页面。
[编辑] 参见
常用运算符 | ||||||
---|---|---|---|---|---|---|
赋值 | 递增 递减 |
算术 | 逻辑 | 比较 | 成员 访问 |
其他 |
a = b |
++a |
+a |
!a |
a == b |
a[...] |
函数调用 a(...) |
逗号 a, b | ||||||
条件 a ? b : c | ||||||
特殊运算符 | ||||||
static_cast 将一种类型转换为另一种相关类型 |
C 文档 关于 C 运算符优先级
|