2010-05-19 40 views
5

我有下面的代碼,我正在讀通過:C. ++ vs | =中的操作順序,首先發生?

if((i%2) == 0){ 
    *d = ((b & 0x0F) << 4); 
} 
else{ 
    *d++ |= (b & 0x0F); 
}; 

我在else聲明專門尋找並在此發生什麼樣的順序不知道?我沒有常規的C編譯器,所以我無法測試它。當我們執行*d++ |= (b & 0x0F);時,會發生什麼順序?

+0

哎喲,我很驚訝,也許不是那些第一次寫的人,並沒有說明他們爲什麼這麼寫。 – wheaties 2010-05-19 13:18:31

回答

11

將++應用於指針d上,而不是指定給的左值*d

如果你真的想,你可以認爲它是這樣的:

  1. b值是按位與:ED與恆0x0f
  2. 產生的位模式按位或:編入d指向的值。
  3. 指針d遞增以指向下一個值。
+0

因此,在所有操作都應用到原始位置之後,從指針移動到下一個位置。萬分感謝。 – chris 2010-05-19 13:22:56

+0

不一定;後綴運算符「++」的語義是在下一個序列點之前的某個時間應用副作用,但是沒有指定發生的時間。編譯器可以在執行任何其他操作之前將'* d'的結果存儲到臨時的並立即增加'd'。 – 2010-05-19 13:50:04

+0

@John:的確,這就是我寫「如果你真的想要」的原因。 – unwind 2010-05-19 13:55:23

0

This link(C++ Operator Precedence)應該給你答案。

2

首先執行|=的右側部分,然後完成*d |=分配,然後d遞增。通常當你有代碼導致這樣的問題時,爲了清楚起見,你應該重寫它。

5

d ++返回d增加前的值。然後通過*解除引用,該位置就是執行的操作。因此,在遞增d之前的位置處的數據將具有(b & 0x0F)。

一般來說,如果一行代碼中的操作順序一目瞭然,則會將該行重構爲其組成操作,直到它爲止。生成的代碼不會變得更快或更簡潔,只需將大量操作擠在一行C上即可!沒有理由以這種方式犧牲可理解性。將該行更換爲

*d |= (b & 0x0F); 
d++; 
+0

同意。不幸的是,這只是〜10,000行腳本中非常小的一部分,看起來非常相似。 – chris 2010-05-19 13:25:03

0

++首先完成。但是後增量(即d++)相當於這個(temp=d, d++, temp)

2

++將在|=之前發生。賦值運算符位於優先級圖的底部。

0

根據http://www.cppreference.com/wiki/operator_precedence

它會評估(B &爲0x0F)然後應用| =它並將其分配給* B,最後增加與* B指向中的價值。

+0

'| ='具有接近最低的優先級,你如何計算它將在增量運算符之前被評估,最高優先? – meagar 2010-05-19 13:22:01

0

表達*d++ |= (b & 0x0F)分解如下:

  1. 表達*d++b & 0x0F分別計算一次(在它們被評估未指定的順序;由於*d++之前編譯器可以自由地評估b & 0x0F結果不取決於評估的順序);
  2. (b & 0x0F)的結果按*d++的結果逐位或結果;
  3. 按位或運算的結果存儲到d最初指向的位置;
  4. 在這一切的某個點上,更新d的值。

將表達式*d++解析爲*(d++);即您正在取消參考表達式d++的結果。表達式d++評估爲當前值d,並且在某個未指定的點在下一個序列點之前(在這種情況下,語句結束),d的值被更新。更新d的副作用不必立即應用;它可以發生在作業之前或之後。