命名空间
变体
操作

C++ 运算符优先级

来自 cppreference.cn
< cpp‎ | language
 
 
C++ 语言
 
 

下表列出了 C++ 运算符的优先级和结合性。 运算符从上到下,按优先级降序排列。 abc 是操作数。

优先级 运算符 描述 结合性
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 逗号 从左到右 →
  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 ++*pdelete(++(*p))),一元后缀运算符始终从左到右结合(a[1][2]++((a[1])[2])++)。 请注意,结合性对于成员访问运算符是有意义的,即使它们与一元后缀运算符分组在一起:a.b++ 被解析为 (a.b)++,而不是 a.(b++)

运算符优先级不受 运算符重载 的影响。 例如,std::cout << a ? b : c; 解析为 (std::cout << a) ? b : c;,因为算术左移的优先级高于条件运算符。

[编辑] 注释

优先级和结合性是编译时概念,独立于 求值顺序,后者是运行时概念。

标准本身没有指定优先级级别。 它们是从语法中派生出来的。

const_caststatic_castdynamic_castreinterpret_casttypeidsizeof...noexceptalignof 未包含在内,因为它们永远不会引起歧义。

某些运算符具有替代拼写(例如,and 代表 &&or 代表 ||not 代表 ! 等)。

在 C 语言中,三元条件运算符的优先级高于赋值运算符。 因此,表达式 e = a < d ? a++ : a = d 在 C++ 中被解析为 e = ((a < d) ? (a++) : (a = d)),但在 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_castconst_castreinterpret_cast 将一种类型转换为另一种类型
new 创建具有动态存储期的对象
delete 析构先前由 new 表达式创建的对象并释放获得的内存区域
sizeof 查询类型的大小
sizeof... 查询形参包的大小 (自 C++11 起)
typeid 查询类型的类型信息
noexcept 检查表达式是否可能抛出异常 (自 C++11 起)
alignof 查询类型的对齐要求 (自 C++11 起)

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