Namespaces
Variants

C Operator Precedence

From cppreference.net

以下表格按优先级从高到低列出了C语言运算符的优先级和结合性。

优先级 运算符 描述 结合性
1 ++ -- 后缀自增与自减 从左到右
() 函数调用
[] 数组下标
. 结构体与联合体成员访问
-> 通过指针访问结构体与联合体成员
( type ){ list } 复合字面量 (C99)
2 ++ -- 前缀自增与自减 [注 1] 从右到左
+ - 一元加与减
! ~ 逻辑非与按位取反
( type ) 强制类型转换
* 间接寻址(解引用)
& 取地址
sizeof 取大小 [注 2]
_Alignof 对齐要求 (C11)
3 * / % 乘法、除法与取模 从左到右
4 + - 加法与减法
5 << >> 按位左移与右移
6 < <= 分别对应关系运算符 < 和 ≤
> >= 分别对应关系运算符 > 和 ≥
7 == != 分别对应关系运算符 = 和 ≠
8 & 按位与
9 ^ 按位异或
10 | 按位或
11 && 逻辑与
12 || 逻辑或
13 ?: 三元条件运算符 [注 3] 从右到左
14 [注 4] = 简单赋值
+= -= 复合赋值:和与差
*= /= %= 复合赋值:积、商与余数
<<= >>= 复合赋值:按位左移与右移
&= ^= |= 复合赋值:按位与、异或、或
15 , 逗号运算符 从左到右
  1. 前缀 ++ -- 的操作数不能是类型转换。该规则在语法层面禁止了某些语义上本就无效的表达式。部分编译器会忽略此规则并通过语义分析检测无效性。
  2. sizeof 的操作数不能是类型转换:表达式 sizeof ( int ) * p 明确解释为 ( sizeof ( int ) ) * p ,而非 sizeof ( ( int ) * p )
  3. 条件运算符中间表达式(位于 ? : 之间)的解析方式如同被括号包围:其与 ?: 的优先级关系会被忽略。
  4. 赋值运算符的左操作数必须是一元(二级非转换)表达式。该规则在语法层面禁止了某些语义上本就无效的表达式。许多编译器会忽略此规则并通过语义分析检测无效性。例如, e = a < d ? a ++ : a = d 因该规则无法被解析。然而许多编译器会忽略此规则,将其解析为 e = ( ( ( a < d ) ? ( a ++ ) : a ) = d ) ,随后因语义无效而报错。

在解析表达式时,位于较高行的运算符将(如同通过括号)比位于较低行的运算符更紧密地绑定其参数。例如,表达式 * p ++ 会被解析为 * ( p ++ ) ,而非 ( * p ) ++

处于同一单元格中的运算符(一个单元格中可能列出多行运算符)具有相同的优先级,按给定方向进行求值。例如,表达式 a = b = c 会被解析为 a = ( b = c ) ,而非 ( a = b ) = c ,这是因为赋值运算符具有从右到左的结合性。

注释

优先级和结合性独立于 求值顺序

标准本身并未规定优先级层级。它们是从语法中推导得出的。

在C++中,条件运算符与赋值运算符具有相同的优先级,且前缀 ++ -- 以及赋值运算符对其操作数没有限制。

为单目运算符指定结合性其实是冗余的,此处仅为表述完整性而展示:单目前缀运算符始终从右向左结合( sizeof ++* p sizeof ( ++ ( * p ) ) ),而单目后缀运算符始终从左向右结合( a [ 1 ] [ 2 ] ++ ( ( a [ 1 ] ) [ 2 ] ) ++ )。需注意结合性对成员访问运算符同样具有意义,尽管它们被归为单目后缀运算符: a. b ++ 会被解析为 ( a. b ) ++ 而非 a. ( b ++ )

参考文献

  • C17 标准 (ISO/IEC 9899:2018):
  • A.2.1 表达式
  • C11 标准 (ISO/IEC 9899:2011):
  • A.2.1 表达式
  • C99标准(ISO/IEC 9899:1999):
  • A.2.1 表达式
  • C89/C90 标准 (ISO/IEC 9899:1990):
  • A.1.2.1 表达式

参见

求值顺序 在运行时对运算符操作数的执行顺序。

常用运算符
赋值 自增
自减
算术 逻辑 比较 成员
访问
其他

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 - > b
a. b

a ( ... )
a, b
( type ) a
a ? b : c
sizeof


_Alignof
(C11起)
(C23前)

alignof
(C23起)

C++ 文档 关于 C++ operator precedence