当一个表达式包含多样操作符时,操作符的优先级控制着单个操作符求值的顺序。例如:表达式x+y*z按照x+(y*z)求值,因为“*”操作符比“+”操作符有更高的优先级。这和数学运算中的先乘除后加减是一致的。表1总结了所有操作符从高到低的优先级顺序。
表1 操作符从高到低的优先级顺序
类别 | 操作符 |
初级操作符 | (x) x.y f(x) a[x] x++ x-- new type of sizeof checked unchecked |
一元操作符 | + - ! ~ ++x --x (T)x |
乘、除操作符 | * / % |
加减操作符 | + - |
移位操作符 | << >> |
关系操作符 | < > <= >= is as |
等式操作符 | == != |
逻辑与操作符 | & |
逻辑异或操作符 | ^ |
逻辑或操作符 | | |
条件与操作符 | && |
条件或操作符 | || |
条件操作符 | ?: |
赋值操作符 | = *= /= %= += -= <<= >>= &= ^= |= |
当一个操作数出现在两个有相同优先级的操作符之间时,操作符按照出现的顺序由左到右执行。
除了赋值的操作符,所有的二进制的操作符都是左结合(left-associative)的,也就是说,操作按照从左向右的顺序执行。例如:x+y+z按(x+y)+z进行求值。
赋值操作符和条件操作符(?:)按照右接合(right-associative)的原则,即操作按照从右向左的顺序执行。如:x=y=z按照x=(y=z)进行求值。
建议在写表达式的时候,如果无法确定操作符的有效顺序,则尽量采用括号来保证运算的顺序,这样也使得程序一目了然,而且自己在编程时能够思路清晰。
原文地址:http://www.shangxueba.com/jingyan/96326.html
C操作符的优先级和关联规则
操作符 | 关联规则 |
关联操作符 () [] -> . | 从左到右 |
一元操作符 ! – ++ -- + - (type) * & sizeof | 从右到左 |
乘法和除法 * / % | 从左到右 |
加法和减法 + - | 从左到右 |
移位操作符 << >> | 从左到右 |
关系操作符 < <= > >= | 从左到右 |
相等比较 == != | 从左到右 |
位操作符 & | 从左到右 |
位操作符 ^ | 从左到右 |
位操作符 | | 从左到右 |
逻辑操作符 && | 从左到右 |
逻辑操作符 || | 从左到右 |
条件操作符 ?: | 从右到左 |
赋值操作符 = += -= *= /= | 从右到左 |
逗号 , | 从左到右 |
1.优先级决定操作符与操作数的绑定顺序
2.操作符是按照优先级从高到低顺序与操作数绑定的
3.在确定两个操作符的相对优先级时,首先从这个表格中找到这两个操作符,表中排在上面的比下面的优先级高;当这两个操作符出现在同一行中时,需要根据“关联规则“来决定它们的优先级;如果是”从左到右“,则左边的操作符有更高的优先级;如果是”从右到左“,则右边的操作符有更高的优先级
4.尽量避免优先级不清的表达式写法,用括号明确区分表达式的计算过程
例:
(1) *p++的计算顺序为(*(p++)):因为*和++属于同一行,所以看其关联规则为”从右到左“,因此操作数先与++绑定,再与*绑定
(2) x || !y && z的计算顺序为(x || ((!y) && z)):因为操作符的优先级顺序为! && ||,因此首先!与y绑定,其次&&与(!y)和z绑定,最后||与x和 ((!y) && z)绑定
(3) x | y & z的计算顺序为(x | (y & z))