在Windows C/C++中使用半字节(4位变量)

Eri*_*ric 19 c c++ windows types

我正在编程网络标头,许多协议使用4位字段.我可以使用方便的类型来表示这些信息吗?

我发现的最小型是BYTE.然后我必须使用大量的二进制操作来仅引用该变量中的几个位.

Meh*_*ari 34

由于存储器是字节寻址的,因此不能寻址小于单个字节的任何单元.但是,您可以构建struct要通过网络发送的内容并使用以下位域:

struct A {
   unsigned int nibble1 : 4;
   unsigned int nibble2 : 4;
};
Run Code Online (Sandbox Code Playgroud)


Chr*_*fer 16

扩展Mehrdads答案,也使用带字节的联合,以避免一些看似邪恶的演员:

union Nibbler {
     struct { 
        unsigned int first:4;
        unsigned int second:4;
     } nibbles;
     unsigned char byte_value;
}
Run Code Online (Sandbox Code Playgroud)


D.S*_*ley 6

每个人似乎都喜欢在structs中使用位字段.就个人而言,我将所有的数据包代码都包装在对象中,这样你就看不到内容了.我在使用协议代码的位字段时发现的问题是它鼓励使用结构作为内存上的叠加.你可以安全地做到这一点,但你必须非常小心,以确保你正确处理endianess和包装问题.除非你真的有充分的理由(例如,你正在编写从内存映射IO区域接收以太网数据包的代码),否则使用内存上覆盖的位字段会产生极其脆弱的代码恕我直言.

我发现编写一个Packet以不同位宽实现提取,插入和覆盖例程的类要容易得多.然后,您可以根据从偏移量中提取特定宽度的值到本机整数来实现数据包处理代码.隐藏抽象背后的所有endianess和打包问题,直到分析证明开销太大而无法承受.

这是我希望多年前学过的课程之一......您可能认为代码的可移植性不是问题,也不是endianess.相信我,当您的编译器更改其填充算法或切换到不同的编译器时,这会导致您的头痛次数将使您确信叠加对于网络数据包处理代码来说是一个非常糟糕的主意.