當前位置: 華文星空 > 知識

i=1,為什麽 (++i)+(++i)=6?

2020-09-18知識

出這種UB(Undefined Behaviour)題目很無聊,這個我已經多次說過了。在實際工作當中寫這種程式碼的首先就應該拉出去斃了。

無論是4,還是5,還是6,都是錯的。因為這是個UB,沒有標準答案。

但是為什麽我還是來答這種問題,因為我認識到這種問題被頻頻拿出來考新手,是因為新手很容易在這裏翻車。而研究新手為什麽很容易在這裏翻車,我覺得是有意義的。

所以本回答旨在探討新手為什麽容易在這裏翻車,思維的陷阱到底在哪裏。(本回答並不是為了解釋這個UB的成因本身,本回答其實也不太適合對電腦組成原理不熟悉的同學,當然你要看我也沒辦法,但是包教不包會,據此面試後果自負)

++i,如果單獨寫成一個語句,等同於i=i+1。我想這個應該沒有人有問題。

但是其實這裏應該是有問題的,特別是新手。對於新手來說,如果沒有意識到這裏的問題,那麽就很可能在上面那個題目當中翻車。

什麽問題呢?

i=i+1,這個式子,在數學上是不成立的。或者說是無解的。(為防止被數學大佬噴,限定一下在初等數學範圍內。。。)

也就是說,程式當中的運算式,並不是完全等同於數學公式。因此,不能以代數方程式的理念去理解它。

程式當中的i=i+1,其實應該理解為:從一個名叫i的地方(記憶體空間)取出一個數,將其加1,然後放入名叫i的地方。

也就是,程式當中的運算式,其實只是一系列語句(statement)的簡寫。i=i+1寫成完整語句,其實是:

  1. load i -> 某CPU寄存器
  2. 將該寄存器內容+1
  3. save該寄存器內容 -> i

所以,(++i)+(++i)的意思其實是:

  1. load i -> 某CPU寄存器 (第一個括弧
  2. 將該寄存器內容+1
  3. save該寄存器內容 -> i
  4. load i -> 某CPU寄存器 (第二個括弧
  5. 將該寄存器內容+1
  6. save該寄存器內容 -> i
  7. load i -> 某CPU寄存器 (兩個括弧之間
  8. load i -> 另一個CPU寄存器
  9. 將兩個寄存器內容相加

(但是註意雖然上面編了序號,但是1-3和4-6之間其實是並列關系,並非要按照序號順序執行。7和8也是並列關系,可以按任何順序執行。而這種執行的順就是導致這個問題是個UB問題的原因)

這樣就應該沒有人還是認為結果一定是4了吧。

新手掉坑裏的原因就在於,把程式當中的運算式當作數學式子,把其中的字母當作未知數。

而理解運算式並不等同於數學式子,變量也不等同於未知數,在我看來是此類問題唯一的價值。

2001/02/19 補充: