微软的一道面试题(2014年校招)
代码:
int i=0;
i+=i>0?i++:i--;
问i等于多少?
在vs2012 C++中等于 -1,而在java中i最终等于0。
下面看看一些关于后置++的底层代码
C++代码:
int i=0;
int b=0;
b=i++;
结果:b=0 i=1
汇编代码:
int i=0;
01326D3E mov dword ptr [i],0 // i<- 0
int b=0;
01326D45 mov dword ptr [b],0 // b<- 0
b=i++;
01326D4C mov eax,dword ptr [i] // eax<- i
01326D4F mov dword ptr [b],eax // b<- eax
01326D52 mov ecx,dword ptr [i] // ecx<- i
01326D55 add ecx,1 // ecx<- ecx+1
01326D58 mov dword ptr [i],ecx // i<- ecx
由汇编代码可知,vs2012 C++先将 b<- i,然后i<- i+1.
********************************************************************
C++代码:
int i=0;
int b=0;
b+=i++;
结果:b=0 i=1
汇编代码:
int i=0;
00106D3E mov dword ptr [i],0 // i<- 0
int b=0;
00106D45 mov dword ptr [b],0 // b<- 0
b+=i++;
00106D4C mov eax,dword ptr [b] // eax<- b
00106D4F add eax,dword ptr [i] //eax <- eax+i
00106D52 mov dword ptr [b],eax // b<- eax
00106D55 mov ecx,dword ptr [i] // ecx<- i
00106D58 add ecx,1 // ecx<-ecx+1
00106D5B mov dword ptr [i],ecx // i<- ecx
由汇编代码可知,vs2012 C++先将 b<- b+i,然后i<- i+1.
****************************************************************************
C++代码:
int i=0;
int b=0;
b+=i>0?i++:i--;
结果:b=0 i=-1
汇编代码:
int i=0;
01166D3E mov dword ptr [i],0 //i<- 0
int b=0;
01166D45 mov dword ptr [b],0 //b<- 0
b+=i>0?i++:i--;
01166D4C cmp dword ptr [i],0 //cmp i , 0
01166D50 jle main+46h (01166D66h) //如果小于,转 main+46h (01166D66h)
01166D52 mov eax,dword ptr [i] //eax<- i
01166D55 mov dword ptr [ebp-0DCh],eax // temp <- eax (temp 临时变量)
01166D5B mov ecx,dword ptr [i] // ecx<- i
01166D5E add ecx,1 // ecx<- ecx+1
01166D61 mov dword ptr [i],ecx // i<- ecx
01166D64 jmp main+58h (01166D78h) //转main+58h (01166D78h)
01166D66 mov edx,dword ptr [i] // edx<- i
01166D69 mov dword ptr [ebp-0DCh],edx //temp<- edx
01166D6F mov eax,dword ptr [i] //eax<- i
01166D72 sub eax,1 //eax<- eax-1
01166D75 mov dword ptr [i],eax //i<- eax
01166D78 mov ecx,dword ptr [b] // ecx<- b
01166D7B add ecx,dword ptr [ebp-0DCh] // ecx<- ecx +temp
01166D81 mov dword ptr [b],ecx //b<- ecx
*****************************************************
C++代码:
int i=0;
i+=i>0?i++:i--;
结果:i=-1
汇编代码:
int i=0;
00C36D3E mov dword ptr [i],0 //i<- 0
i+=i>0?i++:i--;
00C36D45 cmp dword ptr [i],0 //cmp i , 0
00C36D49 jle main+3Fh (0C36D5Fh) //如果小于,转 main+3Fh (0C36D5Fh)
00C36D4B mov eax,dword ptr [i] //eax<- i
00C36D4E mov dword ptr [ebp-0D0h],eax // temp <- eax (temp 临时变量)
00C36D54 mov ecx,dword ptr [i] // ecx<- i
00C36D57 add ecx,1 // ecx<- ecx+1
00C36D5A mov dword ptr [i],ecx // i<- ecx
00C36D5D jmp main+51h (0C36D71h) //转main+51h (0C36D71h)
00C36D5F mov edx,dword ptr [i] //edx<- i
00C36D62 mov dword ptr [ebp-0D0h],edx //temp<- edx
00C36D68 mov eax,dword ptr [i] //eax<- i
00C36D6B sub eax,1 //eax<- eax-1
00C36D6E mov dword ptr [i],eax // i<- eax
00C36D71 mov ecx,dword ptr [i] // ecx<- i
00C36D74 add ecx,dword ptr [ebp-0D0h] // ecx<- ecx +temp
00C36D7A mov dword ptr [i],ecx // i<- ecx
java代码:
int i=0;
i+=i>0?i++:i--;
结果:i=0
java字节码:
0: iconst_0 //stack中存入一个int常量0
1: istore_1 //把它(从栈中弹出)赋值给第一个变量,即我们的i
2: iload_1 //把i入栈
3: iload_1 //把i入栈
4: ifle 14 //如果 栈顶元素小于0,转14
7: iload_1 //把i入栈
8: iinc 1, 1 //i(变量表中的i,不是栈中的i)自加1
11: goto 18 //转18
14: iload_1 //把变量表中的i入栈
15: iinc 1, -1 //把变量表中的i自减1
18: iadd //把栈顶两个元素相加
19: istore_1 //把栈顶元素存入到 i(变量表中的i)