i++与++i

来源:互联网 发布:java向导被中断 编辑:程序博客网 时间:2024/06/05 03:31


int main()
{
int i=0;
printf("%d %d %d\n",i++,++i,--i);
}
结果是多少呢?
大家都知道 前置++是先加再用,后置++是先用在加,并且printf()再传参时,是从右往左的。分析一下:
先是表达式–i, 因为是前置–,所以打印出来的值应该是-1;
接着是表达式++i,因为是前置++,所以打印出来的值应该是0;
最后是i++,因为时后置++,所以打印出来的值应该是0,且i的值是1;

but:
这里写图片描述

可能有人会跟我当时一样懵,感觉自己被老师骗了。那么,来看汇编

printf("%d %d %d\n", i++, ++i, --i);

003C3E25 mov eax,dword ptr [i]
003C3E28 sub eax,1
003C3E2B mov dword ptr [i],eax
可以看到在处理–i时,是先通过寄存器得到i的值,进行-1的操作,之后再通过寄存器将i值放回原来的内存空间中,i值变为-1;

003C3E2E mov ecx,dword ptr [i]
003C3E31 add ecx,1
003C3E34 mov dword ptr [i],ecx
这块是处理前置++的操作,和上面一样,通过寄存器的到值,进行+1,再放回到原来的内存空间,i值为0;

003C3E37 mov edx,dword ptr [i]
003C3E3A mov dword ptr [ebp-0D0h],edx
003C3E40 mov eax,dword ptr [i]
003C3E43 add eax,1
003C3E46 mov dword ptr [i],eax
这里 则是处理i++的操作,和前面不同的是,这次寄存器得到i值后,并未进行+1操作,而是将i值保存在一个临时开辟的内存中,之后才+1,并将之后的i值放回原来的内存空间中,i值为1;

下来则是依次打印表达式的值了
printf(“%d %d %d\n”, i++, ++i, –i);
01163E52 push edx
01163E53 mov eax,dword ptr [ebp-0D0h]
01163E59 push eax
01163E5A push 116CD48h
01163E5F call dword ptr ds:[1170168h]
01163E65 add esp,10h
01163E68 cmp esi,esp
01163E6A call __RTC_CheckEsp (011612D5h)
这里可以看到i++的值则是从系统定义的临时量中获取,而–i或++i的值都是从变量i的原地址中获取。
因此不难想象 :++i或–i所打印出来的值已经不是表达式计算出来的值了,而是i的内存中最终存放的值。

原创粉丝点击