標籤:
首先不要被人蒙了,如果是這樣,根本編譯不過:
int i=1;int b=i+++++i;printf("%d %d\n", b ,i);
Mingw報錯:error: lvalue required as increment operand (好像是說,++缺左值,這裡的++是上題的第三第四個加號)
VC2010報錯:error C2105: ‘++‘ needs l-value
--------------------------------------------------------------------------
正確的面試題應該是這樣:
int i=1;int b=i++ + ++i;printf("%d %d\n", b ,i);
我沒做過編譯器,只能從以往學過的知識猜:
前提,這個語句裡有三個運算式,分別是 i++ (exp1), ++i (exp3), exp+exp3 = exp2
1. 記得以前if語句有多個條件的時候,開啟最佳化開關,一旦第一個條件成立,後面的條件就有可能不評估了,這說明編譯器對錶達式是從左往右分析的。
2. exp1 = i++要在當前整個語句執行完畢以後才執行。如果這句語句有多個函數或者內含多個運算式,就應該等待這些運算式全部計算完畢,才執行++操作。
3. 這一行裡運算式 i++ (exp1),,和 ++i (exp3),使用的是同一個i,因此如果在整個語句結束之前,其中一個運算式計算的值會影響另一個運算式的值。
綜合上面分析:先執行++i (exp3),執行後i=2; 然後執行 b = exp1 + exp3 = i + i = 2 + 2 = 4; 最後執行exp1 = i++ = 2+1 = 3
結果:MingW和VC2010的結果都是4,3,被我都蒙對了。記住兩點:運算式從左往右執行,多個運算式共用一個變數相互影響(而不是各個運算式被分割以後,進行封閉式計算。記憶體裡始終只有一個i,而編譯器也不應該自作主張加上鎖,或者做多份記憶體拷貝,如果刻意想要的效果,應該是由程式員來做這個工作,編譯器不應該越俎代庖)。
沒親手做過編譯器就是被人欺,從一道變態的i++題猜編譯器的行為(運算式從左往右掃描,同一變數相互影響)