2016-03-04 56 views
3

我想使用unsigned char作爲字節。我期望它的範圍從0255Usigned char超過255

我定義了下面的宏:

#define ROTATE_LEFT(BYTE) ((BYTE & 128) > 0) ? ((BYTE << 1) | 1) : (BYTE << 1) 

我想將它旋轉到左邊。

現在我測試的:

unsigned char c1 = 1; 
unsigned char c2 = 128; 
unsigned char c3 = 255; 
unsigned char c4 = 200; 
printf("%u\n", ROTATE_LEFT(c1)); // Expected: 2, Result: 2 
printf("%u\n", ROTATE_LEFT(c2)); // Expected: 1, Result: 257 
printf("%u\n", ROTATE_LEFT(c3)); // Expected: 255, Result: 511 
printf("%u\n", ROTATE_LEFT(c4)); // Expected: 145, Result: 401 

正如你所看到的,我得到的結果should't甚至可能。 有什麼不對?

+0

其實它不是未定義的行爲,請參閱下面的答案。但是,無論如何,「未定義的行爲」是一個您應該熟悉的概念,如果您使用C編程。 –

+4

如果您想使用固定大小的類型,請查看''。 –

+0

@MichaelWalz:其實就是這樣。一個'int'被傳遞並且'unsigned'被期望。 – Olaf

回答

10

這是因爲整數提升

在傳遞給printf之前,將結果提升爲更大的整數。

在將該變量傳遞給printf之前,可以將結果存儲回變量。它們必然會被截斷。

此外,unsigned charprintf說明符是%hhu

最後,我建議如下(未經測試),而不是:

static inline uint8_t rol8(uint8_t x) 
{ 
    uint8_t low = (x & (1<<7)) >> 7; 
    return (x << 1) | low; 
} 
+0

不,它不是在傳遞給printf之前,它是在評估無符號表達式的時候,嘗試'printf(「%zu \ n」,sizeof(ROTATE_LEFT(c2)));' – joop

+0

我沒有想到這個謝謝 – Goldi

+0

但是這個宏是正確的,對嗎? – Goldi

0

就像這樣:

unsigned char c4 = 200; 
printf("%u\n", c4 + 56); 

輸出:256

沒什麼做的unsigned charc4,您只需將一個大於255的值傳遞給printf函數。

相關問題