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

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

一個怪怪的問題..這是編譯器的問題嗎

以下程式結果為何呢?看到答案有點傻眼了  int main(){    unsigned char a=0,b=0;    while(-1)    {        if(a++>10 && b++>10)  // 若a與b同時大於10則離開            break;    }    printf("\\nA:%d  B=%d\\n",a,b);    system("pause");    return 0;}  // ---------------------------------------我預期的答案應該是A:12  B=12       請按任意鍵繼續 . . .     // ---------------------------------------但是.......答案居然是...  A:23  B=12       請按任意鍵繼續 . . .   // ---------------------------------------後來我用TC 與 JAVA 跑,結果答案都一樣 這是C的編譯器故障嗎?或是有人知道原因為何嗎?

5 個解答

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

    這是最佳化問題造成的因為你的判斷式當中, 你寫 if( a++>10 && b++>10)...在 C/C++ 裡面, 遇到 if 判斷式, 會自動進行最佳化, 也就是說, 如果前面的條件不成立, 後面的東西就不用算了 (在進行邏輯運算 && 的時候)因此, 在你的例子當中, 一開始 a=0, 當他執行 a++ 得到 0>10 不成立時, b++ 就不進行運算, 但 a 會執行 ++ 的運算, 也就是 a=1, 以此類推, 直到 a=11 時, 11>10 成立, 他才會判斷後面的運算 b++>10 是否成立也就是說, 當你寫 if( a++>10 && b++>10 )... 內部解讀會跟你寫 if( a++>10 ) if( b++>10 ) ...是一致的, 因此當 b++ 第一次執行之後, a=12,b=1, 以此類推, 最後就會是 a=23, b=12 了這不是編譯器故障, 只是你寫了會讓人與編譯器容易發生誤解的寫法

  • ?
    Lv 5
    1 十年前

    短路運算@@

  • ?
    Lv 6
    1 十年前

    附帶提幾個C++常識:

    1.不要對任何類別重載&&和||運算子

    因為重載過的運算子如同行為函數,參數在輸入時已經決定

    所以重載版的&&和||絕對不可能和內建的一樣

    大多數的C/C++程式設計者都非常熟悉&&和||偷工減料的行為,不要造成別人的困擾

    2.看到這樣的程式碼要注意

    F(x) && G(x).....

    即使G(x)裡面有一些驚天動地的安排

    也很有可能根本不會被執行到

  • 1 十年前

    你這樣寫有這樣的結果是正常的

    原因出在

    if(a++>10 && b++>10) // 若a與b同時大於10則離開

    break;

    因為 兩個判斷間是&&,所以當a++>10 是FALSE時就不會執行b++了!!

    所以當a=12時b才等於1

    a=13,b=2

    :

    :

    a=23,b=12

    才離開

    **有時你越想精簡程式,越容易出錯!!這時你不妨去debug,看每個變數的變化你就會發現怎樣寫最恰當了!!

    2006-10-24 21:46:07 補充:

    if(a++>10 && b++>10)我認為這不是最佳化的問題,是邏輯運算不熟所致,如果把此段轉成低階你就會發現程式變成a和10的比較,比較為大於時,加1然後JUMP到比較b和10的程式,比較為大於時,加1然後JUMP到LOOP外面!!

    2006-10-24 21:48:39 補充:

    && and & 本來意義就不同,樓上提出這個見解其實也是學習C的一個重要課題喔!!

  • 1 十年前

    int main()

    {

    unsigned char a=0,b=0;

    while(-1)

    {

    printf("\nA:%d B=%d\n",a,b); //test

    system("pause"); //test

    if(a++>10 && b++>10)

    break;

    }

    printf("\nA:%d B=%d\n",a,b);

    system("pause");

    return 0;

    }

    編譯器不可能壞掉@@~~ 懷疑編譯器前先懷疑自己才對@@

    if(a++>10 && b++>10)

    a++ 只會先到10以後 b 才會開始累加 .... 你自己查一下書 && 用法

    a++ 不大於10 就直接跳出 if () ... b++ 自然一直保持0 都沒變動 ... 當 a > 10 之後

    b++ 才有開始累加

    我程式加了兩段測試~~你看了就知道~~

    其實這種問題有時候滿難發現的 ~~ 你邏輯上沒有錯 ~~

    謝謝

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