命名空间
变体
操作

C 运算符优先级

来自 cppreference.cn
< c‎ | 语言

下表列出了 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. 赋值运算符的左操作数必须是一元(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 ++*psizeof(++(*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++ 运算符优先级