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 sizeof[注 1]
co_await await-表达式 (C++20)
newnew[\] 动态内存分配
deletedelete[\] 动态内存释放
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_caststatic_castdynamic_castreinterpret_casttypeidsizeof...noexceptalignof 未包含在内,因为它们从不含糊。

一些运算符有替代拼写 (例如,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 起)

转自cppreference.cn

0 条评论

目前还没有评论...