本文最后更新于 2026-03-06,文章内容可能已经过时。

C语言联合体(union)是一种特殊的数据类型,允许多个不同类型的成员共享同一内存空间,其大小由最大成员决定,使用时同一时间只能访问一个成员(修改一个成员会覆盖其他成员的值),适用于内存优化、消息存储、字节序检测等场景,能有效节省内存并实现类型灵活切换。

一、基本概念

联合体(union)是C语言中一种特殊的数据类型,允许在同一内存位置存储不同类型的数据。其核心特点是所有成员共享同一块内存空间,联合体的大小由最大成员的大小决定。

与结构体(struct)不同:结构体各成员有各自内存空间,总长度是各成员长度之和;而联合体各成员共享内存,长度等于最长成员的长度。

二、联合体的声明方式

1. 先定义联合类型,再声明变量

union Data {
    int i;
    float f;
    char str[20];
};

// 声明联合变量
union Data d1, d2;

2. 匿名联合,直接声明变量

union {
    int i;
    float f;
    char str[20];
} d1, d2;

3. 使用typedef定义联合体别名

typedef union {
    int i;
    float f;
    char str[20];
} Data;

Data d1, d2;

三、联合体的内存布局

1. 内存大小计算

联合体的大小由最大成员的大小决定:

union Data {
    char c;     // 1字节
    int i;      // 4字节
    float f;    // 4字节
    double d;   // 8字节
};

printf("sizeof(Data) = %zu\n", sizeof(union Data)); // 输出8

2. 内存共享特性

所有成员共享同一块内存,修改一个成员会覆盖其他成员的值:

union Data d;
d.i = 10;
printf("d.i = %d\n", d.i);  // 输出10

d.f = 220.5;
printf("d.f = %.1f\n", d.f); // 输出220.5
// 此时d.i的值已被覆盖,不再可靠

四、联合体的典型应用场景

1. 内存优化

当需要存储不同类型的数据,但一次只使用其中一种时,联合体可以节省内存。

示例:消息存储

struct message {
    int type;   // 1-整数, 2-浮点, 3-字符串
    union {
        int n;
        float f;
        char str[20];
    } value;
};

// 使用示例
struct message msg;
msg.type = 1;
msg.value.n = 123;  // 存储整数

msg.type = 3;
strcpy(msg.value.str, "Hello");  // 存储字符串

2. 字节序检测

int is_little_endian() {
    union {
        int i;
        char c;
    } u;
    u.i = 1;
    return u.c;  // 1表示小端,0表示大端
}

3. 分离高低字节

单片机中常见应用

union chufa {
    int n;          // 要分离高低字节的数据
    char a[2];      // 数组a与n共享内存
} test;

test.n = 65535 - 200;  // 计算值
TH1 = test.a[0];        // 高位字节
TL1 = test.a[1];        // 低位字节

五、联合体的注意事项

  1. 同一时间只能使用一个成员:修改一个成员会覆盖其他成员的值。

  2. "写A读B"可能产生未定义行为:例如,写入int成员后读取float成员,结果可能不可预测。

  3. 初始化规则:只能初始化联合体的第一个成员。

  4. 对齐要求:联合体的大小会按照最大成员的对齐要求进行调整。

六、联合体与结构体的对比

特性结构体(struct)联合体(union)
内存分配各成员独立内存所有成员共享内存
大小各成员大小之和最大成员的大小
使用方式可同时使用所有成员同一时间只能使用一个成员
适用场景需要同时存储多种类型数据一次只使用一种类型数据,节省内存

七、典型代码示例

#include <stdio.h>
#include <string.h>

union Data {
    int i;
    float f;
    char str[20];
};

int main() {
    union Data d;
    
    // 存储整数
    d.i = 10;
    printf("d.i = %d\n", d.i);
    
    // 存储浮点数,覆盖了整数值
    d.f = 220.5;
    printf("d.f = %.1f\n", d.f);
    
    // 存储字符串,覆盖了浮点数值
    strcpy(d.str, "Hello, World!");
    printf("d.str = %s\n", d.str);
    
    return 0;
}

输出

d.i = 10
d.f = 220.5
d.str = Hello, World!

总结

联合体是C语言中一种内存高效的特殊数据结构,特别适用于以下场景:

  • 需要存储不同类型数据,但一次只使用一种类型
  • 内存受限的环境(如嵌入式系统)
  • 数据解析(如网络协议、文件格式解析)
  • 字节序检测和高低字节分离

使用联合体时需注意:同一时间只能访问一个成员,否则可能导致未定义行为。