Yahoo 知識+ 將於 2021 年 5 月 4 日 (美國東岸時間) 停止服務,而 Yahoo 知識+ 網站現已轉為僅限瀏覽模式。其他 Yahoo 資產或服務,或你的 Yahoo 帳戶將不會有任何變更。你可以在此服務中心網頁進一步了解 Yahoo 知識+ 停止服務的事宜,以及了解如何下載你的資料。
一個怪怪的問題..這是編譯器的問題嗎
以下程式結果為何呢?看到答案有點傻眼了 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 個解答
- RodyLv 51 十年前最愛解答
這是最佳化問題造成的因為你的判斷式當中, 你寫 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 61 十年前
附帶提幾個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++ 才有開始累加
我程式加了兩段測試~~你看了就知道~~
其實這種問題有時候滿難發現的 ~~ 你邏輯上沒有錯 ~~
謝謝