C 运算符优先级
下表列出了 C 运算符的优先级和结合性。运算符从上到下按优先级降序排列。
优先级 | 运算符 | 描述 | 结合性 |
---|---|---|---|
1 | ++ --
|
后缀/后置递增和递减 | 从左到右 |
()
|
函数调用 | ||
[]
|
数组下标 | ||
.
|
结构体和联合体成员访问 | ||
->
|
通过指针访问结构体和联合体成员 | ||
(type){list}
|
复合字面量(C99) | ||
2 | ++ --
|
前缀递增和递减[注 1] | 从右到左 |
+ -
|
一元加和减 | ||
! ~
|
逻辑非和按位非 | ||
(type)
|
类型转换 | ||
*
|
间接寻址(解引用) | ||
&
|
取地址 | ||
sizeof
|
Size-of[注 2] | ||
_Alignof
|
对齐要求(C11) | ||
3 | * / %
|
乘法、除法和取余 | 从左到右 |
4 | + -
|
加法和减法 | |
5 | << >>
|
按位左移和右移 | |
6 | < <=
|
对于关系运算符 < 和 ≤ 分别 | |
> >=
|
对于关系运算符 > 和 ≥ 分别 | ||
7 | == !=
|
对于关系运算符 = 和 ≠ 分别 | |
8 | &
|
按位与 | |
9 | ^
|
按位异或 | |
10 | |
|
按位或 | |
11 | &&
|
逻辑与 | |
12 | ||
|
逻辑或 | |
13 | ?:
|
三元条件[注 3] | 从右到左 |
14[注 4] | =
|
简单赋值 | |
+= -=
|
加法和减法赋值 | ||
*= /= %=
|
乘法、除法和取余赋值 | ||
<<= >>=
|
按位左移和右移赋值 | ||
&= ^= |=
|
按位与、异或和或赋值 | ||
15 | ,
|
逗号 | 从左到右 |
- ↑ 前缀
++
和--
的操作数不能是类型转换。此规则在语法上禁止了一些无论如何在语义上都无效的表达式。一些编译器忽略此规则并在语义上检测无效性。 - ↑
sizeof
的操作数不能是类型转换:表达式 sizeof (int) * p 被明确地解释为 (sizeof(int)) * p,而不是 sizeof((int)*p)。 - ↑ 条件运算符中间的表达式(在
?
和:
之间)被解析为好像用括号括起来一样:它相对于?:
的优先级被忽略。 - ↑ 赋值运算符的左操作数必须是一元(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++)。
[编辑] 参考文献
- 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 |
+a |
!a |
a == b |
a[b] |
a(...) |
C++ 文档 关于 C++ 运算符优先级
|