联合体union的基本用法

引言

联合体(union)是 C/C++ 中一种特殊的复合数据类型,它允许不同类型的成员共享同一块内存空间,主要用于在有限内存中存储 “互斥使用” 的数据。

一、基本用法

1.1 定义与声明

使用 union 关键字定义联合体,语法与结构体类似,但成员共享内存。

// 定义联合体(存储不同类型的数值,但同一时间仅一种有效)
union Data 
{
    int i;       // 整数
    float f;     // 浮点数
    char c;      // 字符
};
// 声明联合体变量
union Data d1;  // 方式1:完整声明
Data d2;        // 方式2:结合typedef取别名(更简洁)

//结合 typedef 取别名(推荐):
typedef union 
{
    int i;
    float f;
    char c;
} Data;

Data d;  // 直接用别名声明,无需重复写union

1.2 成员访问

通过 . 操作符访问成员,与结构体用法一致;若为指针,则用 -> 操作符。

#include <stdio.h>

typedef union 
{
    int i;
    float f;
    char c;
} Data;

int main() 
{
    Data d;
    
    // 赋值整数成员
    d.i = 100;
    printf("d.i = %d\n", d.i);  // 输出 100
    // 此时访问其他成员会得到乱码(内存被覆盖)
    printf("d.f = %f\n", d.f);  // 输出无意义值(如 0.000000 或随机数)
    
    // 赋值浮点数成员(覆盖整数的内存)
    d.f = 3.14f;
    printf("d.f = %f\n", d.f);  // 输出 3.140000
    printf("d.i = %d\n", d.i);  // 输出浮点数3.14的二进制对应的整数值(乱码)
    
    return 0;
}

1.3 内存特性

  • 所有成员共享同一块内存,起始地址相同。
  • 联合体的大小 = 最大成员的大小(确保能容纳所有成员中最大的那个)。

二、应用场景

2.1 解析二进制数据(内存共用)

例如解析一个 4 字节的二进制数据,既可视为整数,也可视为浮点数:

// 4字节二进制数据,可按int或float解析
typedef union 
{
    int i;
    float f;
    char bytes[4];  // 按字节访问
} BinaryData;

int main() 
{
    BinaryData data;
    data.i = 0x41480000;  // 二进制值
    
    printf("作为整数:%d\n", data.i);       // 输出 1094060032
    printf("作为浮点数:%f\n", data.f);     // 输出 12.5(0x41480000对应float的12.5)
    printf("字节1:%02X\n", data.bytes[0]); // 输出 00(小端存储)
    return 0;
}

三、注意事项(避坑关键点)

3.1 成员互斥,赋值会覆盖

写入一个成员会覆盖其他成员的内存,读取未被赋值的成员会得到无意义的 “脏数据”。
解决:始终用一个 “类型标记”(如枚举)记录当前有效的成员类型(见场景 1 示例)。

3.2 内存对齐规则

联合体的大小由最大成员决定,但需满足最大成员的对齐要求:

union Align 
{
    char c;       // 1字节(对齐要求1)
    double d;     // 8字节(对齐要求8)
};
printf("联合体大小:%lu\n", sizeof(union Align)); // 输出8字节(满足double的对齐)
posted @ 2025-09-27 00:38  开心猪扒  阅读(35)  评论(0)    收藏  举报