2012-12-05 54 views
1

任何人都可以解釋一下,新手C程序員會理解這個函數的作用麼?解釋這個函數的作用

unsigned getunsigned(unsigned char *bufp, int len) { 
    unsigned value = 0; 
    int shift = 0; 
    while (len--) { 
     value |= *bufp++ << shift; 
     shift += 8; 
    } 
    return value; 
} 

我想這是給我的最麻煩繞到我的頭行:

value |= *bufp++ << shift; 

而且,任何人都可以提供一種方式來重新寫這個所以這是更清晰一個沒有經驗的C程序員要了解?

我在做一項任務研究的同時在網上發現了這個代碼,我不想使用它,除非我完全理解它在做什麼以及它是如何做的。

+0

'* bufp ++'應該在左移之前轉換爲'unsigned'。否則,默認情況下它會被提升爲「int」,並且當移位爲最高字節時,結果可能會超過int中可表示的結果。那麼行爲是不確定的。 –

回答

5

這正在從緩衝器通過bufp指向連續的字節,並且將它們放入value

value |= *bufp++ << shift;正在值在bufp(即,在charbufp指向的地址),並用的value 8個比特或運算它。然後它遞增bufp指向緩衝區中的下一個字節。之後,它增加了8到shift - 這就是確定其中的8位value新字節得到了或。即,shift開始爲0,所以在第一次迭代中,bufp的第一個字節替換了value的底部8位(替換,因爲它們開始爲0)。在下一個迭代器中,bufp的下一個字節被左移8個字節,以取代value的接下來的8個位,依此類推爲len個字節。

另外:如果len大於sizeof(unsigned),這會寫在value的末尾,導致未定義的行爲。

+0

我現在明白了。感謝您的詳細解釋。 –

1
value |= *bufp++ << shift; 

相當於

value = value | (*bufp << shift); 
bufp++; 
+1

@rekire。一點都不。您應該仔細閱讀[按位或](http://en.wikipedia.org/wiki/Bitwise_operation)是如何工作的。唯一的時間是等價的,如果操作數的按位相交(AND)爲零。換句話說,'0x10 | 0x04 == 0x10 + 0x04 == 0x14'。但'0x10 | 0x10!= 0x10 + 0x10' –

+0

實際上,它等於'value =(uint8_t)(value |((int)* bufp << shift)); bufp ++;'因爲整數升級。在這種特殊情況下,我認爲整數升級不會導致任何錯誤。 – Lundin

+0

@Lundin:當'* bufp'被提升爲一個int並左移時,它可能會產生一個無法在int中表示的值。那麼行爲是不確定的。 –

1
value |= *bufp++ << shift; 

等效於在bufp

value = value | (*bufp << shift); 
bufp++; 

第一值被移位到移位值和所得到的是或運算|value然後bufp遞增。

在換擋最後值由shift +=8改變意味着shift = shift + 8

因此,需要在bufp所有字節,因爲while循環將不會終止,直到len變得0