关于C语言前置++和后置++的二三事
标签:
c语言it |
首先来看这样一段代码
后置++,则是直接对a当前的值进行读取,a作为一个变量
int main()
{
int a = 0;
printf("%d,%d,%d\n",a++,++a,a++);
}
这段代码看起来很简单,相信一部分人会觉得这么简单的问题还有必要拿出来讲???
先来看看答案与你想象中的是否一样吧~
他的答案输出就是2,3,0
我在第一次看到这种代码时毫不犹豫说出答案,最后运行出来与自己想象中完全不同,不少人又要想,我的编译器怎么肥四?!http://www/uc/myshow/blog/misc/gif/E___6692EN00SIGG.gif
下边我来带你分析一下这段简单的代码吧http://www/uc/myshow/blog/misc/gif/E___7474ZH00SIGG.gif
在VS2012中将这段代码转到汇编语言,如下图
http://s14/bmiddle/0026EXGzzy7fjQY5Mlf3d&690
---------------------------------------------------------------------------------
---------------------------------------------------------------------------------
前边栈帧的开辟和初始化就不放上来了,无大碍http://www/uc/myshow/blog/misc/gif/E___6712EN00SIGG.gif
我们来分析一下这段代码
首先压栈操作是按从后往前的顺序压的,为方便说明,先姑且将printf中的a++,++a,a++中第一个a记为a1,第二个++a为a2,第三个为a3
mov
eax,dword ptr [a]
//将a的值赋给eax寄存器,此时为0
mov
dword ptr [ebp-0D0h],eax
//将eax的值赋给一个 a3的临时量=0
mov
ecx,dword ptr [a]
//再将a的给一个ecx寄存器
add
ecx,1
//ecx++ (第三个a++)
mov
dword ptr [a],ecx
//将ecx赋给a, 此时a的值改变为1
--------以上执行完a++
mov
edx,dword ptr [a]
//a的值赋给edx寄存器
add
edx,1
//edx++ (此处为++a)
mov
dword ptr [a],edx
//将edx赋给a, 此时a的值改变为2
--------以上执行完++a
mov
eax,dword ptr [a]
// 将a的值赋给eax寄存器,此时a的值为2
mov
dword ptr [ebp-0D4h],eax
// 将eax的值赋给一个a1的临时量=2
mov
ecx,dword ptr [a]
// 再将a的给一个ecx寄存器
add
ecx,1
// ecx++ (第一个a++)
mov
dword ptr [a],ecx
// 将ecx赋给a,此时a的值改变为3
--------以上执行完a++
mov
esi,esp
mov
edx,dword ptr [ebp-0D0h]
//将 a3产生的临时量=0,赋给edx寄存器
push
edx
//edx压栈,a3处a++的值即为0
mov
eax,dword ptr [a]
// 将a的值=3,赋给eax寄存器
push
eax
//eax压栈,a2处++a的值为3
mov
ecx,dword ptr [ebp-0D4h]
// 将a1产生的临时量=2,赋给ecx寄存器
push
ecx
//将ecx压栈,a1处a++的值即为2
总结:前置++,会在压栈前用一个寄存器来存储当前a的值,最终压进栈的值是临时量里的值而不是a本身
就这样了~
Bye~

加载中…