2011-10-27 112 views

回答

1
ip_vhl = (version << 4) | (headerlen & 0xf); 

然後字節將是這樣的:

VVVVHHHH 

要恢復原始值:

version = ip_vhl >> 4; 
headerlen = ip_vhl & 0xf; 
1
// Here we are trusting that version and length are both < 0xF 
unsigned char ip_vhl = (unsigned char)version << 4 | (unsigned char)length; 

unsigned char version = ip_vhl >> 4; 
unsigned char length = ip_vhl & 0xF; 
5

如果每個數字是4位,則y你將使用角色的最低8位。在很多情況下,這將是所有的位。

做它像這樣:

ip_vhl = ((version & 15) << 4) | (length & 15); 

假設version是你在高位想要的,和length是你在最下位想要的東西。 & 15確保每個值只有4位。對於length值,這主要是爲了避免在長度大於15時覆蓋專用於version的位。十進制常量15會被很多人寫成十六進制(如0xf0x0f),這是一個風格和品味的問題你覺得更清潔。

寫作的另一種方式「設置爲1 n個最右位的整數,且所有其它設置爲0」是((1 << n) - 1),並且因爲在這裏n = 4我們可以使用((1 << 4) - 1),這當然計算結果爲15

你的代碼似乎分length下來第一和商店,如果這是你想要做你包裝成單char之前應該這樣做,爲了清楚是什麼:(a)使用

length >>= 2; /* Convert from bytes to 32-bit words (or whatever). */ 
ip_vhl = ((version & 15) << 4) | (length & 15); 
+4

0xf代替15看起來更好 – ThiefMaster

+0

@ThiefMaster:這是一個味道問題,我猜...這是一個字符更長。但我會編輯提及它。 – unwind

+0

我發現了位掩碼的六角清理器,因爲它與位模式非常直接相關。並不意味着我總是使用十六進制,但;-) –

2

版本位字段

struct entry { 
    unsigned char version : 4; 
    unsigned char length : 4; 
} ip_vhl; 

ip_vhl.version = version; 
ip_vhl.length = length; 

版(b)中算術

ip_vhl = (version << 4) | (length & 0xF) 
version = ip_vhl >> 4; 
length = ip_vhl & 0xf; 
+1

根據C99標準,位字段是特定於實現的。可能不支持_Bool和int類型(有符號和無符號)。位字段的順序是實現定義的。他們需要多少內存也是特定於實現的(可能需要超過必要的)。與對齊相同。 –

+0

@Alex具體使用情況取決於您的需求。位字段可能非常有用。 – Artyom

+0

我沒有說他們沒有/不能用。我只是警告說,他們可能不是正確的或便攜式的解決方案。 –

1

此外,您還可以再打一個結構與位域:

typedef struct s_ip_vhl 
{ 
    int version : 4; 
    int header_length : 4; 
} ip_vhl_type; 

ip_vhl_type my_ip_vhl; 
my_ip_vhl.version = 4; 
my_ip_vhl.header_length = 5; 
unsigned char byte = *((byte*)(&my_ip_vhl)); 

或者你可以打包帶無符號字符工會的結構一氣呵成地將整個字節:

typedef union u_ip_vhl 
{ 
    typedef struct s_ip_vhl 
    { 
     int version : 4; 
     int header_length : 4; 
    } ip_vhl_type; 
    unsigned char byte; 
} ip_vhl_union; 
+0

請參閱我的評論[此答案](http://stackoverflow.com/questions/7913760/c-storing-2-numbers-in-one-byte/7913806#7913806) –