C
C 语法

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):