還研究的挺仔細(xì)的嘛,呵呵,竟然看字節(jié)碼了
千里兄過獎(jiǎng)了
順便補(bǔ)充一下,剛才我研究了JavaScript和C語言中的類似情況,發(fā)現(xiàn)JavaScript的結(jié)果與剛才講的Java代碼結(jié)果相同,但是C語言代碼有明顯不同的結(jié)果;
比如這段代碼:
int i=1;
int t=(4+(i++));
執(zhí)行完成之后,t的值為5,i的值為2;這個(gè)結(jié)果一點(diǎn)也不出乎意料
但是稍加改寫
int i=1;
i=(4+(i++));
執(zhí)行完成之后,i的值變成了6;如果這段交給Java虛擬機(jī)運(yùn)行,如上面所示,結(jié)果是5;
所以,我的想法是,C語言中的++(位于操作數(shù)右邊)在整條用分號(hào)結(jié)束的語句結(jié)束之后運(yùn)行;相當(dāng)于在該語句之后單獨(dú)寫一條i++語句。
i=(4+(i++)); 這種寫法會(huì)讓人不知所然,既然i++了,又賦給i
是的,現(xiàn)實(shí)中應(yīng)該幾乎沒有這種寫法,純興趣研究:)
如果要看i=(4+(i++));在C++中執(zhí)行就反匯編出來看看
7: int i=1;
00401798 mov dword ptr [ebp-4],1
8: i=(4+(i++));
0040179F mov eax,dword ptr [ebp-4]
004017A2 add eax,4
004017A5 mov dword ptr [ebp-4],eax
004017A8 mov ecx,dword ptr [ebp-4]
004017AB add ecx,1
004017AE mov dword ptr [ebp-4],ecx
再進(jìn)一步,考慮:
i=1;
i=(4+(i++)+(i++));
C語言的運(yùn)行結(jié)果為8,Java和JavaScript的結(jié)果為7.
印證了我剛才對(duì)于C語言機(jī)制的想法,即++操作在整條語句之后執(zhí)行;相加的值為(4+1+1)
在Java和JavaScript中,第二次load i的值時(shí),++操作已經(jīng)被執(zhí)行過一次了,所以相加的值為(4+1+2)
謝謝Unmi,看來在C語言中,++確實(shí)在最后執(zhí)行,這與Java和JavaScript非常不一樣。后者的++在表達(dá)式走出作用域的時(shí)候就執(zhí)行,而不會(huì)等到整個(gè)語句結(jié)束。
二樓的實(shí)驗(yàn)也非常有意義。沒想到c和java在這一點(diǎn)上還有區(qū)別,呵呵,學(xué)到了。不過有一點(diǎn)不太同意二樓說的,我覺得在c里面應(yīng)該是 i=i++;和i=(i++);的區(qū)別,前者不會(huì)加1,后者會(huì),而java中這兩者是一樣的。我說的僅僅是猜測,并沒有實(shí)驗(yàn)過,說錯(cuò)了見諒
teasp 說的二樓是我嗎? 偶是樓主的說:)
我剛看了
執(zhí)行下面兩句
1: i=i++;
2: i=(i++);
在C中,執(zhí)行完成之后,i的值均為2
在Java和JavaScript中,均為1
總結(jié)一下,這樣寫
i=(4+(++i));
完全是給自己制造麻煩,代碼不規(guī)范
極端一些,如果你碰到面試問你
int a=1;
int b=1;
int c= a++*b+++a++b;
你會(huì)去做這種題嗎?
我會(huì)轉(zhuǎn)身走人
奇怪,難道連括號(hào)也保證不了運(yùn)算的優(yōu)先級(jí)?
a++和++a是不同的,在java中本來就有分,一個(gè)是先把值return出去再自加,一個(gè)是自加後才return,因?yàn)槟愕膶懛ㄊ莂++,所以先return的值是1,再和4相加就是5且又指給a,這樣後來的a自加就沒有用了
是符合語義的。++操作的優(yōu)先級(jí)本來就大于加號(hào),所以一直不用寫括號(hào),寫括號(hào)只是為了可讀性@dc
是的,Java和JavaScript是這樣的,但是你看前面的評(píng)論,C語言中,a++在整個(gè)語句(用分號(hào)結(jié)束的語句)結(jié)束之后才執(zhí)行。這是關(guān)鍵。@piaoyi
研究的挺多,激發(fā)了我的研究熱情,XX(謝謝)樓上各位!