2011-03-14 97 views
1

請解釋在每種情況下工作。解釋這個C程序的工作

爲什麼這兩種情況具有相同的輸出?

案例一:

int main (void) 
{ 
    int i = 5; 
    if(i == ++i)   //plz explain here How values are checked 
     printf("Equal"); 
    else 
     printf("Not Equal"); 

    return 0; 
} 
//Output: Equal; 

案例二:

int main (void) 
{ 
    int i = 5; 
    if(++i == i)   //plz explain here How values are checked 
     printf("Equal"); 
    else 
     printf("Not Equal"); 

    return 0; 
} 
//Output: Equal; 

回答

10

無論這些方案是有效的;您不允許讀取和更新相同的變量,而沒有中間的序列點。因此,這些程序都是未定義的行爲,因此它們可能碰巧在你的編譯器和機器上返回相同的答案並不意味着什麼。

+0

但是這兩個程序都正確執行 – 2011-03-14 04:20:01

+7

@Javed Akram:是的 - 未定義行爲的一個可能結果是代碼似乎正常工作,甚至可能產生您期望的結果。再次,它可能不會做任何一個。當然,最常見的結果是,它似乎在測試中運行良好,然後在爲客戶端演示時做了一些可怕的事情。 – 2011-03-14 04:22:57

+0

@Jerry好吧,我不認爲機器代碼會因演示而波動,但請嘗試切換編譯器(即使是簡單的升級也可以做到這一點),看看你什麼時候開始哭泣。 – stefan 2011-03-14 04:24:43

0

它是相等的,因爲這是C.另一個回答說,這個操作的結果是不確定的,因爲你違反了C規則 - 這意味着在切換編譯器時你不能保證相同的答案(儘管所有的編譯器可能是實施類似,這並不能保證)。 C允許你在腳下拍攝自己的事實並不意味着這樣做是一種好的做法。

現在,它爲什麼會起作用?

猜想#1:

i可以被存儲在寄存器中,說r1,並且編譯器可被編譯此整個比較成一個單一的CMP指令,具有自動增量的尋址模式。假設它是CMP ++r1, r1CMP r1, ++r1,然後根據實際的CPU,兩者可能會返回一個真正的比較結果。

猜想#2:

編譯器可編譯比較爲:

inc r1 // increment r1 
CMP r1, r1 // compare with itself 

猜想三:

編譯器可優化,始終把一個簡單的變量訪問右側。它可以這樣做,因爲==運算符中的執行順序是未定義的,編譯器可以按照它的喜好重新排列。

相關問題