跳转到内容

C 语言联合基础

来自代码酷
Admin留言 | 贡献2025年4月29日 (二) 04:46的版本 (Page creation by admin bot)

(差异) ←上一版本 | 已核准修订 (差异) | 最后版本 (差异) | 下一版本→ (差异)

C语言联合基础[编辑 | 编辑源代码]

介绍[编辑 | 编辑源代码]

联合(Union)是C语言中的一种复合数据类型,它允许在相同的内存位置存储不同的数据类型。联合与结构体(Struct)类似,但关键区别在于:联合的所有成员共享同一块内存空间,而结构体的每个成员拥有独立的内存空间。因此,联合在任何时候只能存储一个成员的值,修改一个成员会影响其他成员的值。

联合常用于以下场景:

  • 节省内存空间(特别是在嵌入式系统中)。
  • 实现多态或类型转换(例如,将同一块内存解释为不同的数据类型)。
  • 处理硬件寄存器或协议数据(如网络数据包解析)。

语法与定义[编辑 | 编辑源代码]

联合的定义语法与结构体类似,使用关键字union

union UnionName {
    member_type1 member1;
    member_type2 member2;
    // 更多成员...
};

例如,定义一个包含intfloat的联合:

union Data {
    int i;
    float f;
};

联合的内存布局[编辑 | 编辑源代码]

联合的大小由其最大的成员决定。例如,上述union Data的大小为sizeof(float)(假设floatint占用更多空间)。

pie title 联合的内存分配 "int i" : 4 bytes "float f" : 4 bytes

基本用法示例[编辑 | 编辑源代码]

以下代码演示联合的声明、赋值和访问:

#include <stdio.h>

union Data {
    int i;
    float f;
};

int main() {
    union Data data;

    data.i = 42;
    printf("data.i = %d\n", data.i);  // 输出: data.i = 42

    data.f = 3.14;
    printf("data.f = %f\n", data.f);  // 输出: data.f = 3.140000
    printf("data.i = %d\n", data.i);  // 输出: data.i = 垃圾值(取决于浮点数的二进制表示)

    return 0;
}

注意:修改data.f后,data.i的值变得无意义,因为两者共享同一内存空间。

实际应用案例[编辑 | 编辑源代码]

1. 节省内存空间[编辑 | 编辑源代码]

在嵌入式系统中,联合可用于节省内存。例如,传感器数据可能以整数或浮点数形式存储:

union SensorData {
    int raw_value;
    float calibrated_value;
};

2. 类型转换[编辑 | 编辑源代码]

联合可用于将同一块内存解释为不同类型:

union Converter {
    float f;
    unsigned char bytes[sizeof(float)];
};

int main() {
    union Converter conv;
    conv.f = 1.0f;

    // 打印浮点数的字节表示
    for (int i = 0; i < sizeof(float); i++) {
        printf("byte[%d] = 0x%02X\n", i, conv.bytes[i]);
    }
    return 0;
}

输出示例(取决于系统的小端/大端存储):

byte[0] = 0x00
byte[1] = 0x00
byte[2] = 0x80
byte[3] = 0x3F

3. 协议解析[编辑 | 编辑源代码]

联合可用于解析网络协议或硬件寄存器:

union Packet {
    uint32_t raw;
    struct {
        uint8_t header;
        uint8_t payload;
        uint16_t checksum;
    } fields;
};

int main() {
    union Packet packet;
    packet.raw = 0xAABBCCDD;

    printf("Header: 0x%X\n", packet.fields.header);  // 输出取决于字节序
    return 0;
}

联合与结构体的区别[编辑 | 编辑源代码]

特性 联合(Union) 结构体(Struct)
内存分配 所有成员共享同一内存 每个成员拥有独立内存
大小 由最大成员决定 所有成员大小之和(考虑对齐)
用途 节省内存、类型转换 存储多个独立数据

注意事项[编辑 | 编辑源代码]

1. 初始化:只能初始化联合的第一个成员。

   union Data data = {10};  // 正确:初始化i

2. 字节序问题:跨平台时需注意大小端存储差异。

3. 类型安全:访问未赋值的成员可能导致未定义行为。

数学表示[编辑 | 编辑源代码]

联合的内存共享特性可表示为: Union Size=max(Size(m1),Size(m2),,Size(mn)) 其中m1,m2,,mn为联合的成员。

总结[编辑 | 编辑源代码]

联合是C语言中一种高效利用内存的工具,适用于需要灵活解释数据的场景。正确使用时,它能显著减少内存占用,但需谨慎处理类型安全和平台兼容性问题。