Namespaces
Variants

C++ 运算符优先级

来自 zh.cppreference.net
 
 
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 取地址
^^a 反射运算符 (自 C++26)
sizeof 大小[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 逗号 从左到右 →
  1. ↑ 的操作数sizeof不能是 C 风格类型转换:表达式 sizeof (int) * p 被明确解析为 (sizeof(int)) * p,而非 sizeof((int)*p)。
  2. ↑ 条件运算符中间(? 和 : 之间)的表达式被视为加了括号来解析:其相对于 ?: 的优先级被忽略。

解析表达式时,上表中某行中列出的具有特定优先级的运算符将比其下方行中列出的具有较低优先级的运算符更紧密地(如同通过括号)绑定到其参数。例如,表达式 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 + = b
a - = b
a * = b
a / = b
a % = b
a & = b
a | = b
a ^ = b
a <<= b
a >>= b

++ a
-- a
a ++
a --

+ a
- a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

! a
a && b
a || b

a == b
a ! = b
a < b
a > b
a <= b
a >= b
a <=> b

a [ ... ]
* a
& a
a - > b
a. b
a - > * b
a. * b

函数调用

a ( ... )
逗号

a, b
条件

a ? b : c
特殊运算符

static_cast 将一种类型转换为另一种相关类型
dynamic_cast 在继承层次结构内进行转换
const_cast 添加或移除 cv 限定符
reinterpret_cast 将类型转换为不相关类型
C风格转换 通过混合使用 static_cast 、 const_cast 和 reinterpret_cast 将一种类型转换为另一种类型
new 创建具有动态存储期的对象
delete 销毁先前由 new 表达式创建的对象并释放获取的内存区域
sizeof 查询类型的大小
sizeof... 查询 参数包 的大小 (C++11 起)
typeid 查询类型的类型信息
noexcept 检查表达式是否能抛出异常 (C++11 起)
alignof 查询类型的对齐要求 (C++11 起)

C 文档 关于 C 运算符优先级