乐闻世界logo
搜索文章和话题

C语言中联合体(union)的使用场景和内存布局是什么?

2月18日 17:21

C语言中联合体(union)的使用场景和内存布局是什么?

联合体基本概念:

  1. 定义和声明

    c
    union Data { int i; float f; char str[20]; }; union Data data; data.i = 10; data.f = 3.14; strcpy(data.str, "Hello");
  2. 内存共享特性

    c
    union Example { int value; char bytes[4]; }; union Example ex; ex.value = 0x12345678; // bytes[0] = 0x78 (小端序) // bytes[1] = 0x56 // bytes[2] = 0x34 // bytes[3] = 0x12

典型使用场景:

  1. 数据类型转换

    c
    union FloatInt { float f; unsigned int i; }; float_to_bits(float value) { union FloatInt converter; converter.f = value; return converter.i; }
  2. 节省内存空间

    c
    // 不使用联合体:占用12字节 struct Message { int type; union { int int_data; float float_data; char char_data[4]; } data; }; // 使用联合体:只占用8字节 union CompactMessage { struct { int type; int data; } int_msg; struct { int type; float data; } float_msg; };
  3. 网络协议解析

    c
    union IPHeader { struct { unsigned int version : 4; unsigned int ihl : 4; unsigned int tos : 8; unsigned int total_length : 16; } fields; unsigned int raw; };
  4. 变体数据类型

    c
    enum DataType { INT, FLOAT, STRING }; struct Variant { enum DataType type; union { int int_val; float float_val; char *str_val; } value; };

内存布局分析:

  1. 大小计算

    c
    union SizeExample { char c; // 1字节 int i; // 4字节 double d; // 8字节 }; sizeof(union SizeExample); // 8字节(最大成员的大小)
  2. 对齐规则

    c
    union AlignedExample { char c; int i; double d; }; // 大小为8字节,对齐到8字节边界

高级应用:

  1. 位域操作

    c
    union BitManipulation { unsigned int value; struct { unsigned int bit0 : 1; unsigned int bit1 : 1; unsigned int bit2 : 1; unsigned int rest : 29; } bits; }; union BitManipulation bm; bm.value = 0; bm.bits.bit0 = 1;
  2. 类型安全的联合体

    c
    struct SafeUnion { enum { INT, FLOAT, STRING } type; union { int int_val; float float_val; char *str_val; } data; }; void print_safe_union(struct SafeUnion *su) { switch (su->type) { case INT: printf("%d\n", su->data.int_val); break; case FLOAT: printf("%f\n", su->data.float_val); break; case STRING: printf("%s\n", su->data.str_val); break; } }

注意事项:

  1. 同时访问问题

    c
    union Data { int i; float f; }; union Data d; d.i = 10; d.f = 3.14; // 覆盖了之前的值 // 此时访问 d.i 是未定义行为
  2. 字节序依赖

    c
    union EndianTest { int value; char bytes[4]; }; union EndianTest test; test.value = 1; if (test.bytes[0] == 1) { printf("Little Endian\n"); } else { printf("Big Endian\n"); }
  3. 初始化

    c
    union Data { int i; float f; }; union Data d1 = {10}; // 初始化第一个成员 union Data d2 = {.f = 3.14}; // 指定成员初始化
标签:C语言