【转载】运算符的优先级
补充 运算符的优先级
C 语言中有数量众多的运算符,其优先级分 15 个级别。
和其他语言相比,C 语言的优先级别还是非常多的。很多 C 的参考书,都像表 3-5 这样
记载了运算符优先级的内容。
表3-5 运算符优先顺序表(摘录于K&R p.65)
运算符 |
结合顺序 |
() [] -> . |
从左往右 |
! ~ ++ -- + - * & (type) sizeof |
从右往左 |
* / % |
从左往右 |
+ - |
从左往右 |
<< >> |
从左往右 |
< <= > >= |
从左往右 |
== != |
从左往右 |
& |
从左往右 |
^ |
从左往右 |
| |
从左往右 |
&& |
从左往右 |
|| |
从左往右 |
?: |
从右往左 |
= += -= *= /= %= &= ^= |= <<= >>= |
从右往左 |
, |
从左往右 |
注:进行单目运算的+、-、和*的优先级高于进行双目运算的+、-、和*。
其中,对于优先级“最高”的是(),有相当多的人抱有以下观点:
当需要改变原本语法规定的优先级、强制地设定自己需要的优先级的时候,
程序员们会使用()。因此,()具有最高的优先级是理所当然的。
这是一种误解。
如果()可以这样理解,还有必要特地将它记载在优先级的表中吗?
这个表中的(),(正如 K&R 中记述的那样)代表着调用函数的运算符。此时的优先级
是指,对于 func(a, b)这样的表达式,func 和()之间的关联强度。
此外,我们经常看到类似于下面这样的编码:
*p++;
究竟是对 p 进行加法运算?还是对 p 所指向的对象(*p)进行加法运算?关于这一
点,很多书是这样解释的:
尽管*和++的优先级相同,但由于连接规则是从右往左,所以 p 和++先进行连
接。因此,被进行加法运算的不是*p,而是 p。
就连 K&R 自身也是这样说明的。其实这种说法不太恰当。
根据 BNF(Backus-Naur Form)规则,C 语言标准定义了语法规则,其中也包含了运算
符的语法规则。
关于 BNF,由于超出了本书的范围,在此就不做说明了。根据 BNF,后置的++比前置
的++和*等运算符的优先级高,()和[]的优先级相同*。
* 参照 K&R 中 的标准 6.3.2 和 6.3.3。
也就是说,关于*p++的运算符优先级,
后置的++比*的优先级高,因此,被进行加法运算的不是*p,而是 p。从语法上来看,这种说法才是比较合理的。