Union declaration
Union declaration
联合是由存储重叠的成员序列组成的类型(与结构相对,结构是一种由存储按有序序列分配的成员序列组成的类型)。至多一个成员的价值可以在任何时候存储在工会中。
struct
除了使用的关键字之外,联合的类型说明符与 类型说明符相同:
句法
联合体名称(可选){结构声明列表} | (1) | |
---|---|---|
工会名称 | (2) | |
name | - | 正在定义的联盟的名称 |
---|---|---|
结构声明列表 | - | 任何数量的变量声明,位域声明和静态断言声明。不完整类型的成员和函数类型的成员是不允许的。 |
说明
工会的规模只有持有其最大成员所需的那么大(另外还可以添加未命名的追尾填充)。其他成员以相同字节分配,作为该最大成员的一部分。
指向联合的指针可以转换为指向其每个成员的指针(如果联合有位字段成员,指向联合的指针可以转换为指向位字段的基础类型的指针)。同样,可以将指向任何联合成员的指针转换为指向包围联合的指针。
如果用于访问联合的内容的成员与上次用于存储值的成员不相同,则存储的值的对象表示将被重新解释为新类型的对象表示(这称为类型打孔
)。如果新类型的大小大于最后写入类型的大小,则超出字节的内容未指定(并且可能是陷阱表示)。
与struct类似,类型为无名称的联合的联合的未命名成员称为匿名联合。匿名联盟的每个成员都被认为是封闭结构或联盟的成员。如果封闭的结构或联合也是匿名的,则这将递归应用。struct v {union {//匿名联合结构{int i,j; }; //匿名结构struct {long k,l; } w; }; int m; } v1; v1.i = 2; //有效v1.k = 3; //无效:内部结构不是匿名的v1.wk = 5; // valid类似于struct,如果union没有任何命名成员(包括通过匿名嵌套结构或联合获得的)定义,则程序的行为是未定义的。 | (自C11以来) |
---|
关键词
union
.
笔记
有关结构和联合初始化的规则,请参阅结构初始化。
例
#include <stdio.h>
#include <stdint.h>
#include <assert.h>
int main(void)
{
union S {
uint32_t u32;
uint16_t u16[2];
uint8_t u8;
} s = {0x12345678}; // s.u32 is now the active member
printf("Union S has size %zu and holds %x\n", sizeof s, s.u32
s.u16[0] = 0x0011; // s.u16 is now the active member
// reading from s.u32 or from s.u8 reinterprets the object representation
// printf("s.u8 is now %x\n", s.u8 // unspecified, typically 11 or 00
// printf("s.u32 is now %x\n", s.u32 // unspecified, typically 12340011 or 00115678
// pointers to all members of a union compare equal to themselves and the union
assert((uint8_t*)&s == &s.u8
// this union has 3 bytes of trailing padding
union pad {
char c[5]; // occupies 5 bytes
float f; // occupies 4 bytes, imposes alignment 4
} p = {.f = 1.23}; // the size is 8 to satisfy float's alignment
printf("size of union of char[5] and float is %zu\n", sizeof p
}
输出:
Union S has size 4 and holds 12345678
size of union of char[5] and float is 8
每个成员都被分配好像它是唯一的成员,这就是为什么s.c
在上面的例子中第一个字节是别名s.s[0]
。
参考
- C11标准(ISO / IEC 9899:2011):