2010-12-03 157 views
8

對於這裏的專家來說,這可能是非常基本的或者甚至是愚蠢的,但是我想讓我的頭腦解決這個問題。大部分的時間我一般寫這樣的十六進制值在C:解釋十六進制值?

unsigned int a = 0xFFFF1232; 

比方說,我想提取的第一個和最後一個16位的話,我可以簡單地做:

unsigned short high = a >> 16; // Gives me 0xFFFF 
unsigned short low = a & 0x0000FFFF; // Gives me 0x000which is then stored as 0x1232 

在一些代碼我讀我所遇到如下:

unsigned short high = a >> 16; 
unsigned short low = a & 0xFFFF; 

我有兩個問題

  • 當您使用掩碼爲AND 32位值時,爲什麼人們會寫0xFFFF而不是0x0000FFFF?它保持緊湊嗎?
  • 編寫0x0000FFFF作爲0xFFFF總是安全嗎?它在任何情況下都有不同的解釋嗎?

回答

7

它們完全是同義詞。排除前導零使得它更具可讀性。

+0

我認爲哪一個「更具可讀性」是有爭議的,可以解釋,但是+1。 – 2010-12-03 22:38:28

+0

我寧願說「不太可讀」(例如:今天是00000002010/00000000012/00000000004)。 – ruslik 2010-12-03 22:38:54

+0

@xscott:編寫`char c = 0x000000000000000000001'是完全合法的;`只有當實際值(而不是它的表示)超過目標的大小時纔會收到警告, – ruslik 2010-12-03 22:48:47

2

在你的例子中lowshort(通常是16位)。因此,前導零不僅是多餘的,他們建議預期32位結果,在這種情況下,高位被丟棄,所以可以說它使得代碼的意圖更清晰。

事實上,在這種情況下

unsigned short low = a ; 

就足夠了,但也許是不太清楚。

而且你不應該假設整數寬度是適當的,並使用<stdint.h>類型,而不是:

uint32_t a = 0xFFFF1232; 
uint16_t = a >> 16; 
uint16_t = a & 0xFFFF; 

如果你使用VC++不提供這個頭,你可以使用this implementation

3

他們是相同的。

而且,你假設整數總是32位長。如果你的平臺碰巧使用64位整數,你會這樣寫嗎?

unsigned short low = a & 0x000000000000FFFF; // ouch. Did I count them right? 

而且還有另外一個原因,爲什麼你不應該浪費時間投入前導零:你會試着和小數做下一個,這是一個壞主意:

int x = 00000377 

printf("%d\n", x); // 255! WTF.... 
1

喜歡的東西0x1被稱爲文字,默認爲一個int類型。這不一定是32位,這取決於編譯器或平臺,所以是的,存在一種上下文不安全的情況,即忽略前導零。

例如,在嵌入式系統中,常見的是隻有16位長的int類型。如果你想要一個更長的整數,你需要使用long int。

在這種情況下,編譯器會通知您是否忘記將「L」附加到十六進制文字中,以表明您需要更長的類型。

unsigned int a = 0xFFFF1234; 

最好是編譯器錯誤,或最壞的情況下是未檢測到的錯誤。您需要使用

unsigned long int a = 0xFFFF1234L; 

改爲。

1

你的情況0x0000FFFF和0xFFFF是相同的。

如果您的變量不是無符號的,則不會出現這種情況:0xFFFF的16位值意味着-1,即32位中的0xFFFFFFFF。