从根源解释++i与i++

文章详细解释了C/C++中前置递增运算符++i和后置递增运算符i++的区别,通过两个示例展示了它们在代码执行中的不同顺序和效果,并使用VS2017的反汇编来进一步验证和解释这些差异。重点在于理解这两个运算符的结合及顺序对变量值的影响。
摘要由CSDN通过智能技术生成

一、++i与i++的规则

初学编程的人,对于++i与i++老是傻傻分不清,甚至有一定开发经验的人也会栽倒在这两个表达式上。大家看下面两个例子:

例1:代码如下,这是个比较简单的例子,对于表达式j=i++;等同于"j=i;i=i+1;",而对于表达式k=i++;等同于"i=i+1;k=i;",所以最后的执行结果是:i=2,j=0,k=2。

int i=0,j,k;
j=i++;
k=++i;
printf("i=%d,j=%d,k=%d\n",i,j,k);

例2:上例的用法很常见,这个例子就有点麻烦了,如果不能从根本上理解++i和i++,可能就会出错了。

int i=0,j;
j=(i++)+(++i)+(i++)+(++i)+(i++)+(++i);
printf("%d,%d\n",i,j);

‘'j=(i++)+(++i)+(i++)+(++i)+(i++)+(++i);"中有3组“++i”,有3组“i++”。所以代码等同于

int i=0,j;
// 先处理++i
i=i+1;
i=i+1;
i=i+1;
//执行语句,++i和i++都替换成i
j=i+i+i+i+i+i;
// 处理i++
i=i+1;
i=i+1;
i=i+1;
printf("i=%d,j=%d\n",i,j);

所以,该例最终结果是"i=6,j=18"

从上述例子中我们假设"语句A"含有n个“++i”和m个“i++”;则"语句A"就等同于

// 执行n次i=i+1
i=i+1;
.....
//将"语句A"中的++i和i++都替换成i
语句A
// 执行m次i=i+1
i=i+1;
.....

二、通过反汇编语言验证

我们使用Vs2017的反汇编验证一下例1

j = i++;
/*等同于j=i*/
00007FF65B8E5771  mov         eax,dword ptr [i]  // 将变量i的数据导入寄存器eax
00007FF65B8E5774  mov         dword ptr [j],eax  // 将寄存器eax的数据导出到变量j
/*等同于i=i+1*/                                         
00007FF65B8E5777  mov         eax,dword ptr [i]  // 将i的数据导入寄存器eax
00007FF65B8E577A  inc         eax                // 将寄存器eax累加1
00007FF65B8E577C  mov         dword ptr [i],eax  // 将寄存器eax的数据导出到变量i


k = ++i;
/*等同于i=i+1*/
00007FF65B8E577F  mov         eax,dword ptr [i]   // 将i的数据导入寄存器eax
00007FF65B8E5782  inc         eax                 // 将寄存器eax累加1
00007FF65B8E5784  mov         dword ptr [i],eax   // 将寄存器eax的数据导出到变量i
/*等同于k=i*/
00007FF65B8E5787  mov         eax,dword ptr [i]   // 将变量i的数据导入寄存器eax
00007FF65B8E578A  mov         dword ptr [k],eax   // 将寄存器eax的数据导出到变量k

我们使用Vs2017的反汇编验证一下例2

    j = (i++)+ (++i)+(i++) + (++i) + (i++) + (++i) ;
/*等同于i=i+1*/
00007FF65CD35771  mov         eax,dword ptr [i]  
00007FF65CD35774  inc         eax  
00007FF65CD35776  mov         dword ptr [i],eax  
/*等同于i=i+1*/
00007FF65CD35779  mov         eax,dword ptr [i]  
00007FF65CD3577C  inc         eax  
00007FF65CD3577E  mov         dword ptr [i],eax  
/*等同于i=i+1*/
00007FF65CD35781  mov         eax,dword ptr [i]  
00007FF65CD35784  inc         eax  
00007FF65CD35786  mov         dword ptr [i],eax  
/*等同于j=i+i+i+i+i+i;*/
00007FF65CD35789  mov         eax,dword ptr [i]  // 将i的数据导入寄存器eax
00007FF65CD3578C  mov         ecx,dword ptr [i]  // 将i的数据导入寄存器ecx
00007FF65CD3578F  add         ecx,eax            // ecx=ecx+eax=i+i
00007FF65CD35791  mov         eax,ecx            // eax=ecx=i+i
00007FF65CD35793  add         eax,dword ptr [i]  // eax=eax+i
00007FF65CD35796  add         eax,dword ptr [i]  // eax=eax+i
00007FF65CD35799  add         eax,dword ptr [i]  // eax=eax+i
00007FF65CD3579C  add         eax,dword ptr [i]  // eax=eax+i
00007FF65CD3579F  mov         dword ptr [j],eax  // 将寄存器eax的数据导出到变量j
/*等同于i=i+1*/
00007FF65CD357A2  mov         eax,dword ptr [i]  
00007FF65CD357A5  inc         eax  
00007FF65CD357A7  mov         dword ptr [i],eax  
/*等同于i=i+1*/
00007FF65CD357AA  mov         eax,dword ptr [i]  
00007FF65CD357AD  inc         eax  
00007FF65CD357AF  mov         dword ptr [i],eax  
/*等同于i=i+1*/
00007FF65CD357B2  mov         eax,dword ptr [i]  
00007FF65CD357B5  inc         eax  
00007FF65CD357B7  mov         dword ptr [i],eax  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿来不是梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值