Yahoo 知識+ 將於 2021 年 5 月 4 日 (美國東岸時間) 停止服務,而 Yahoo 知識+ 網站現已轉為僅限瀏覽模式。其他 Yahoo 資產或服務,或你的 Yahoo 帳戶將不會有任何變更。你可以在此服務中心網頁進一步了解 Yahoo 知識+ 停止服務的事宜,以及了解如何下載你的資料。
編譯器進化論嗎?一樣的程式三種結果,有人知道原因嗎?
編譯器進化論嗎?一樣的程式三種結果,有人知道原因嗎?以下程式int main(){ char i=0; printf("%d %d %d\\n",i++,i++,i++); printf("%d \\n",i); getch(); return 0;}我在VC 上跑結果是..0 0 0 3 請按任意鍵繼續 . . . 在 TC 上跑2 1 0 3 而在 JAVA 上跑卻是class test4 { public static void main(String p[]){ int i=0; System.out.println(" "+ (i++) + " "+ (i++) + " "+(i++)); System.out.println(i); }} 0 1 2 3 有點給他 點點點加三條線C的平台可轉移性很強,但是結果卻有差異?一樣的程式三種結果,有人知道原因嗎?
8 個解答
- RodyLv 51 十年前最愛解答
你寫了這樣的程式, 才叫人點點點加三條線為什麼這麼說呢? 因為以規範而言, 只有要求 ++ 放在前面或後面要先算還是後算, 卻沒有規範當一堆 ++ 擺在同一行, 哪個要先算, 哪個要後算; 也沒規範擺在一起的時候, 還把他傳入函數, 那是該傳入後就立刻後算, 還是要整行傳入後算你這樣的程式, 就是想要考驗不同編譯器對這種規範的模糊地帶的處理方式, 既然是模糊地帶, 每個編譯器當然就是見招拆招, 各自表述了, 你寫了一個模糊定義的語法, 才來質疑移植性問題, 所以我認為根本上是問題不合理, 因為你要這樣質疑, 首先必須你的寫法是在標準規範內, 而且每個編譯器都要合乎標準規範才會成立, 但我可以告訴你, C/C++ 雖然在國際間有幾次定義了標準規範, 但也不是每個編譯器都完全照做, TC 是多年前的產品, 更不可能來符合新的規範, 連 VC 6.0 也有很多地方不符合了, 那 TC 就更不要談了, 對於規範模糊的地方, 並不建議寫這樣的程式碼去測試它, 因為即使你測試出在這編譯器會有如此結果, 但同樣的程式碼換了環境, 你就無法給予任何保證, 這就失去了可移植性的意義結論是, 不建議把太多針對同一變數的連續操作寫在同一行程式碼裡, 寧可把他分開來寫, 因為即使你程式碼寫得再精簡, 翻譯出來的機械碼和分開來寫的程式碼可能是一樣的 (該做的動作還是要做, 跑不掉的), 太過精簡的程式碼除了縮短程式碼的篇幅以外, 幾乎沒有任何好處, 還會產生解讀障礙與可移植性問題 (太過精簡的程式碼, 你無法確定每個看的人的解釋會相同)
2006-10-26 07:14:42 補充:
looping 的用意不在於哪邊可以測試這種模糊的寫法, 在於你根本不該用這種模糊的寫法, 雖然看起來好像很高竿, 但其實很糟糕
2006-10-26 18:46:42 補充:
i=i++; ?
喔... 果然又是個弔詭的寫法,真要這樣寫,誰知道寫的人到底想要什麼結果?
- ?Lv 61 十年前
C或C++都未定義函數的argument list的運算順序,只保證所有的值都會在進入函數前會被算出來。
而comma operator則保證由左到右計算
左邊造成的任何效應,都會在啟動右邊的expression之前結束,包括臨時物件。
但函數不受comma operator的限制
假設有一個F(arg1, arg2, arg3),則
F(a, (b = 2, ++b), c);
*三個argument計算的順序未定義
*但肯定先算b=2再算++b,第二個argument等於3
另一個著名的expression是
i = i++;
- ?Lv 41 十年前
處理方法不同...這方面沒有一定的規範.討論這個很沒有意義.
舉個例子...SWAP
x^=y^=x^=y; //看起來很漂亮,但真的是好的嗎!
在VC++可以work無誤.
在Java則失敗.
所以要避免掉不好的寫法.