Namespaces
Variants

C 运算符优先级

来自 zh.cppreference.net
< c | 语言

下表列出了 C 运算符的优先级和结合性。运算符按优先级从高到低自上而下排列。

优先级 运算符 描述 结合性
1 ++ -- 后缀/后置自增与自减 从左到右
() 函数调用
[] 数组下标
. 结构体和联合体成员访问
-> 通过指针的结构体和联合体成员访问
(type){list} 复合字面量(C99)
2 ++ -- 前缀/前递自增与自减[1] 从右到左
+ - 一元正负号
! ~ 逻辑非与按位取反
(type) 强制类型转换(转型)
* 间接访问(解引用)
& 取地址
sizeof 大小(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. ↑ 赋值运算符的左操作数必须是一元(级别 2 的非转型)表达式。此规则在语法上禁止了某些在语义上本就不合法的表达式。许多编译器忽略此规则,而是从语义上检测错误。例如,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++)。

参考文献

  • C23 标准 (ISO/IEC 9899:2024):
  • A.3.1 表达式
  • 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++ 运算符优先级