关于“++i”自增自减在C和java中区别的研究

      在学习C的过程中发现了一件诡异的事情,在运行"++i"时两者的逻辑是一样的,但是在运行"++i + ++i"时就有问题了,如下图代码在java中输出为23,在C中输出为24.

伪代码:

int i=10;
int j=++i + ++i;
printf("%d",j);

java:

C:

        明明是同一段代码,在java中输出的是23,但是C中却是24,怀着好奇我打开了两者的反汇编文件,研究了一会儿找到了问题所在

java:

java的.class文件在IDEA中打开是这样的,可以看到是在变量3运行之前,先给变量2自增一次,然后是"变量3=变量2++ +变量2"(这段代码在C里输出的是2*变量2),最后输出23,可以看出在java的公式中变量的值是动态变化的,每加载一个变量就变化一次。

javap:

在控制台输入"javap -c 文件名"可以打开.class文件的反汇编,进行分析

第11行:寄存器2存的是i的值

第12行:寄存器2自增

(中间少了两行)

第15行:寄存器2的值载入

第16行:寄存器2自增

可以看到公式计算过程中变量值确实是动态变化的,符合上面的猜想。

C:

这是C语言的反汇编,可以在vs:调试->窗口->反汇编 中打开,下面是分析:


00007FF7A3B55A0B  mov         dword ptr [i],0Ah  //将0Ah(10)放入i的位置
00007FF7A3B55A12  mov         eax,dword ptr [i]   //将[i]放入eax寄存器
00007FF7A3B55A15  inc         eax                         //eax寄存器自增
00007FF7A3B55A17  mov         dword ptr [i],eax   //将eax里的值放回[i]的位置
00007FF7A3B55A1A  mov         eax,dword ptr [i]  
00007FF7A3B55A1D  inc         eax  
00007FF7A3B55A1F  mov         dword ptr [i],eax  
00007FF7A3B55A22  mov         eax,dword ptr [i]  
//将[i]的值先放入eax寄存器
00007FF7A3B55A25  mov         ecx,dword ptr [i]   //再将[i]的值放入ecx寄存器
00007FF7A3B55A28  add         ecx,eax                 //执行加法操作
00007FF7A3B55A2A  mov         eax,ecx            //将ecx的值给eax,加法结果默认在第二个寄存器
00007FF7A3B55A2C  mov         dword ptr [k],eax   //将值放入[k]的位置

       可以看到在C中执行“k=++i + ++i”时,是先把公式中的所有有自增操作变量有进行一次自增,然后把值放入寄存器进行操作,在公式执行过程中是静态的,在公式执行前将所有需要的操作已经做完了。

      其他还有很多自增自减的操作,感兴趣的可以去试一下,原理都是一样的。

      总结:

      在java中,公式是一步一步运行的,每运行一步就会更新变量的变化;

       在C中,公式里的变量会在执行前将所有需要的操作执行完毕,然后执行公式,最后执行所有公式执行后需要的操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值