C 运算符优先级
下表列出了 C 运算符的优先级和结合性。运算符按优先级从上到下排列。
优先级 | 运算符 | 描述 | 结合性 |
---|---|---|---|
1 | ++ --
|
后缀/后置自增和自减 | 从左到右 |
()
|
函数调用 | ||
[]
|
数组下标 | ||
.
|
结构体和联合体成员访问 | ||
->
|
通过指针访问结构体和联合体成员 | ||
(类型){列表}
|
复合字面量(C99) | ||
2 | ++ --
|
前缀自增和自减[注 1] | 从右到左 |
+ -
|
一元加号和减号 | ||
! ~
|
逻辑非和按位非 | ||
(类型)
|
强制转换 | ||
*
|
间接寻址(解引用) | ||
&
|
取地址 | ||
sizeof
|
大小-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++ 运算符优先级
|