Yahoo 知識+ 將於 2021 年 5 月 4 日 (美國東岸時間) 停止服務,而 Yahoo 知識+ 網站現已轉為僅限瀏覽模式。其他 Yahoo 資產或服務,或你的 Yahoo 帳戶將不會有任何變更。你可以在此服務中心網頁進一步了解 Yahoo 知識+ 停止服務的事宜,以及了解如何下載你的資料。

ㄚ旺
Lv 5
ㄚ旺 發問於 電腦與網際網路程式設計 · 1 十年前

編譯器進化論嗎?一樣的程式三種結果,有人知道原因嗎?

編譯器進化論嗎?一樣的程式三種結果,有人知道原因嗎?以下程式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 個解答

評分
  • Rody
    Lv 5
    1 十年前
    最愛解答

    你寫了這樣的程式, 才叫人點點點加三條線為什麼這麼說呢? 因為以規範而言, 只有要求 ++ 放在前面或後面要先算還是後算, 卻沒有規範當一堆 ++ 擺在同一行, 哪個要先算, 哪個要後算; 也沒規範擺在一起的時候, 還把他傳入函數, 那是該傳入後就立刻後算, 還是要整行傳入後算你這樣的程式, 就是想要考驗不同編譯器對這種規範的模糊地帶的處理方式, 既然是模糊地帶, 每個編譯器當然就是見招拆招, 各自表述了, 你寫了一個模糊定義的語法, 才來質疑移植性問題, 所以我認為根本上是問題不合理, 因為你要這樣質疑, 首先必須你的寫法是在標準規範內, 而且每個編譯器都要合乎標準規範才會成立, 但我可以告訴你, C/C++ 雖然在國際間有幾次定義了標準規範, 但也不是每個編譯器都完全照做, TC 是多年前的產品, 更不可能來符合新的規範, 連 VC 6.0 也有很多地方不符合了, 那 TC 就更不要談了, 對於規範模糊的地方, 並不建議寫這樣的程式碼去測試它, 因為即使你測試出在這編譯器會有如此結果, 但同樣的程式碼換了環境, 你就無法給予任何保證, 這就失去了可移植性的意義結論是, 不建議把太多針對同一變數的連續操作寫在同一行程式碼裡, 寧可把他分開來寫, 因為即使你程式碼寫得再精簡, 翻譯出來的機械碼和分開來寫的程式碼可能是一樣的 (該做的動作還是要做, 跑不掉的), 太過精簡的程式碼除了縮短程式碼的篇幅以外, 幾乎沒有任何好處, 還會產生解讀障礙與可移植性問題 (太過精簡的程式碼, 你無法確定每個看的人的解釋會相同)

    2006-10-26 07:14:42 補充:

    looping 的用意不在於哪邊可以測試這種模糊的寫法, 在於你根本不該用這種模糊的寫法, 雖然看起來好像很高竿, 但其實很糟糕

    2006-10-26 18:46:42 補充:

    i=i++; ?

    喔... 果然又是個弔詭的寫法,真要這樣寫,誰知道寫的人到底想要什麼結果?

  • ㄚ旺
    Lv 5
    1 十年前

    1.1234

    2009-10-17 02:52:17 補充:

    1.1234

    2009-10-17 02:53:42 補充:

    1.234567890

  • ?
    Lv 6
    1 十年前

    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 6
    1 十年前

    x^=y^=x^=y

    vb不能這樣寫吧?

  • ?
    Lv 4
    1 十年前

    同樣一句話,每個人聽到的都不一樣,吧

  • ?
    Lv 5
    1 十年前

    沒錯. 很差的例子.

  • 1 十年前

    x^=y^=x^=y; // swap x y

    我在vb 上用可以~~ Java 倒是沒試過

  • ?
    Lv 4
    1 十年前

    處理方法不同...這方面沒有一定的規範.討論這個很沒有意義.

    舉個例子...SWAP

    x^=y^=x^=y; //看起來很漂亮,但真的是好的嗎!

    在VC++可以work無誤.

    在Java則失敗.

    所以要避免掉不好的寫法.

還有問題嗎?立即提問即可得到解答。