C语言中的自增自减问题

自增自减运算符的优先级为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;
请添加图片描述

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值