吾爱破解 - LCG - LSG |安卓破解|病毒分析|破解软件|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1520|回复: 28

[VC] 研究++a与a++的区别

  [复制链接]
发表于 2017-2-15 17:12 | 显示全部楼层
发现新人对前置、后置++操作都比较困惑,那么它们的区别到底再哪呢?我们通过汇编代码来分析就知道了。
先上我们的示例代码:
[C] 纯文本查看 复制代码
int main()
{
    int a=5,b=0,c=0,d=0;
    b=++a;
    c=a++;
    d=a;
    return 0;
}


下面来看看上面代码在QtCreator中的汇编代码:
081105_SkeF_853228.png

下面分析汇编代码,很简单:
变量初始化代码:
[Asm] 纯文本查看 复制代码
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代码:
[Asm] 纯文本查看 复制代码
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++代码:
[Asm] 纯文本查看 复制代码
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代码:
[Asm] 纯文本查看 复制代码
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。
实际上,c=a++等价于下面的代码:
[Asm] 纯文本查看 复制代码
int tmp=a;
++a;
c=tmp;

免费评分

参与人数 7吾爱币 +7 热心值 +6 收起 理由
52_pojie_52 + 1 + 1 谢谢@Thanks!
tmdrubik + 1 + 1 谢谢@Thanks!
wsp756 + 1 + 1 谢谢@Thanks!
xnzhan + 1 + 1 谢谢@Thanks!
asdl1243 + 1 + 1 谢谢@Thanks!
花〆折断了寂 + 1 + 1 大神
老猫5558 + 1 +号在前面就使用之前+1,反之在后面就使用之后+1,很好记的

查看全部评分

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2017-3-14 12:54 | 显示全部楼层
yysniper 发表于 2017-3-14 12:23
你说的这个情况确实要看编译器,但是单独的前置或者后置是编译器独立的

真是这样吗……
话说如果单独的情况彼此一致而联合起来使用反而彼此不同……
这证明了编译器对联合起来的情况做了不同的处理……而显然这是没必要的
以c=a++为例,可以写成:
c=a(先执行语句);a++(后让a自增)
也可以写成temp=a(先保存变量的值);a++(再让a自增);c=temp;(最后赋值)
正是类似的细节处理不同导致了编译器编译结果不同
不信你可以试试打开编译器的-O3选项


发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2017-2-15 19:47 | 显示全部楼层
这不是原来学习C++课程的时候需要做的一道课后作业么,要求写出A++和++A的实现过程。
A++实现(int* a){
     int temp=*a;
          *a=*a+1;
     return temp;
}
++A实现(int *a){
     *a=*a+1;
}

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2017-2-15 17:17 | 显示全部楼层

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2017-2-15 17:17 | 显示全部楼层
程序大牛啊

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2017-2-15 17:24 | 显示全部楼层
++A    使用A变量值之前先自加..
A++    使用完A变量值之后A再自加..

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2017-2-15 17:34 | 显示全部楼层
使用前和使用后加1的区别,我都是这样记

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2017-2-15 17:57 | 显示全部楼层
把每个步骤,每个变量都打印一下,很快就明白什么意思了

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2017-2-15 18:01 | 显示全部楼层
666,大神看问题是从本质来的。

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2017-2-15 18:13 | 显示全部楼层
这个有什么好研究?

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

发表于 2017-2-15 18:29 | 显示全部楼层
有啥区别?

发帖求助前要善用论坛搜索功能,那里可能会有你要找的答案;

如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】

如何回报帮助你解决问题的坛友,一个好办法就是给对方加【热心】【CB】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则


免责声明:
吾爱破解所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。

Mail To:Service@52PoJie.Cn

快速回复 收藏帖子 返回列表 搜索

RSS订阅|手机版|小黑屋|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2017-9-21 13:10

Powered by Discuz!

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表