2011-05-29 46 views
3

çFAQ問題16.7:http://c-faq.com/strangeprob/ptralign.html爲什麼C FAQ問題16.7中的不一致行?

我有一個關於該行的一個問題:

s.i32 |= (unsigned)(*p++ << 8); 

我理解該行代碼是如何工作的,但我不明白爲什麼它不是簡單地寫成要麼:

s.i32 |= (long) *p++ << 8; 

或:

s.i32 |= (unsigned)*p++ << 8; 

這是爲什麼?

===========================

struct mystruct { 
    char c; 
    long int i32; 
    int i16; 
} s; 

char buf[7]; 
unsigned char *p; 
fread(buf, 7, 1, fp); 
p = buf; 

s.c = *p++; 

s.i32 = (long)*p++ << 24; 
s.i32 |= (long)*p++ << 16; 
s.i32 |= (unsigned)(*p++ << 8); // line in question 
s.i32 |= *p++; 

s.i16 = *p++ << 8; 
s.i16 |= *p++; 

============

更新:

它仍然不是很清楚,我爲什麼鑄件必須做到移位操作有問題的線路。也許正如littleadv所說:「這是一個例子,不是唯一的可能性」。

如果我提出的兩種選擇有什麼問題,請添加您的答案。現在我選擇littleadv的評論作爲答案,雖然演員的優先順序和< <並不是真的讓我困惑。

P.S.我無法將問題提交給FAQ的作者,因爲他不再通過電子郵件接受任何問題。

回答

6

由於鑄造是在上面的order of precedence<<,並且希望鑄件上的<<結果。

「此代碼假定的getc讀取8:

編輯爲澄清

原因鑄造完成long轉移之前,以及unsigned變速後的different question with the same code解釋並且數據首先被存儲爲最高有效字節(``big endian'')。強制轉換(long)確保16位和24位移位對長值操作(見問題3.14),而投到(無符號)警衛以防止延長簽名(一般來說,這是編寫這樣的代碼時更安全地使用所有未簽名的類型,但請參閱問題3.19)。「

+0

那麼,爲什麼同樣的理由不適用於前面兩行? – Nemo 2011-05-29 05:24:38

+0

在執行移位操作之前將* p ++轉換爲unsigned(int)會出現什麼問題? – 2011-05-29 05:25:50

+0

我想這個問題是:爲什麼沒有對兩行使用'<< 16'和'<< 24' – ChrisWue 2011-05-29 05:27:47