5.2 共用体

本篇学习共用体的共享存储特性,并能理解它与结构体在内存布局和使用方式上的根本区别。

共用体

概念说明

共用体和结构体一样,也能把多个成员组织在一起。 但共用体的所有成员共享同一块内存,因此同一时刻通常只适合把其中一个成员当成有效值来使用。

这让共用体在节省空间、做协议解析或与底层数据布局交互时很有用。 不过它的使用前提是你必须非常清楚当前内存里到底按哪种成员解释。

在实际项目里,如果要安全表达“当前到底是哪一种值”,通常会把 union 和一个额外的标签字段搭配使用,也就是所谓的 tagged union 思路。

语法/规则

  1. 共用体定义形式是 union 共用体名 { 成员列表 };
  2. 共用体大小通常由最大成员决定,并受对齐规则影响。
  3. 给某个成员赋值后,再读取另一个成员的结果要格外谨慎。
  4. 共用体适合“同一段内存的不同解释方式”,不适合同时保存多份独立数据。
  5. 如果程序里需要知道“当前有效成员是谁”,最好配合枚举标签一起使用。
  6. 用共用体做底层技巧时,要特别注意可移植性和未定义行为边界。

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>

enum ValueType {
    VALUE_INT,
    VALUE_FLOAT
};

struct TaggedValue {
    enum ValueType type;
    union {
        int i;
        float f;
    } data;
};

int main(void) {
    struct TaggedValue first = {VALUE_INT, {.i = 10}};
    struct TaggedValue second = {VALUE_FLOAT, {.f = 3.5f}};

    printf("first = %d\n", first.data.i);
    printf("second = %.1f\n", second.data.f);
    return 0;
}

输出结果:

1
2
first = 10
second = 3.5

常见错误

  1. 像使用结构体一样,期望共用体所有成员同时都保留自己的值。
  2. 写入一个成员后直接把另一成员解释成可靠结果,却没有确认这样做是否安全。
  3. 只是为了“省几个字节”盲目使用共用体,结果让代码可读性和可维护性变差。
  4. 没有额外标签来记录当前有效成员,导致后续读取时完全靠猜。
  5. 直接把共用体技巧当成通用跨平台方案,而没有考虑编译器和平台差异。
本文禁止转载
使用 Hugo 构建
主题 StackJimmy 设计 由 Hobin 魔改
最近构建时间:2026-04-17 19:07:48 CST
载入天数...载入时分秒...
发表了 1 篇文章 · 发表了 152 篇笔记 · 总计 18 万 0 千字