i++与++i最大的区别就是:
i++:先取值后自加;
++i:先自加后取值。
运行代码:
#include <stdio.h>
int main()
{
int i = 0;
printf("%d,%d,%d\n",i++,--i,i++);
return 0;
}
运用debug调试的反汇编查看汇编代码,如下:
int main()
{
00161420 push ebp
00161421 mov ebp,esp
00161423 sub esp,0D4h
00161429 push ebx
0016142A push esi
0016142B push edi
0016142C lea edi,[ebp-0D4h]
00161432 mov ecx,35h
00161437 mov eax,0CCCCCCCCh
0016143C rep stos dword ptr es:[edi]
int i = 0;
0016143E mov dword ptr [i],0
printf("%d,%d,%d\n",i++,--i,i++);
00161445 mov eax,dword ptr [i]
00161448 mov dword ptr [ebp-0D0h],eax
0016144E mov ecx,dword ptr [i]
00161451 add ecx,1
00161454 mov dword ptr [i],ecx
00161457 mov edx,dword ptr [i]
0016145A sub edx,1
0016145D mov dword ptr [i],edx
00161460 mov eax,dword ptr [i]
00161463 mov dword ptr [ebp-0D4h],eax
00161469 mov ecx,dword ptr [i]
0016146C add ecx,1
0016146F mov dword ptr [i],ecx
00161472 mov esi,esp
00161474 mov edx,dword ptr [ebp-0D0h]
0016147A push edx
0016147B mov eax,dword ptr [i]
0016147E push eax
0016147F mov ecx,dword ptr [ebp-0D4h]
00161485 push ecx
00161486 push offset string "%d,%d,%d" (16573Ch)
0016148B call dword ptr [__imp__printf (1682BCh)]
00161491 add esp,10h
00161494 cmp esi,esp
00161496 call @ILT+315(__RTC_CheckEsp) (161140h)
return 0;
0016149B xor eax,eax
}
0016149D pop edi
0016149E pop esi
0016149F pop ebx
001614A0 add esp,0D4h
001614A6 cmp ebp,esp
001614A8 call @ILT+315(__RTC_CheckEsp) (161140h)
001614AD mov esp,ebp
001614AF pop ebp
001614B0 ret
函数传参过程:C++沿用C的参数传递方式,是从右到左传递的,即从第三个参数,到第二个参数,再到第一个参数,依次执行相应操作,然后依次压栈。
下图为main函数中
printf("%d,%d,%d\n",i++,--i,i++);
给printf函数传参的汇编代码的详解:
(右键全屏看高清大图)
最后printf打印的值为:0, 1, 0
结论:
i++在函数压栈过程前:
1,先取内存数据段i的值,存入一个临时量中;
2,然后进行自加,再写入内存数据段的i中;
3,等待所有参数运算完成后,最后压栈时,将保存的临时量的值进行压栈。
++i在函数压栈过程前:
1,直接取内存数据段的i值,进行自加,再写入内存数据段的i中;
2,等待所有参数运算完成后,最后压栈时,直接取内存数据段的i值进行压栈。