【发布时间】:2019-06-26 14:06:47
【问题描述】:
我尝试使用具有不同大小位域的结构。使用的总位数为 64。但是,当我检查结构大小时,我得到 11 而不是预期的 8。通过尝试分解结构,我发现差异来自 day 字段。如果我打包每个位以获得 8 位包,则 day 字段在 month 的“结束”和 hour 的“开始”之间打包时间>。我不知道这是否是一个好方法。有人可以解释一下吗?
typedef unsigned char uint8_t;
typedef struct frameHeader_t
{
uint8_t encryption : 2;
uint8_t frameVersion : 2;
uint8_t probeType : 4;
uint8_t dataType : 5;
uint8_t measurePeriod : 3;
uint8_t remontePerdiod : 4;
uint8_t nbrMeasure : 2;
uint8_t year : 7;
uint8_t month : 4;
uint8_t day : 5;
uint8_t hour : 5;
uint8_t minute : 6;
uint8_t second : 6;
uint8_t randomization : 5;
uint8_t status : 4;
}FrameHeader;
int main()
{
FrameHeader my_frameHeader;
printf("%d\n", sizeof(FrameHeader));
return 0;
}
【问题讨论】:
-
您可能需要
#pragma pack或类似的(取决于您的编译器,或者更准确地说,编译器的预处理器)。year字段“着陆”在两个字节上,因此很可能它是由编译器填充的。随后,它后面的一些字段也“降落”在两个字节上,因此应用了更多填充。 -
问题是这样的:“...一个预期的 8”。没有预期的位域大小。它们不能可靠地用于内存映射。
-
在纯 C 中,不能保证结构的内存布局。
-
在 C 中,打包位域的传统方法是将它们打包到大小与声明的整数类型相同的整数中。因此,在您的示例中,它们将被打包成 8 位整数。如果一个位域不合适,它会跳到一个新的整数。我相信从那时起包装要求已经放宽了,但这仍然是一种常见的策略。所以在你的情况下,包装是 (1) 2, 2, 4 (2) 5, 3 (3) 4, 2 (4) 7 (5) 4 (6) 5 (7) 5 (9) 6 (9) 6 (10) 5 (11) 4. 所以你最终得到 11 个 8 位整数。如果您想改进打包,请切换到更大的整数类型,例如
uint32_t.
标签: c struct bit-fields