C 运算符优先级
C
编译器支持
语言
头文件
类型支持
程序工具
可变参数函数支持
错误处理
动态内存管理
字符串库
算法
数值
日期和时间工具
输入/输出支持
本地化支持
并发支持 (C11)
技术规范
符号索引
[编辑] C 语言
基本概念
关键字
预处理器
语句
表达式
初始化
声明
函数
杂项
C 的历史
技术规范
[编辑] 表达式
通用
值类别
求值顺序和顺序点
常量表达式
隐式转换
泛型选择 (C11)
常量和字面量
整型常量
浮点常量
字符常量
true/false(C23)
nullptr(C23)
字符串字面量
复合字面量 (C99)
运算符
运算符优先级
成员访问和间接寻址
逻辑运算符
比较运算符
算术运算符
赋值运算符
递增和递减
函数调用、逗号、条件运算符
sizeof
_Alignof(C11*)
类型转换运算符
[编辑]
下表列出了 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 = ba += ba -= ba *= ba /= ba %= ba &= ba |= ba ^= ba <<= ba >>= b
++a
--aa++a--
+a
-aa + ba - ba * ba / ba % b~aa & ba | ba ^ ba << ba >> b
!aa && ba || b
a == ba != ba < ba > ba <= ba >= b
a[b]
*a
&aa->ba.b
a(...)a, b
(type) aa ? b : c
sizeof
_Alignof(自 C11 起)(截至 C23)
alignof(自 C23 起)
C++ 文档 关于 C++ 运算符优先级