2017-02-12 95 views
-3

算術運算符誰能幫我解決這個問題邏輯程序:增量,和c

void main() 
{ 
    int num, a=5; 
    num = -a-- + + ++a; 
    printf("%d %d\n", num, a); 
} 

答:0 5

怎麼會呢?任何人都可以解釋背後的邏輯?

+3

沒有人能解釋它,因爲表達式沒有意義。 –

+0

注意[main()應該在C和C++中返回什麼?](http://stackoverflow.com/questions/204476/) –

回答

0

曾幾何時,我看到兩個積極進取的波士頓司機試圖在同一個停車位停車,以至於他們實際上將車撞向對方。非常像這樣的事情發生在這裏。

此代碼還有其他錯誤,但我們只關注存儲在a中的內容。如果我們想象表達式a-- + ++a從左到右進行評估,則首先發生的是a--部分。 a起始爲5,因此a--的值爲5,並將註釋存儲到a中。想象一下,這張紙條是交給第一輛車的司機。

接下來我們來到++a。現在假設將4存儲到a的消息尚未完成。所以++a的值是6,有一個註釋可以將6存儲到a中。想象一下,這張紙條是給第二輛汽車的司機交付的。

一個大問題是,什麼是num的最終價值,但我現在並不擔心這一點。讓我們來問一下,a的最終價值是多少?我們有一個車手試圖​​將其設置爲4,另一個試圖設置爲6.但是隻有一個停車位標記爲a。也許第一個驅動程序首先到達那裏,並將其設置爲4,或者第二個驅動程序到達那裏並將其設置爲6.或者,他們可能在同一時間到達那裏,並碰撞到對方,並且a被設置爲扭曲來自第二輛車前保險槓的一塊金屬。 (也許這個扭曲的金屬片看起來有點像5號,所以打印5是最好的printf可以做的。)

正如我所說的,這個代碼還有其他的錯誤。首先,我們不應該想象它會從左到右進行評估;根本不能保證。我們也不知道++a部分是否應以a的原始值或受a--影響的值運行。事實上,我們不知道這個表達式應該做什麼,而且可能令人驚訝的事實是,編譯器也不知道,不同的編譯器會以不同的方式解釋這樣的表達式,給出截然不同的答案。沒有一個答案是正確的,沒有錯,因爲這個表達式是undefined

該表達式是未定義的,因爲在它內部有兩次不同的嘗試來爲a分配一個新值。 (你會在鏈接的答案中找到更多未定義行爲的正式定義。)因此,避免未定義行爲的一個簡單規則是「不要試圖在一個表達式中設置變量的值兩次」。

你可能會認爲這個表達應該有一個明確的解釋。您可能會認爲顯然應該從左到右進行評估。您可能會認爲a--應該立即將新值存儲到a,以確保它是表達式「稍後」部分所看到的值。你可能會想到這些事情,而且他們可能對某些其他編程語言是真實的,但不是C.C確實不是保證表達式嚴格按照從左到右的順序進行評估,並且確實不是保證a--++a立即更新a的值。試圖在一個表達式中更新a的值兩次會導致未定義的行爲,未定義的行爲意味着可能發生任何事情。