打印一个 2 字节的数据包

Printing a 2 bytes packet

有一个2字节的数据包。前 5 位代表版本,接下来的 5 位代表类型,最后 6 位代表值。我将数据包作为 char* 传递给函数 (print_pak)。在该函数中,我想打印版本、类型和数据包值。我该怎么做?

void print_pak(char* pak)
{
}

为此您需要使用位掩码和移位。此外,在进行位操作时,我认为最好使用无符号整数类型,因为 C 标准未定义负整数的二进制表示形式。

void
print_pak(const unsigned char *pak)
{
    unsigned char version, type, value;

    version = (pak[0] >> 3);
    type = ((pak[0]&0x07) << 2) + (pak[1] >> 6);
    value = pak[1]&0x3f;

    printf("Version = %u, Type = %u, Value = %u\n", version, type, value);
}

这是它的工作原理。 <<>> 运算符用于位移。假设您有一个 unsigned charx,它保存位 10111010。将其右移 3 位是由 (x >> 3) 完成的(运算符优先级在进行位操作时总是让我感到困惑,所以我抛出括号内是安全的)。右边的三个钻头哪儿也去不了,所以它们掉了下来。结果是 00010111。向左移动也一样(有点)。

位掩码,&,实现二进制“与”。也就是说,如果 x 是 10101011 而 y 是 00011111,那么 x&y 只有 1,其中 xy 共享它们。所以,它将是 00001011。

让我们利用所有这些来解决您的问题。版本是第一个字节的前五位。因此,我们要右移低三位。

类型是第一个字节的最后三位和第二个字节的前两位。第一组可以通过屏蔽掉第一个字节的高五位来获得(0x07 在二进制中是 00000111)。第二组可以通过将第二个字节右移六位来获得。然后,要将它们放在一起,您需要将第一组左移两位,以便为第二组腾出空间。

最后,该值为第二个字节的低六位,可以通过简单屏蔽这些位来获得(0x3f二进制为00111111)。