联合体声明

来自cppreference.com
< c‎ | language

联合体是一种由一序列的成员所组成的类型,成员的存储重叠(与结构体相反,结构体是由一序列的成员所构成的类型,成员的存储以顺序分配)。在任一时刻,最多能在联合体中存储其一个成员的值。

联合体的类型指定符结构体(struct类型指定符是相同的,只是所用的关键词有别。

目录

[编辑] 语法

union name(可选) { struct-declaration-list } (1)
union name (2)
name - 正在定义的联合体名称
struct-declaration-list - 任意数量的变量声明、位域声明,及静态断言声明。不允许不完整类型的成员和函数类型的成员。

[编辑] 解释

联合体只大到能保有其最大的成员(可能添加无名的尾随填充字节)。其他成员被分配在与最大成员的一部分相同的字节中。

指向联合体的指针能被转型成指向它每个成员的指针(若联合体拥有位域成员,则指向联合体的指针能被转型成指向位域的底层类型的指针)。类似的,指向结构体任何成员的指针都能被转型成指向整个结构体的指针。

若用于访问内容的联合体成员不同于上次存储值的成员,则存储的该值对象表示会被转译成新类型的对象表示(这被称为类型双关)。若新类型的大小大于上次写入的类型大小,则多出的字节内容是未指定的(而且可以是陷阱表示)。

类似结构体,类型是无name的联合体的无名联合体成员被称作匿名联合体。每个匿名联合体的成员被认为是包含它的整个结构体或联合体的成员。若整个结构体或联合体亦为匿名,则递归调用此规则。

struct v {
   union { // 匿名联合体
      struct { int i, j; }; // 匿名结构体
      struct { long k, l; } w;
   };
   int m;
} v1;
 
v1.i = 2;   // 合法
v1.k = 3;   // 非法:内层结构体不是匿名的
v1.w.k = 5; // 合法

类似结构体,若联合体的定义无任何具名成员(包含通过匿名嵌套结构体或联合体含有的成员),则程序行为未定义。

(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现为活跃成员
    printf("Union S has size %zu and holds %x\n", sizeof s, s.u32);
    s.u16[0] = 0x0011;  // s.u16现为活跃成员
    // 从s.u32或s.u8的读取转译对象表示
//  printf("s.u8 is now %x\n", s.u8); // 未指定,典型结果是11或00
//  printf("s.u32 is now %x\n", s.u32); // 未指定,典型结果是12340011或00115678
 
    // 指向联合体所有成员的指针彼此间比较相等,也与指向联合体的指针比较相等
    assert((uint8_t*)&s == &s.u8);
 
    // 此联合体拥有尾随的3个填充字节
    union pad {
       char  c[5];   // 占用5字节
       float f;      // 占用4字节,隐含对齐量4
    } p = {.f = 1.23}; // 大小为8以满足float的对齐
    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.u8之所以为s.u32之首字节之别名。

[编辑] 参考

  • C11 standard (ISO/IEC 9899:2011):
  • 6.7.2.1 Structure and union specifiers (p: 112-117)
  • C99 standard (ISO/IEC 9899:1999):
  • 6.7.2.1 Structure and union specifiers (p: 101-104)
  • C89/C90 standard (ISO/IEC 9899:1990):
  • 3.5.2.1 Structure and union specifiers

[编辑] 参阅

联合体声明C++ 文档