我需要你的帮助来理解位字段在C编程中的工作原理。
我已经宣布了这个结构:
struct message
{
unsigned char first_char : 6;
unsigned char second_char : 6;
unsigned char third_char : 6;
unsigned char fourth_char : 6;
unsigned char fifth_char : 6;
unsigned char sixth_char : 6;
unsigned char seventh_char : 6;
unsigned char eigth_char : 6;
}__packed message;
我使用sizeof(message)将结构的大小保存为整数。
我认为大小的值将是6,因为6 * 8 = 48位,这是6个字节, 但它的大小值为8个字节。
任何人都可以向我解释原因,以及比特字段及其对齐的确切方式如何?
修改
我忘了解释我使用struct的情况。
假设我以这种形式接收6字节的数据包:
void * packet
message * msg = (message *)packet;
现在我想打印每个成员的值,所以虽然我将成员声明为6位,但成员使用8位,这会导致打印时出错。 例如,我收到下一个数据:
00001111 11110000 00110011 00001111 00111100 00011100
我认为成员的价值如下所示:
first_char = 000011
second = 111111
third = 000000
fourth = 110011
fifth = 000011
sixth = 110011
seventh = 110000
eigth = 011100
但这不是什么hapening,我希望我解释得很好,如果不是,请告诉我。
答案 0 :(得分:3)
位字段不必跨越不同的底层元素(“单元”),因此您正在目睹每个字段占用整个unsigned char。行为是实现定义的,thoug;比照C11 6.7.2.1/11:
实现可以分配足够大的任何可寻址存储单元来保存位字段。如果剩余足够的空间,则紧跟在a中的另一个位字段的位字段 结构应打包到同一单元的相邻位。如果剩余空间不足, 是否将不适合的位域放入下一个单元或重叠相邻单元 实现定义。单位内位域分配的顺序(高位到 实现定义的是低阶或低阶到高阶。对齐 可寻址存储单元未指定。
此外,通过6.7.2.1/4中的约束,没有比特字段可能大于适合单个单元的比特字段:
指定位域宽度的表达式应为整数常量 具有非负值的表达式,该值不超过对象的宽度 将指定的类型是冒号和表达式省略。