有些书说是,但下面的代码表明它不是真的
union
{
int n;
char array[5];
} u;
printf("%d %d %d", sizeof(u.n), sizeof(u.array), sizeof(u));
你怎么看?
联合体的大小必须满足两个要求:
需要后一条规则才能使数组起作用;当一个接一个地放置在内存中时,它可以保持联合正确对齐。
因此,如果最大元素是五个字节,但某些元素需要四字节对齐,则联合大小必须是大于或等于五个字节的四个字节的倍数。八个字节满足了这一点。
大多数 C 实现使用符合这两个规则的最小尺寸。
在这种情况下,联合在 32 位机器上与 4 个字节对齐(或在 64 位机器上与 8 个字节对齐),因此它在内存中看起来像这样:
11 11 11 11
11 XX XX XX
^ ^ ^
3 padded bytes
因此,为了对齐添加了额外的三个字节,这使得大小为 8。如果要更改此行为,您需要将其打包为 1 个字节:
#pragma pack(1)
union
{
int n;
char array[5];
} u;
#pragma pack()
现在联合的大小正好是 5,看起来像:
11 11 11 11
11
编译器通常根据对齐要求确定大小。在您的情况下,最大成员的大小是 5 并且对齐它使其成为 8。这是必需的,因为您可以声明此联合类型的数组。
该标准只保证a的大小union
对于最大的成员是足够的,即不一定是相同的大小。
C11 6.7.2.1 结构和联合说明符
a 的大小
union
足以包含其最大的成员。任何时候最多可以将其中一个成员的值存储在联合对象中。一个指向union
对象的指针,经过适当的转换,指向它的每个成员(或者如果一个成员是一个位域,那么指向它所在的单元),反之亦然。
当我在我的机器上运行您的示例时,输出是4 5 8
,可能 的大小union
被填充为机器字的倍数,就像struct
.