探究++a与a++的区别到底在哪

最近发现好多童鞋对++a与a++的区别一直很困惑。因此我决定对这个简单的问题进行简单的研究,所以写下此文,希望对童鞋有帮助。


 环境:windows7+QtCreator+Qt5.5.1+GCC 4.9.2+GDB 7.8.1

来看看要研究的代码,很简单。
 

int main()
{
    int a=5,b=0,c=0,d=0;
    b=++a;
    c=a++;
    d=a;
    return 0;
}

 

QtCreator中下断,然后进入反汇编模式看看反汇编代码。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

(题外话,QtCreator的栈窗口我不太喜欢,要是和OllyDBG一样就好了)

Debug模式下的反汇编,很简单很清晰。下面来进行分析:

变量初始化代码:

mov    DWORD PTR [esp+0xc],0x5    给变量a赋初始值
mov    DWORD PTR [esp+0x8],0x0    给变量b赋初始值
mov    DWORD PTR [esp+0x4],0x0    给变量c赋初始值
mov    DWORD PTR [esp],0x0        给变量d赋初始值

可以看到,几个变量都是在栈中分配空间的。

b=++a代码:

add    DWORD PTR [esp+0xc],0x1    给a加上1
mov    eax,DWORD PTR [esp+0xc]    将a的值拷贝到eax寄存器
mov    DWORD PTR [esp+0x8],eax    将eax寄存器的值再拷贝给b

从上面可以看出,和我们想的一样,给a加上1后就赋值给了b。

c=a++代码:

mov    eax,DWORD PTR [esp+0xc]    将a的值拷贝打eax寄存器
lea    edx,[eax+0x1]              将eax加1后存入edx寄存器,此时edx的值为7
mov    DWORD PTR [esp+0xc],edx    再将edx的值拷贝给a
mov    DWORD PTR [esp+0x4],eax    将eax的值拷贝给c

可以看到,先将a的值也就是6保存在eax寄存器中,然后将a的值加1,此时a已经是7了。但是赋给c的值却不是a,而是eax寄存器保存的值,也就是6。

d=a代码:

mov    eax,DWORD PTR [esp+0xc]   将a的值拷贝到eax寄存器,注意此时a的值已经是7了
mov    DWORD PTR [esp],eax       将eax的值拷贝给d,于是d的值是7

那么,最终运行结果是:

a==7;

b==6;

c==6;

d==7;

从上我们可以得出结论:

对于b=++a,编译器是将a加1后直接赋值给b

对于c=a++,编译器是先将a的值保存在一个临时变量中,本文是eax寄存器,然后将a加1,最后将临时变量的值赋值给c。结果就是c中是a原来的值,而a已经加了1。

我也将本文整理成百度经验:http://jingyan.baidu.com/article/9f63fb919997f3c8400f0efb.html

转载于:https://my.oschina.net/yysniper/blog/794886

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值