首页 > 编程笔记 > C语言笔记

C语言联合体和结构体有什么区别?

在C语言中,联合体(union)和结构体(struct)都是用于组织和存储多个不同类型数据的复合数据类型,虽然它们看起来有些相似,但在内存分配和使用方式上存在显著差异。

内存分配方式

结构体和联合体在内存分配上有着本质的区别:结构体为每个成员分配独立的内存空间,而联合体则让所有成员共享同一块内存空间。


对于结构体,其总大小通常是所有成员大小的总和(可能会因字节对齐而略有增加)。每个成员占据各自的内存位置。例如:

struct Example {
    int a;    // 4 bytes
    char b;   // 1 byte
    double c; // 8 bytes
};

// sizeof(struct Example) 通常为 16 bytes(考虑对齐)

而对于联合体,其大小等于最大成员的大小。所有成员共享这块内存空间,因此在任意时刻只有一个成员可以存储有效值。例如:

union Example {
    int a;    // 4 bytes
    char b;   // 1 byte
    double c; // 8 bytes
};

// sizeof(union Example) 为 8 bytes

数据存储和访问

结构体允许同时存储和访问所有成员,每个成员都有自己的内存位置,可以独立地赋值和读取,这使得结构体非常适合表示具有多个相关属性的复杂数据类型。

struct Person {
    char name[50];
    int age;
    float height;
};

struct Person p1 = {"Alice", 25, 165.5};
printf("Name: %s, Age: %d, Height: %.1f\n", p1.name, p1.age, p1.height);
输出结果:
Name: Alice, Age: 25, Height: 165.5

联合体则只能在同一时间存储一个成员的值,当给联合体的一个成员赋值时,会覆盖其他成员的值。这种特性使得联合体适合用于需要在不同数据类型之间切换的场景,或者需要节省内存的情况。

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

union Data data;
data.i = 10;
printf("data.i: %d\n", data.i);

data.f = 220.5;
printf("data.f: %.1f\n", data.f);
printf("data.i: %d\n", data.i);  // 这里的值已经被覆盖,不再是 10
输出结果:
data.i: 10
data.f: 220.5
data.i: 1128792064  // 这是 float 220.5 的二进制表示被解释为 int 的结果

内存效率

在内存使用效率方面,联合体通常比结构体更节省空间。当我们需要在不同时间使用不同类型的数据,但不需要同时保存所有数据时,联合体是一个很好的选择。


例如,假设我们需要存储不同类型的传感器数据:

union SensorData {
    int temperature;
    float humidity;
    char pressure[8];
};

// 只使用 8 bytes 的内存就可以存储三种不同类型的数据

如果使用结构体,我们将需要更多的内存:

struct SensorData {
    int temperature;
    float humidity;
    char pressure[8];
};

// 使用至少 16 bytes 的内存(考虑对齐)

使用场景

结构体适用于需要同时存储和访问多个相关数据项的情况,例如,表示一个学生的信息:

struct Student {
    char name[50];
    int id;
    float gpa;
};

联合体适用于在不同时间需要不同数据类型的情况,或者需要以不同的方式解释同一块内存。例如,在网络编程中解析不同类型的数据包:

union PacketData {
    struct {
        int type;
        char data[100];
    } text_packet;
    
    struct {
        int type;
        int width;
        int height;
        char data[92];
    } image_packet;
};

类型安全

结构体提供了更好的类型安全性,每个成员都有明确的类型,编译器可以检查类型匹配和进行类型转换。而联合体由于其共享内存的特性,可能导致类型混淆和不安全的操作,需要程序员更加小心地管理数据。


声明:《C语言系列教程》为本站“54笨鸟”官方原创,由国家机构和地方版权局所签发的权威证书所保护。