自增自减运算符的优先级为2(仅低于中小括号,成员对象选择符,成员指针选择符),右结合性。
2.7.1 前置与后置的区别
#include<stdio.h>
int main()
{
//后置
int i = 0, j;
j = (i++) + (i++) + (i++);
printf("j=%d\ni=%d\n",j,i);
//前置
i = 0;
j = (++i) + (++i) + (++i);
printf("j=%d\ni=%d\n", j, i);
}
对于以上代码,执行结果应该是怎样的呢?
对于后置情况来说:由于后置中的先用后变中的“变”只有在遇到逗号、分号等表示该执行单位结束的运算符时才会自增自减。所以此处的表达式实际上等同于j=i+i+i;i=i+1;i=i+1;i=i+1;
对于前置情况来说:C语言的标准没有准确说明,因此其值因编译器而定。对于VS来说,其等同于i=i+1;i=i+1;i=i+1;j=i+i+i;也就说先执行自增自减再执行其他运算。
那么,把上面的括号去掉会怎么样呢?
#include<stdio.h>
int main()
{
//后置
int i = 0, j;
j = i++ + i++ + i++;
printf("j=%d\ni=%d\n",j,i);
//前置
i = 0;
j = ++i++ + i++ + i;
printf("j=%d\ni=%d\n", j, i);
int i=0, j=0;
i++ + j;
i++++ + j;
}
C语言有一个贪心策略,就是说当有多个符号在一起的时候,会从左往右尽可能将更多的符号组成一个运算符。
因此对于后置来说,其表达式等同于j = (i++) + (i++) + (i++); 对于前置来说,其表达式等同于j =((++i)++)+(i++)+i;因此该表达式格式也是错误的,因为自增自减不能作为左值,也就是不能被赋值。
2.7.2 自增自减与逗号表达式
#include<stdio.h>
int main()
{
//后置
int i = 0, j;
j = (i++,i++,i++);
printf("j=%d\ni=%d\n", j, i);
//前置
i = 0;
j = (++i,++i,++i);
printf("j=%d\ni=%d\n", j, i);
}
对于后置来说:由于后置是先用后变,而自增自减运算符的优先级又低于逗号运算符,所以执行顺序为i=i+1;i=i+1;j=;i=i+1;
对于前置来说:由于前置是先变后用,且自增自减运算在遇到以逗号或分号的单位执行结束运算符时就会"变",因此执行顺序为i=i+1,i=i+1,i=i+1,j=i;
2.7.3 自增自减与逻辑运算符
#include<stdio.h>
int main()
{
//前置
int i = 0,j;
j = ++i || --i && i--;
printf("j=%d\ni=%d\n", j, i);
//后置
i = 0;
j = i++ || --i && i--;
printf("j=%d\ni=%d\n", j, i);
}
由于自增自减运算符优先级高于逻辑运算符,且逻辑运算符有短路特性(对于逻辑或,只要其左侧表达式为真则结果为真,其右侧表达式不再执行;对于逻辑与,只要其左侧表达式为假则结果为假,其右侧表达式不在执行),因此执行顺序为i=i+1;j=i;逻辑或右侧的表达式不在执行。
2.7.4 自增自减与函数实参
#include<stdio.h>
void fun(int i, int j, int k)
{
printf("i=%d\n", i);
printf("j=%d\n", j);
printf("k=%d\n", k);
printf("\n");
}
void fun1(int i, int j, int k,int z)
{
printf("i=%d\n", i);
printf("j=%d\n", j);
printf("k=%d\n", k);
printf("z=%d\n", z);
}
int main()
{
int x = 0;
fun(x, ++x, --x);
fun1(--x, ++x, x, ++x);
x = 0;
fun(x, x++, x--);
}
由于函数执行时其实参值是按照从右向左的顺序入栈的,因此对于函数实参中的自增自减运算要特别注意!
对于前置来说:只有执行单位结束其值才会变,再结合函数实参的入栈方式,所以fun(x, ++x, --x);的执行顺序是:k=x;j=x;i=x;x=x-1;x=x+1;x=x;同理可知fun1(–x, ++x, x, ++x);的执行顺序。
对于后置来说:其就直接先用后变就可以,因此fun(x, x++, x–);执行顺序为:k=x;x=x-1;j=x;x=x+1;i=x;x=x;