作者rainphiz ( )
看板TransCSI
標題Re: [問題] i值結果
時間Wed Apr 1 08:36:53 2009
※ 引述《RJking (RJ-king)》之銘言:
: ※ 引述《walks (蹦蹦跳跳)》之銘言:
: : 1.: i = 1 ;
: : 2.: ++i+=i++;
: 老實說這個答案好像不同compiler會不一樣,因為對語句解釋的不同
: 大概講一下RJ牌人腦compiler的答案跟流程
: 1.: i = 1 ; //將i指定為1
: 2.: ++i+=i++ ; //先做++i(i變成2),然後做i+=i(i指定成i+i,i變成4)
: //然後做i++(i變成5)
: 所以i的值最後是5
: 還有就是VS2005跟VS2008跟DEV C++會直接跟你說"++i+=i++"這行語法錯誤
: 如果題目直接註明一定有答案或是你怕老師認為一定會有答案,你可以考慮用我的答案
: 我對第二行的解釋只是單純基於運算子優先順序而已...
在 C 中這是違法的,而在 C++ 中這是合法的。
所以以上運算式用 g++ 是可以 compile 過的,而 gcc 不行。
簡單來說,
在 C++ 中, ++i 會將 i 值遞增後,回傳 i 這個 [變數]
而在 C, ++i 在 i 遞增後回傳的是 i 這個變數的 [值]
而無論在 C/C++
i++ 回傳的都是都是 i 的 [值]。
但放在等號左邊的必須為一 lvalue,也就是可被解析出該物件的位址
因此,i 這個 [變數] 可以當作 lvalue,因為 i 是一個有位址的物件
但 i 的 [值] 卻不行,因為它並非是一個物件
因此,在 C++ 中,
++i = i++; 會過
i++ = i++; 不會過
在 C 中,
上面兩式均不會通過編譯。
我們也可經由上面知道,
*(&i) = 0; 這樣的指定式在 C/C++ 中均不會通過編譯,
因為 *(&i) 回傳的是 i 的 [值] 而不是 i 這個 [變數物件]。
: 這可以算是Undefined behavior吧...
: http://en.wikipedia.org/wiki/Undefined_behavior
是的,因為 i 的值在 sequence points 中被更改了兩次,
不過我想老師應該只是要考運算子優先序的觀念,答案應該就是 5 吧。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.133.2.239
→ RJking:我DEV C++是用g++ compile的...VS2005跟VS2008也是以C++來 04/01 11:39
→ RJking:跑的...阿就不會過... 04/01 11:40
推 avogau:會不會是你其他地方寫錯了 04/01 12:30
→ avogau:我用 code::blocks 可以過 04/01 12:30
→ avogau:code::blocks是用g++3.4.5 04/01 12:31
→ avogau:還是你的副檔名是用 .c 04/01 12:31
推 zptdaniel:這題不是undefined behavior嗎? 04/01 13:17
→ zptdaniel:答題不就直接說未定義行為,不同的編輯器會有不同的答案? 04/01 13:17
→ zptdaniel:C_and_CPP裡面討論過很多次的樣子,可以去翻翻看文章. 04/01 13:18
→ zptdaniel:不過確實*.c會不能執行。*.cpp可以執行且值為5. 04/01 13:23
→ zptdaniel:所以還是看題目是哪種語言吧@@ 04/01 13:23
→ RJking:副檔名當然是.cpp DEV C++跟VS2005、VS2008預設都存.cpp 04/01 19:43
推 RJking:OK看來是沒有寫進function的錯...VS2005、VS2008、DEV C++ 04/01 19:58
→ RJking:跟code::blocks都跑出5,證明RJ牌人腦compiler是對的XD 04/01 19:59