不要写如下类型的代码 n=(++i)+(++i); n=(++i)+(++i)+(++i);
不要写如下类型的代码:
n=(++i)+(++i);
n=(++i)+(++i)+(++i);
看看汇编就知道为什么了:
n=(++i)+(++i);的汇编 (i=5) :
00401090 mov ecx,dword ptr [ebp-8]
00401093 add ecx,1
00401096 mov dword ptr [ebp-8],ecx 完成 i 自加1
00401099 mov edx,dword ptr [ebp-8] 结果放入edx
0040109C add edx,1
0040109F mov dword ptr [ebp-8],edx 完成第二次 i 自加1
004010A2 mov eax,dword ptr [ebp-8] 1 结果放入eax
004010A5 add eax,dword ptr [ebp-8] 2 eax <-- eax+i
004010A8 mov dword ptr [ebp-4],eax 3
看看最后3行代码:1-->把 i 的值放入寄存器eax,
2-->把 i 的值和eax相加,这就是相当于 i + i 了
3-->把eax的结果放入n中
结果就是n=i+i,而且 i 是经过两次自加后的终值。
所以 i 经过两次自加后 i = 7 ,n=7+7=14,而不是我们想象的 n = 6+7。
而且在不同的编译器、不同的CPU的情况下,处理方式恐怕都会不同。
再看 n=(++i)+(++i)+(++i); 的汇编 (i=5) :
00401090 mov ecx,dword ptr [ebp-8]
00401093 add ecx,1
00401096 mov dword ptr [ebp-8],ecx 完成第一次 i 自加1
00401099 mov edx,dword ptr [ebp-8] 结果放入edx
0040109C add edx,1
0040109F mov dword ptr [ebp-8],edx 完成第二次 i 自加1
004010A2 mov eax,dword ptr [ebp-8] 结果放入eax
004010A5 add eax,dword ptr [ebp-8] eax <-- eax+i (eax= i + i)
004010A8 mov ecx,dword ptr [ebp-8] 结果放入ecx (ecx=i+i)
004010AB add ecx,1
004010AE mov dword ptr [ebp-8],ecx 完成第三次 i 自加1
004010B1 add eax,dword ptr [ebp-8] eax <-- eax+i
004010B4 mov dword ptr [ebp-4],eax 结果放入n
前8句代码和n=(++i)+(++i);一样、结果为14、这个值放入eax和ecx中、i=7
然后 i 自加1、i=8 --> eax= eax+i =14+8=22
一般认为n=6+7+8=21、但是过程和我们的习惯想法不同。
使用picc(PIC单片机的编译器)编译的结果和过程和VC++6.0一样。
这样的代码和我们思考的习惯相差较大、不用为宜。
当然、类似n=(i++)+(++i);之类的代码也不宜出现,除非你对过程很熟悉、
或者你愿意经常为了这几句代码去查看具体的执行过程。
VC++6.0查看汇编:
F10进入调试、view菜单里面的反汇编选项:view/debug window/diss.../
n=(++i)+(++i);
n=(++i)+(++i)+(++i);
看看汇编就知道为什么了:
n=(++i)+(++i);的汇编 (i=5) :
00401090 mov ecx,dword ptr [ebp-8]
00401093 add ecx,1
00401096 mov dword ptr [ebp-8],ecx 完成 i 自加1
00401099 mov edx,dword ptr [ebp-8] 结果放入edx
0040109C add edx,1
0040109F mov dword ptr [ebp-8],edx 完成第二次 i 自加1
004010A2 mov eax,dword ptr [ebp-8] 1 结果放入eax
004010A5 add eax,dword ptr [ebp-8] 2 eax <-- eax+i
004010A8 mov dword ptr [ebp-4],eax 3
看看最后3行代码:1-->把 i 的值放入寄存器eax,
2-->把 i 的值和eax相加,这就是相当于 i + i 了
3-->把eax的结果放入n中
结果就是n=i+i,而且 i 是经过两次自加后的终值。
所以 i 经过两次自加后 i = 7 ,n=7+7=14,而不是我们想象的 n = 6+7。
而且在不同的编译器、不同的CPU的情况下,处理方式恐怕都会不同。
再看 n=(++i)+(++i)+(++i); 的汇编 (i=5) :
00401090 mov ecx,dword ptr [ebp-8]
00401093 add ecx,1
00401096 mov dword ptr [ebp-8],ecx 完成第一次 i 自加1
00401099 mov edx,dword ptr [ebp-8] 结果放入edx
0040109C add edx,1
0040109F mov dword ptr [ebp-8],edx 完成第二次 i 自加1
004010A2 mov eax,dword ptr [ebp-8] 结果放入eax
004010A5 add eax,dword ptr [ebp-8] eax <-- eax+i (eax= i + i)
004010A8 mov ecx,dword ptr [ebp-8] 结果放入ecx (ecx=i+i)
004010AB add ecx,1
004010AE mov dword ptr [ebp-8],ecx 完成第三次 i 自加1
004010B1 add eax,dword ptr [ebp-8] eax <-- eax+i
004010B4 mov dword ptr [ebp-4],eax 结果放入n
前8句代码和n=(++i)+(++i);一样、结果为14、这个值放入eax和ecx中、i=7
然后 i 自加1、i=8 --> eax= eax+i =14+8=22
一般认为n=6+7+8=21、但是过程和我们的习惯想法不同。
使用picc(PIC单片机的编译器)编译的结果和过程和VC++6.0一样。
这样的代码和我们思考的习惯相差较大、不用为宜。
当然、类似n=(i++)+(++i);之类的代码也不宜出现,除非你对过程很熟悉、
或者你愿意经常为了这几句代码去查看具体的执行过程。
VC++6.0查看汇编:
F10进入调试、view菜单里面的反汇编选项:view/debug window/diss.../