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

What are the usage scenarios and memory layout of unions in C language?

2月18日 17:21

What are the usage scenarios and memory layout of unions in C language?

Union Basic Concepts:

  1. Definition and Declaration

    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. Memory Sharing Property

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

Typical Usage Scenarios:

  1. Data Type Conversion

    c
    union FloatInt { float f; unsigned int i; }; float_to_bits(float value) { union FloatInt converter; converter.f = value; return converter.i; }
  2. Memory Space Saving

    c
    // Without union: 12 bytes struct Message { int type; union { int int_data; float float_data; char char_data[4]; } data; }; // With union: only 8 bytes union CompactMessage { struct { int type; int data; } int_msg; struct { int type; float data; } float_msg; };
  3. Network Protocol Parsing

    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. Variant Data Types

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

Memory Layout Analysis:

  1. Size Calculation

    c
    union SizeExample { char c; // 1 byte int i; // 4 bytes double d; // 8 bytes }; sizeof(union SizeExample); // 8 bytes (size of largest member)
  2. Alignment Rules

    c
    union AlignedExample { char c; int i; double d; }; // Size is 8 bytes, aligned to 8-byte boundary

Advanced Applications:

  1. Bit Field Operations

    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. Type-Safe Unions

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

Important Considerations:

  1. Simultaneous Access Issues

    c
    union Data { int i; float f; }; union Data d; d.i = 10; d.f = 3.14; // Overwrites previous value // Accessing d.i now is undefined behavior
  2. Endianness Dependency

    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. Initialization

    c
    union Data { int i; float f; }; union Data d1 = {10}; // Initialize first member union Data d2 = {.f = 3.14}; // Designated initializer
标签:C语言