u_char ip_vhl; /* version << 4 | header length >> 2 */
我無法弄清楚,這是如何完成的? 你能給我如何使用這個字節來存儲這些2號 知道,每一個都是例子4位C在一個字節中存儲2個數字
u_char ip_vhl; /* version << 4 | header length >> 2 */
我無法弄清楚,這是如何完成的? 你能給我如何使用這個字節來存儲這些2號 知道,每一個都是例子4位C在一個字節中存儲2個數字
ip_vhl = (version << 4) | (headerlen & 0xf);
然後字節將是這樣的:
VVVVHHHH
要恢復原始值:
version = ip_vhl >> 4;
headerlen = ip_vhl & 0xf;
// 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;
如果每個數字是4位,則y你將使用角色的最低8位。在很多情況下,這將是所有的位。
做它像這樣:
ip_vhl = ((version & 15) << 4) | (length & 15);
假設version
是你在高位想要的,和length
是你在最下位想要的東西。 & 15
確保每個值只有4位。對於length
值,這主要是爲了避免在長度大於15時覆蓋專用於version
的位。十進制常量15
會被很多人寫成十六進制(如0xf
或0x0f
),這是一個風格和品味的問題你覺得更清潔。
寫作的另一種方式「設置爲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);
版本位字段
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;
根據C99標準,位字段是特定於實現的。可能不支持_Bool和int類型(有符號和無符號)。位字段的順序是實現定義的。他們需要多少內存也是特定於實現的(可能需要超過必要的)。與對齊相同。 –
@Alex具體使用情況取決於您的需求。位字段可能非常有用。 – Artyom
我沒有說他們沒有/不能用。我只是警告說,他們可能不是正確的或便攜式的解決方案。 –
此外,您還可以再打一個結構與位域:
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;
請參閱我的評論[此答案](http://stackoverflow.com/questions/7913760/c-storing-2-numbers-in-one-byte/7913806#7913806) –
0xf代替15看起來更好 – ThiefMaster
@ThiefMaster:這是一個味道問題,我猜...這是一個字符更長。但我會編輯提及它。 – unwind
我發現了位掩碼的六角清理器,因爲它與位模式非常直接相關。並不意味着我總是使用十六進制,但;-) –