2010-05-16 71 views
2

我發現了一些我無法解釋的奇怪東西。如果某人在這裏可以看到發生了什麼或爲什麼,我想知道。我正在做的是含有高排列像這樣的12位無符號短:C中的位移和指針奇怪,尋找解釋

1111 1111 1111 0000

那麼我想希夫位,這樣在短期內保持7位與MSB作爲墊每個字節。在什麼上面給出的結果應該是這樣的:

0111 1111 0111 1100

我所做的是這樣的:

unsigned short buf = 0xfff; 
//align high 
buf <<= 4; 

buf >>= 1; 
*((char*)&buf) >>= 1; 

這讓我有點像看起來就像是正確的,但前一次換檔的結果葉位設置是這樣的:

0111 1111 1111 1100

很奇怪。如果我使用一個unsigned char用作臨時存儲和轉變,那麼它的工作原理,這樣的:

unsigned short buf = 0xfff; 
buf <<= 4; 

buf >>= 1; 
tmp = *((char*)&buf); 
*((char*)&buf) = tmp >> 1; 

這樣做的結果是:

0111 1111 0111 1100

任何想法是怎麼回事?

回答

4

是的,它看起來像char已在您的平臺上簽名。如果你做了*((unsigned char*)&buf) >>= 1,它會工作。

+0

是的!感謝您的解釋,現在正在工作。這讓我發瘋。 – foo 2010-05-16 18:12:56

1

讓我們打破這一點。我假定你的編譯器認爲16位內存很短。

unsigned short buf = 0xfff; 
//align high 
buf <<= 4; 

相當於:

unsigned short buf = 0xfff0; 

...和

buf >>= 1; 

應導致buf中具有值0x7FF8將(即第比特移位一位到右側)。現在爲您的花式線:

*((char*)&buf) >>= 1; 

很多事情在這裏......第一個左側需要解決。你所說的是將buf視爲指向8位內存的指針(而不是自然的16位)。 buf最初提到的兩個字節中的哪一個依賴於已知存儲器的端節點(如果它是big-endian buf指向0x7f,如果little-endian buf指向0xf8)。我假設你在一個英特爾盒子上,這意味着它的小端,現在buff指向0xf8。然後您的語句表示分配給該字節,該字節的值向右移動(並且自char被簽名後的符號擴展),或者0xfc。另一個字節將保持不變。如果你不需要任何符號擴展,請將buf加入(unsigned char *)。

+0

謝謝。這是沒有'unsigned'讓我:D。令人沮喪。 – foo 2010-05-16 18:24:06