020. 理解联合的使用

在C语言中,联合(Union) 是一种特殊的数据类型,它允许不同的数据类型共享同一块内存。与结构体(Struct) 不同,结构体中的每个成员都占用独立的内存空间,而联合中的所有成员共享同一块内存空间。这意味着在任何时刻,联合中只能存储一个成员的值。

1. 定义联合

联合的定义使用union关键字,后面跟着联合的名称和花括号{},花括号内定义了联合的成员变量。

示例1:定义一个简单的联合

#include <stdio.h>

// 定义一个联合
union Data {
    int i;
    float f;
    char str[20];
};

2. 初始化联合

联合可以在声明时初始化,也可以在声明后单独赋值。联合的初始化值必须是联合的第一个成员的类型。

示例2:初始化联合

#include <stdio.h>

// 定义一个联合
union Data {
    int i;
    float f;
    char str[20];
};

int main() {
    // 在声明时初始化联合
    union Data data = {10}; // 初始化为第一个成员的值

    // 输出联合的成员
    printf("data.i: %d\n", data.i); // 输出 10
    printf("data.f: %f\n", data.f); // 输出一个随机值,因为内存共享
    printf("data.str: %s\n", data.str); // 输出一个随机值,因为内存共享

    return 0;
}

输出结果

data.i: 10
data.f: 0.000000
data.str: (随机值)

3. 使用联合存储不同类型的值

由于联合中的所有成员共享同一块内存,因此可以通过修改不同的成员来存储不同类型的值。

示例3:使用联合存储不同类型的值

#include <stdio.h>

// 定义一个联合
union Data {
    int i;
    float f;
    char str[20];
};

int main() {
    union Data data;

    // 存储一个整数
    data.i = 10;
    printf("data.i: %d\n", data.i); // 输出 10

    // 存储一个浮点数
    data.f = 20.5;
    printf("data.f: %f\n", data.f); // 输出 20.5

    // 存储一个字符串
    strcpy(data.str, "Hello");
    printf("data.str: %s\n", data.str); // 输出 "Hello"

    return 0;
}

输出结果

data.i: 10
data.f: 20.500000
data.str: Hello

4. 联合的用途

联合的主要用途是节省内存,特别是在需要存储多种类型的数据但每次只使用其中一种类型时。联合常用于以下场景:

  • 内存管理:在嵌入式系统中,联合可以用于映射硬件寄存器。

  • 数据压缩:在需要存储多种类型的数据但每次只使用其中一种类型时,联合可以节省内存。

  • 类型转换:联合可以用于在不同类型的值之间进行转换。

示例4:联合用于内存映射

假设我们需要映射一个硬件寄存器,该寄存器可以被解释为一个整数或一个浮点数。

#include <stdio.h>

// 定义一个联合
union Register {
    int i;
    float f;
};

int main() {
    union Register reg;

    // 存储一个整数
    reg.i = 0x3F800000; // IEEE 754表示的1.0
    printf("reg.i: %x\n", reg.i); // 输出 3f800000
    printf("reg.f: %f\n", reg.f); // 输出 1.000000

    return 0;
}

输出结果

reg.i: 3f800000
reg.f: 1.000000

5. 联合与结构体的结合使用

联合可以嵌套在结构体中,形成更复杂的数据结构。这种组合可以用于实现类似“标签联合”的功能,即在结构体中包含一个联合和一个标签,用于指示当前联合中存储的是哪种类型的数据。

示例5:联合与结构体的结合使用

#include <stdio.h>

// 定义一个联合
union Data {
    int i;
    float f;
    char str[20];
};

// 定义一个结构体,包含联合和标签
struct MixedData {
    int type; // 标签,用于指示当前联合中存储的是哪种类型的数据
    union Data data; // 联合
};

int main() {
    struct MixedData mixed;

    // 存储一个整数
    mixed.type = 1;
    mixed.data.i = 10;
    printf("Type: %d, Data: %d\n", mixed.type, mixed.data.i);

    // 存储一个浮点数
    mixed.type = 2;
    mixed.data.f = 20.5;
    printf("Type: %d, Data: %f\n", mixed.type, mixed.data.f);

    // 存储一个字符串
    mixed.type = 3;
    strcpy(mixed.data.str, "Hello");
    printf("Type: %d, Data: %s\n", mixed.type, mixed.data.str);

    return 0;
}

输出结果

Type: 1, Data: 10
Type: 2, Data: 20.500000
Type: 3, Data: Hello

通过上述示例,你可以看到联合(Union)在C语言中的用途和特性:

  1. 定义联合:使用union关键字定义联合,并在花括号内声明成员变量。
  2. 初始化联合:可以在声明时初始化,也可以在声明后单独赋值。
  3. 使用联合存储不同类型的值:联合中的所有成员共享同一块内存,因此可以通过修改不同的成员来存储不同类型的值。
  4. 联合的用途:联合常用于内存管理、数据压缩和类型转换。
  5. 联合与结构体的结合使用:联合可以嵌套在结构体中,形成更复杂的数据结构,用于实现类似“标签联合”的功能。

视频讲解

BiliBili: 视睿网络-哔哩哔哩视频 (bilibili.com)