# 6.5 联合 Unions

### 6.5.1 联合的基本概念

<figure><img src="https://2339153498-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FM5ElOYGdYiUaQPhsTyPV%2Fuploads%2FSFqiTeswXaOmkuF2eufo%2F%E6%88%AA%E5%B1%8F2024-01-31%2011.05.25.png?alt=media&#x26;token=349b8d2a-71b7-4aaa-a8c7-d44177c0a67e" alt=""><figcaption></figcaption></figure>

联合 Unions 允许你在同一内存位置存储不同的数据类型。和结构体（struct）不同的是，**联合体中的成员共享同一块内存空间**。因为，编译器最只为联合中最大的成员分配足够的内存空间。  **注意使用联合体的风险：**

<figure><img src="https://img.imotao.com/i/2024/02/01/65bb00bcb0a3d.png#id=E753H&#x26;originHeight=1166&#x26;originWidth=1348&#x26;originalType=binary&#x26;ratio=1&#x26;rotation=0&#x26;showTitle=false&#x26;status=done&#x26;style=none&#x26;title=" alt=""><figcaption></figcaption></figure>

* 数据共享风险： 联合体的不同成员共享同一块内存，容易导致数据混淆或覆盖，因此使用时需要格外小心。
* 只能同时存储一个值： 一次只能存储一个成员的值，存入新值会覆盖原来的值。
* 对齐和大小： 联合体的大小和对齐方式取决于最大的成员。

### 6.5.2 用联合来节省空间的例子

![](https://img.imotao.com/i/2024/02/01/65bb02538dd9a.jpeg#id=M65IK\&originHeight=2569\&originWidth=3024\&originalType=binary\&ratio=1\&rotation=0\&showTitle=false\&status=done\&style=none\&title=)

{% code title="6.5.1 union-with-struct-fucked.c" lineNumbers="true" %}
```c
#include <stdio.h>
#include <string.h>

// 定义一个结构体
struct Employee {
    int id;
    char name[20];
    char department[30];
    union {
        float salary;
        struct {
            int hours_worked;
            int rate_per_hour;
        } hourly_payment;
    } payment_info;
};

int main() {
    // 定义一个 Employee 结构体变量
    struct Employee emp1;

    // 设置员工信息
    emp1.id = 1001;
    strcpy(emp1.name, "John Doe");
    strcpy(emp1.department, "Engineering");

    // 设置薪资信息（这里使用联合来节省空间）
    emp1.payment_info.salary = 5000.0; // 设置月薪

    // 打印员工信息
    printf("Employee ID: %d\n", emp1.id);
    printf("Name: %s\n", emp1.name);
    printf("Department: %s\n", emp1.department);

    // 利用联合来访问薪资信息
    printf("Salary: $%.2f\n", emp1.payment_info.salary);

    // 如果员工是按时薪支付
    emp1.payment_info.hourly_payment.hours_worked = 40;
    emp1.payment_info.hourly_payment.rate_per_hour = 20;

    printf("Hours Worked: %d\n", emp1.payment_info.hourly_payment.hours_worked);
    printf("Rate per Hour: $%d\n", emp1.payment_info.hourly_payment.rate_per_hour);

    return 0;
}

```
{% endcode %}

```c
Employee ID: 1001
Name: John Doe
Department: Engineering
Salary: $5000.00
Hours Worked: 40
Rate per Hour: $20
```
