u_char ip_vhl; /* version << 4 | header length >> 2 */
我做不到,这是怎么做到的? 你能举例说明如何使用这个字节存储这两个数字 知道每一个都是4位
答案 0 :(得分:5)
如果每个数字是4位,则您将使用该字符的最低8位。在许多情况下,这将是所有的位。
这样做:
ip_vhl = ((version & 15) << 4) | (length & 15);
假设version
是您想要的高位,length
是您想要的最低位。 & 15
确保每个值仅为4位。这主要是length
值所需要的,以避免在长度大于15时覆盖专用于version
的位。十进制常量15
将以十六进制写入({{1许多人认为风格和品味都很清晰。
另一种编写“n个最右边的位设置为1,其他所有设置为0的整数”的方法是0xf
,因为0x0f
,我们可以使用((1 << n) - 1)
},当然评估为n = 4
。
您的代码似乎首先将((1 << 4) - 1)
分开并保存,如果这是您想要做的,您应该在将其打包到单个15
之前执行此操作,为清楚起见:
length
答案 1 :(得分:2)
版本(a)使用位字段
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;
答案 2 :(得分: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;
答案 3 :(得分:1)
ip_vhl = (version << 4) | (headerlen & 0xf);
然后字节将如下所示:
VVVVHHHH
要取回原始值:
version = ip_vhl >> 4;
headerlen = ip_vhl & 0xf;
答案 4 :(得分: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));
或者您可以使用带有unsigned char的联合打包结构,以便一次性获取整个字节:
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;