国际访客建议访问 Primers 编程伙伴 国际版站点 > C 教程 > 共用体 union 以获得更好的体验。

# C 语言的共用体 union

C语言中的共用体是一种特殊数据类型,它允许在同一内存中存储不同的数据类型。共用体的大小为其中最大成员的大小。

共用体的定义使用 union 关键字:

// 定义共用体类型
union 共用体类型名
{
    类型 变量名1;
    类型 变量名2;
    类型 变量名3;
    // ...
};

// 定义共用体类型的变量
struct 共用体类型名 变量名;

通过共用体类型的变量访问其内部成员时,使用 . 运算符;通过共用体指针类型的变量访问其内部成员时,使用 -> 运算符。

示例:

#include <stdio.h>
#include <stdbool.h>

// 定义枚举,表示事件类型
enum EventType
{
    QUIT_EVENT,
    KEY_EVENT,
    // ... 其它事件类型
};

// 定义结构体,表示退出事件的具体信息
struct QuitEvent
{
    enum EventType type;    // 事件类型,为 QUIT_EVENT
};

// 定义结构体,表示按键事件的具体信息
struct KeyEvent
{
    enum EventType type;    // 事件类型,为 KEY_EVENT
    int key;                // 按键编码
    bool press;             // 按下还是松开
};

// 定义共用体类型
union Event
{
    enum EventType type;  // 事件类型
    struct QuitEvent quit;  // 退出事件的信息
    struct KeyEvent key;    // 按键事件的信息
};

int main(void)
{
    printf("union Event 的大小为 %zu 字节\n", sizeof(union Event));
    printf("enum EventType 的大小为 %zu 字节\n", sizeof(enum EventType));
    printf("struct QuitEvent 的大小为 %zu 字节\n", sizeof(struct QuitEvent));
    printf("struct KeyEvent 的大小为 %zu 字节\n", sizeof(struct KeyEvent));

    // 定义事件变量
    union Event event;

    // 编辑事件内容
    event.type = KEY_EVENT;     // 事件类型为按键事件
    event.key.key = 'A';        // 按键为 A
    event.key.press = true;     // 按键被按下

    // 解析事件
    switch (event.type)
    {
    case QUIT_EVENT:
        printf("退出事件\n");
        break;

    case KEY_EVENT:
        printf("按键事件, '%c', %s\n", event.key.key, event.key.press ? "按下" : "松开");
        break;

    default:
        printf("未知事件\n");
        break;
    }

    return 0;
}

运行结果:

union Event 的大小为 12 字节
enum EventType 的大小为 4 字节
struct QuitEvent 的大小为 4 字节
struct KeyEvent 的大小为 12 字节
按键事件, 'A', 按下

这个示例中通过共用体实现了事件类型 union Event,包含成员 typequitkey;其中 key 最大,为 12 字节,因此 union Event 的大小为 12 字节。

这里 union Eventstruct QuitEventstruct KeyEvent 采用了相同的内存布局,即第一个字段都是 int type,用于保存事件类型。

在获取事件(union Event)后读取 type 字段判断事件类型,然后根据事件类型,采用不同的字段(quitkey)来解析事件内容。

flowchart TB
 subgraph subGraph0["struct QuitEvent"]
        qe0["type"]
  end
 subgraph subGraph1["struct KeyEvent"]
        ke0["type"]
        ke1["key"]
        ke2["press"]
  end
 subgraph subGraph2["union Event"]
        e0["type"]
        subGraph0
        subGraph1
  end
    e0 --> qe0 --> ke0

    style qe0 stroke:#00C853,fill:#C8E6C9
    style ke0 stroke:#00C853,fill:#C8E6C9
    style ke1 stroke:#00C853,fill:#C8E6C9
    style ke2 stroke:#00C853,fill:#C8E6C9
    style e0 stroke:#AA00FF,fill:#E1BEE7
    style subGraph0 stroke:#AA00FF,fill:#E1BEE7
    style subGraph1 stroke:#AA00FF,fill:#E1BEE7
    style subGraph2 stroke:#2962FF,fill:#BBDEFB
本文 更新于: 2025-11-27 09:38:06 创建于: 2025-11-27 09:38:06