前言:本文章仅是使用汇编对i++和++i的底层进行分析,不做深入。
先看第一个案例:
#include <stdio.h> // 头文件
#include <Windows.h>
int main()
{
__asm mov eax,eax; // 设置断点
int ii = 0; // 局部变量
ii++;
printf("%d",ii);
++ii;
printf("%d",ii);
return 0;
}
代码的逻辑很简单,简单到没有逻辑。就不解释了。
CTRL+ALT+F7编译,F5运行,ALT+8转到反汇编
我们先来看从ii++到printf:
再来看++ii到printf:
从上面两张图的ii++和++ii他们的动作来看,是没有任何区别的。这是为什么呢?因为我们没有立即使用到这个值,就是说ii++和++ii我们只是当作一个加值的操作直接过了,并没有把它当成表达式去立即使用,所以底层也就是这两个步骤作为了"变量+1"的操作,所以是一样的。
我们稍微修改一下代码,如下:
#include <stdio.h> // 头文件
#include <Windows.h>
int main()
{
__asm mov eax,eax; // 设置断点
int ii = 0; // 局部变量
printf("%d",ii++);
printf("%d",++ii);
return 0;
}
CTRL+ALT+F7编译,F5运行,ALT+8转到反汇编
我们再来看看ii++:
我们可以看到,ii++的操作是:先将值 0 取出,放到一个临时的局部变量ebp-D0中,然后再将+1的结果放到ecx中,ecx最终又放回了ii这个局部变量,然后调用函数的时候传给printf的是临时局部变量的0,其实变量已经+1了,只不过传给printf的是未+1之前备份的值。
所以总结:ii++的动作是,先+1后输出。
再来看看++ii:
我们可以看到:++ii的动作也是先加1后输出 。
总结:
无论是ii++还是++ii,其实在底层汇编上,都是先+1,然后再输出。不过++ii输出的是+1之后的变量,而ii++输出的则是+1之前备份的临时变量。所以才会看到,第一个输出的是0、第二个输出的是2。