C++ Operator Precedence
以下表格列出了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
|
取大小 [注 1] | ||
| co_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
|
抛出运算符 | ||
| co_yield | yield表达式 (C++20) | ||
| a = b | <td style="border-bottom-style
- ↑ 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语言中无法通过编译。具体细节请参阅对应的C语言页面。
参见
| 常用运算符 | ||||||
|---|---|---|---|---|---|---|
| 赋值 |
自增
自减 |
算术 | 逻辑 | 比较 |
成员
访问 |
其他 |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
...
]
|
函数调用
a ( ... ) |
|
逗号
a, b |
||||||
|
条件
a ? b : c |
||||||
| 特殊运算符 | ||||||
|
static_cast
将一种类型转换为另一种相关类型
|
||||||
|
C 文档
关于
C 运算符优先级
|