Namespaces
Variants

C++ Operator Precedence

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Operators
Operator precedence
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

以下表格列出了C++运算符的优先级和结合性。运算符按从上到下的顺序排列,优先级递减。 a b c 为操作数。

<td style="border-bottom-style
优先级 运算符 描述 结合性
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
  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 运算符优先级