研究++a与a++的区别
发现新人对前置、后置++操作都比较困惑,那么它们的区别到底再哪呢?我们通过汇编代码来分析就知道了。先上我们的示例代码:
int main()
{
int a=5,b=0,c=0,d=0;
b=++a;
c=a++;
d=a;
return 0;
}
下面来看看上面代码在QtCreator中的汇编代码:
下面分析汇编代码,很简单:
变量初始化代码:
mov DWORD PTR ,0x5 给变量a赋初始值
mov DWORD PTR ,0x0 给变量b赋初始值
mov DWORD PTR ,0x0 给变量c赋初始值
mov DWORD PTR ,0x0 给变量d赋初始值
可以看到,几个变量都是在栈中分配空间的。
b=++a代码:
add DWORD PTR ,0x1 给a加上1
mov eax,DWORD PTR 将a的值拷贝到eax寄存器
mov DWORD PTR ,eax 将eax寄存器的值再拷贝给b
从上面可以看出,和我们想的一样,给a加上1后就赋值给了b。
c=a++代码:
mov eax,DWORD PTR 将a的值拷贝打eax寄存器
lea edx, 将eax加1后存入edx寄存器,此时edx的值为7
mov DWORD PTR ,edx 再将edx的值拷贝给a
mov DWORD PTR ,eax 将eax的值拷贝给c
可以看到,先将a的值也就是6保存在eax寄存器中,然后将a的值加1,此时a已经是7了。但是赋给c的值却不是a,而是eax寄存器保存的值,也就是6。
d=a代码:
mov eax,DWORD PTR 将a的值拷贝到eax寄存器,注意此时a的值已经是7了
mov DWORD PTR ,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++等价于下面的代码:
int tmp=a;
++a;
c=tmp; yysniper 发表于 2017-3-14 12:23
你说的这个情况确实要看编译器,但是单独的前置或者后置是编译器独立的
{:17_1054:}真是这样吗……
话说如果单独的情况彼此一致而联合起来使用反而彼此不同……
这证明了编译器对联合起来的情况做了不同的处理……而显然这是没必要的
以c=a++为例,可以写成:
c=a(先执行语句);a++(后让a自增)
也可以写成temp=a(先保存变量的值);a++(再让a自增);c=temp;(最后赋值)
正是类似的细节处理不同导致了编译器编译结果不同
不信你可以试试打开编译器的-O3选项
谁在前面先算谁 程序大牛啊{:1_921:} ++A 使用A变量值之前先自加..
A++ 使用完A变量值之后A再自加..
使用前和使用后加1的区别,我都是这样记 把每个步骤,每个变量都打印一下,很快就明白什么意思了 666,大神看问题是从本质来的。 这个有什么好研究? 有啥区别? 这不是原来学习C++课程的时候需要做的一道课后作业么,要求写出A++和++A的实现过程。
A++实现(int* a){
int temp=*a;
*a=*a+1;
return temp;
}
++A实现(int *a){
*a=*a+1;
}