计算的优先级和顺序
C 运算符的优先级和结合性将影响表达式中操作数的分组和计算。 仅当存在优先级较高或较低的其他运算符时,运算符的优先级才有意义。 首先计算带优先级较高的运算符的表达式。 也可以通过“绑定”一词描述优先级。优先级较高的运算符被认为具有更严格的绑定。
下表总结了 C 运算符的优先级和结合性(计算操作数的顺序),并按照从最高优先级到最低优先级的顺序将其列出。 如果几个运算符一起出现,则其具有相同的优先级并且将根据其结合性对其进行计算。 以后缀运算符开头的部分描述了表中的运算符。 此部分的其余部分提供了有关优先级和结合性的常规信息。
C 运算符的优先级和关联性
符号 1
操作类型
结合性
[ ] ( ) . ->++ --(后缀)
表达式
从左到右
sizeof & * + - ~ !++ --(前缀)
一元
从右到左
typecasts
一元
从右到左
* / %
乘法
从左到右
+ -
加法
从左到右
<< >>
按位移动
从左到右
< > <= >=
关系
从左到右
== !=
相等
从左到右
&
按位“与”
从左到右
^
按位“异或”
从左到右
|
按位“与或”
从左到右
&&
逻辑“与”
从左到右
||
逻辑“或”
从左到右
? :
条件表达式
从右到左
= *= /= %=+= -= <<= >>= &=^= |=
简单和复合赋值 2
从右到左
,
顺序计算
从左到右
1 运算符按优先级的降序顺序列出。 如果多个运算符出现在同一行或一个组中,则它们具有相同的优先级。
2 所有简单的和复合的赋值运算符都有相同的优先级。
表达式可以包含优先级相同的多个运算符。 当多个具有相同级别的这类运算符出现在表达式中时,计算将根据该运算符的结合性按从右到左或从左至右的顺序来执行。 计算的方向不影响在相同级别包括多个乘法 (*)、加法 (+) 或二进制按位(&、| 或 ^)运算符的表达式的结果。 语言未定义运算的顺序。 如果编译器可以保证一致的结果,则编译器可以按任意顺序随意计算此类表达式。
只有顺序计算 (,)、逻辑“与”(&&)、逻辑“或” (||)、条件表达式 (? :) 和函数调用运算符构成序列点,因此,确保对其操作数的计算采用特定顺序。 函数调用运算符是一组紧跟函数标识符的圆括号。 确保顺序计算运算符 (,) 按从左到右的顺序计算其操作数。 (函数调用中的逗号运算符与顺序计算运算符不同,不提供任何此类保证。)有关详细信息,请参阅序列点。
逻辑运算符还确保按从左至右的顺序计算操作数。 但是,它们会计算确定表达式结果所需的最小数目的操作数。 这称作“短路”计算。 因此,无法计算表达式的一些操作数。 例如,在下面的表达式中
x && y++
仅当 y++ 为 true(非零)时,才计算第二操作数 (x)。 因此,如果 y 为 false (0),则 x 不增加。
示例
以下列表显示编译器如何自动绑定多个示例表达式:
表达式
自动绑定
a & b || c
(a & b) || c
a = b || c
a = (b || c)
q && r || s--
(q && r) || s--
在第一个表达式中,按位“与”运算符 (&) 的优先级高于逻辑“或”运算符 (||) 的优先级,因此,a & b 构成了逻辑“或”运算的第一操作数。
在第二个表达式中,逻辑“或”运算符 (||) 的优先级高于简单赋值运算符 (=) 的优先级,因此,b || c 在赋值中分组为右操作数。 请注意,赋给 a 的值为 0 或 1。
第三个表达式显示可能会生成意外结果的格式正确的表达式。 逻辑“与”运算符 (&&) 的优先级高于逻辑“或”运算符 (||) 的优先级,因此,将 q && r 分组为操作数。 由于逻辑运算符确保按从左到右的顺序计算操作数,因此 q && r 先于 s-- 被计算。 但是,如果 q && r 计算的结果为非零值,则不计算 s--,并且 s 不会减少。 如果 s 未减少会导致程序出现问题,则 s-- 应显示为表达式的第一操作数,或者在单独的运算中应减少 s。
以下表达式是非法的并会在编译时生成诊断消息:
非法表达式
默认分组
p == 0 ? p += 1: p += 2
( p == 0 ? p += 1 : p ) += 2
在此表达式中,相等运算符 (==) 的优先级最高,因此,将 p == 0 分组为操作数。 条件表达式运算符 (? :) 具有下一个最高级别的优先级。 其第一操作数是 p == 0,第二操作数是 p += 1。 但是,条件表达式运算符的最后一个操作数被视为 p 而不是 p += 2,因为与复合赋值运算符相比,p 的匹配项将更紧密地绑定到条件表达式运算符。 由于 += 2 没有左操作数,因此发生语法错误。 您应使用括号以防止此类错误发生并生成可读性更高的代码。 例如,可以按如下所示使用括号来更正和阐明前面的示例:
( p == 0 ) ? ( p += 1 ) : ( p += 2 )
请参阅
C 运算符