C++ 运算符优先级
下表列出了 C++ 运算符的优先级和结合性。运算符按优先级从上到下排列。
优先级 | 运算符 | 描述 | 结合性 |
---|---|---|---|
1 | ::
|
作用域解析 | 左结合 → |
2 | a++ a-- |
后缀/后置递增和递减 | |
type() type{} |
函数风格强制转换 | ||
a()
|
函数调用 | ||
a[]
|
下标 | ||
. -> |
成员访问 | ||
3 | ++a --a |
前缀/前置递增和递减 | 右结合 ← |
+a -a |
一元/加号和减号 | ||
! ~ |
逻辑非 和 按位非 | ||
(type)
|
C 风格强制转换 | ||
*a
|
间接访问(解引用) | ||
&a
|
取地址 | ||
sizeof
|
sizeof[note 1] | ||
co_await | await 表达式 (C++20) | ||
new new[] |
动态内存分配 | ||
delete delete[] |
动态内存释放 | ||
4 | .* ->* |
指向成员的指针 | 左结合 → |
5 | a*b a/b a%b |
乘法、除法和取模 | |
6 | a+b a-b |
加法和减法 | |
7 | << >> |
按位/左移和右移 | |
8 | <=>
|
三元比较运算符 (自 C++20 起) | |
9 | < <= > >= |
对于 关系运算符 < 和 ≤ 和 > 和 ≥ 分别 | |
10 | == != |
对于 相等运算符 = 和 ≠ 分别 | |
11 | a&b
|
按位与 | |
12 | ^
|
按位异或(异或) | |
13 | |
|
按位或(或) | |
14 | &&
|
逻辑与 | |
15 | ||
|
逻辑或 | |
16 | a?b:c
|
三元条件[note 2] | 右结合 ← |
throw
|
抛出运算符 | ||
co_yield | yield 表达式 (C++20) | ||
=
|
直接赋值(默认情况下为 C++ 类提供) | ||
+= -= |
复合赋值 通过求和和求差 | ||
*= /= %= |
复合赋值 通过乘积、商和余数 | ||
<<= >>= |
复合赋值 通过按位左移和右移 | ||
&= ^= |= |
复合赋值 通过按位与、异或和或 | ||
17 | ,
|
逗号 | 左结合 → |
- ↑
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;,因为算术左移的优先级高于条件运算符。
[edit] 注意
优先级和结合性是编译时概念,与 求值顺序 无关,求值顺序是运行时概念。
标准本身没有指定优先级级别。它们是从语法推导出来的。
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 页面。
[edit] 另请参阅
常用运算符 | ||||||
---|---|---|---|---|---|---|
赋值 | 递增 递减 |
算术 | 逻辑 | 比较 | 成员 访问 |
其他 |
a = b |
++a |
+a |
!a |
a == b |
a[...] |
函数调用 |
a(...) | ||||||
逗号 | ||||||
a, b | ||||||
条件 | ||||||
a ? b : c | ||||||
特殊运算符 | ||||||
static_cast 将一种类型转换为另一种相关类型 |
C 文档 针对 C 运算符优先级
|