在C语言中,运算符优先级决定了表达式中运算符的求值顺序。下面是一些常见的运算符及其优先级,按照从高到低排序:
- 后缀(如
(),[],->,., 表达式后置的++和--) - 前缀(如
++,--, 单目运算符如+,-,!,~, 一元*(解引用),&(取地址),sizeof,(type)(类型转换)) - 乘法性运算符 (
*,/,%) - 加法性运算符 (
+,-) - 移位运算符 (
<<,>>) - 关系运算符 (
<,<=,>,>=) - 等等运算符 (
==,!=) - 按位与 (
&) - 按位异或 (
^) - 按位或 (
|) - 逻辑与 (
&&) - 逻辑或 (
||) - 条件运算符 (
?:) - 赋值运算符 (
=,+=,-=,*=,/=,%=,<<=,>>=,&=,^=,|=) - 逗号运算符 (
,)
请注意,前置自增 (++) 和前置自减 (--) 属于前缀运算符的一部分,而后置自增和后置自减则属于后缀运算符。
当有相同优先级的运算符时,它们的结合性决定了计算的方向。大多数二元运算符是从左到右结合,而赋值运算符和条件运算符是从右到左结合。后缀运算符总是比前缀运算符先结合。
因此,在考虑 ++ 运算符和取地址运算符 & 的情况下,前置 ++ 是一个前缀运算符,它的优先级高于取地址运算符 &;而后置 ++ 则是后缀运算符,它同样具有较高的优先级,但其语义是在整个表达式求值之后才增加变量的值。所以如果要同时使用 & 和 ++,你可能需要使用括号来明确表达式的意图。例如:
int a = 5;
int *p;
// 如果想要先自增再取址:
p = &(++a);
// 如果想要先取址:
p = &a;
(*p)++;
每个编译器可能会对一些细节有不同的处理方式,所以在不确定的时候最好使用括号来明确优先级。