C 语言中,struct(结构体)和 union(联合体)都是自定义复合数据类型,它们可以用来将多个不同类型的变量组合在一起。但它们之间的行为和内存布局有本质区别。结构体适合用于组合多个字段,联合体适合在一个时间点只使用一个字段的情况,特别适合节省内存或实现多态数据结构。

1、基本定义与语法

1)struct 结构体

每个成员都有 独立的内存空间,多个成员可以同时存在且独立访问。

#include <stdio.h>

// 定义结构体
struct Example {
    int i;
    float f;
};

int main() {
    // 创建结构体变量并初始化
    struct Example e1;
    e1.i = 42;
    e1.f = 3.14f;

    // 输出结构体成员
    printf("e1.i = %d\n", e1.i);
    printf("e1.f = %.2f\n", e1.f);

    // 使用结构体数组
    struct Example arr[2] = {
        {1, 1.1f},
        {2, 2.2f}
    };

    for (int j = 0; j < 2; j++) {
        printf("arr[%d] = { i: %d, f: %.1f }\n", j, arr[j].i, arr[j].f);
    }

    return 0;
}

2)union 联合体

所有成员共享同一块内存空间,任何时刻只能存储一个成员的值,写入一个成员可能会破坏其他成员的值。

#include <stdio.h>

union Example {
    int i;
    float f;
};

int main() {
    union Example ex;

    // 存储 int 值
    ex.i = 42;
    printf("ex.i = %d\n", ex.i);

    // 存储 float 值,将覆盖之前的 int 值
    ex.f = 3.14f;
    printf("ex.f = %.2f\n", ex.f);

    // 再次访问 int,注意值已经被 float 覆盖
    printf("Now ex.i (after storing float) = %d\n", ex.i);

    return 0;
}

2、内存布局区别

结构体(struct)和联合体(union)都是用户自定义的复合数据类型,但它们在内存布局和使用方式上有显著差别。

特性

struct

(结构体)

union

(联合体)

内存分配

每个成员都有自己的内存空间

所有成员共享同一段内存空间

大小

大小是所有成员大小之和(含对齐填充)

大小是最大成员的大小(含对齐填充)

用途

同时保存多个字段的数据

多个字段

共用一段内存

,节省空间

访问

可同时访问多个成员

任何时刻只能有效访问一个成员

例如,

#include <stdio.h>

struct MyStruct {
    int i;
    float f;
    char c;
};

union MyUnion {
    int i;
    float f;
    char c;
};

int main() {
    printf("struct 大小: %lu\n", sizeof(struct MyStruct));
    printf("union  大小: %lu\n", sizeof(union MyUnion));
    return 0;
}

3、用途对比

如需要同时使用多个字段,用 struct。如需要在不同时间使用不同字段,并且想节省空间,用 union

用途/特点

struct

(结构体)

union

(联合体)

多个字段同时有效

✅ 是

❌ 否(任一时刻只有一个字段有效)

节省内存

❌ 否(分配每个字段内存)

✅ 是(多个字段共享内存)

使用场景

存储多种属性的数据结构(如学生信息)

用于节省内存,如解析协议字段/变体结构体等

成员访问行为

成员间独立,不影响彼此

修改一个成员可能会影响其他成员

推荐文档