跳转到内容

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;
    // ...
};

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

graph TD A[union Data] --> B[int i] A --> C[float f] A --> D[char str[20]] style A fill:#f9f,stroke:#333 style B fill:#bbf,stroke:#333 style C fill:#bbf,stroke:#333 style D fill:#bbf,stroke:#333

上图中,联合Data的三个成员ifstr共享同一内存空间,其大小为最大成员(此处为str[20])的大小。

代码示例[编辑 | 编辑源代码]

基本使用[编辑 | 编辑源代码]

#include <stdio.h>
#include <string.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);
    
    data.f = 220.5;
    printf("data.f : %f\n", data.f);
    
    strcpy(data.str, "C Programming");
    printf("data.str : %s\n", data.str);
    
    return 0;
}

输出:

data.i : 10
data.f : 220.500000
data.str : C Programming

注意: 最后一次赋值会覆盖之前的值,因为所有成员共享内存。

类型转换应用[编辑 | 编辑源代码]

联合可用于实现低级别的类型转换:

#include <stdio.h>

union Converter {
    float f;
    unsigned int u;
};

int main() {
    union Converter conv;
    conv.f = 3.14f;
    
    printf("Float value: %f\n", conv.f);
    printf("Binary representation: 0x%08X\n", conv.u);
    
    return 0;
}

输出:

Float value: 3.140000
Binary representation: 0x4048F5C3

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

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

在网络协议中,联合常用于解析不同格式的数据包:

#include <stdio.h>

union IPAddress {
    unsigned int address;
    unsigned char octets[4];
};

int main() {
    union IPAddress ip;
    ip.address = 0xC0A80101; // 192.168.1.1
    
    printf("IP in hex: 0x%08X\n", ip.address);
    printf("Dotted format: %d.%d.%d.%d\n", 
           ip.octets[3], ip.octets[2], 
           ip.octets[1], ip.octets[0]);
    
    return 0;
}

输出:

IP in hex: 0xC0A80101
Dotted format: 192.168.1.1

硬件寄存器访问[编辑 | 编辑源代码]

在嵌入式系统中,联合常用于访问硬件寄存器:

typedef union {
    struct {
        unsigned int enable : 1;
        unsigned int mode : 3;
        unsigned int reserved : 28;
    } bits;
    unsigned int word;
} ControlRegister;

void setup_hardware() {
    ControlRegister cr;
    cr.word = 0; // 初始化
    cr.bits.enable = 1;
    cr.bits.mode = 5;
    
    printf("Register value: 0x%08X\n", cr.word);
}

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

特性 联合 结构体
内存使用 共享内存 独立内存
大小 最大成员的大小 所有成员大小之和(考虑对齐)
同时访问 只能访问一个成员 可同时访问所有成员

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

联合的内存分配可以表示为: sizeof(union)=max(sizeof(member1),sizeof(member2),,sizeof(membern))

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

  • 联合不能包含引用类型的成员(如指针指向的数据不共享)
  • 使用联合进行类型转换可能引发未定义行为(取决于平台)
  • 匿名联合(C11特性)可以直接访问成员
  • 联合常用于实现变体类型(variant type)

高级应用:标签联合[编辑 | 编辑源代码]

结合结构体和枚举实现类型安全的联合:

#include <stdio.h>

typedef enum { INT, FLOAT, STR } Type;

typedef struct {
    Type type;
    union {
        int i;
        float f;
        char s[20];
    } value;
} Variant;

void print_variant(Variant v) {
    switch(v.type) {
        case INT: printf("INT: %d\n", v.value.i); break;
        case FLOAT: printf("FLOAT: %f\n", v.value.f); break;
        case STR: printf("STR: %s\n", v.value.s); break;
    }
}

int main() {
    Variant v1 = { .type = INT, .value.i = 42 };
    Variant v2 = { .type = FLOAT, .value.f = 3.14f };
    
    print_variant(v1);
    print_variant(v2);
    
    return 0;
}

输出:

INT: 42
FLOAT: 3.140000

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

联合是C语言中强大的特性,特别适用于:

  • 内存敏感型应用
  • 底层硬件编程
  • 数据格式转换
  • 实现多态数据结构

正确使用联合需要充分理解其内存共享特性,避免意外覆盖数据。结合结构体和枚举可以实现更安全、更高级的编程模式。