首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言結構體 vs 聯合體:記憶體佈局與使用場景深度對比

     編輯:關於C語言

核心差異一覽

特性結構體聯合體
記憶體分配所有成員同時存在,總大小 = 成員大小之和(含對齊填充)所有成員共用同一塊記憶體,大小 = 最大成員大小(含對齊)
成員存取可同時讀寫多個成員,互不干擾同一時刻只能存取一個成員,寫入新成員會覆蓋舊值
初始化可指定多個成員僅能初始化第一個成員
典型用途邏輯相關的資料聚合型別轉換、節省記憶體、互斥資料欄位

記憶體佈局解

結構體:線性排列


struct Demo {
    char c;      // offset 0, size 1
    // padding 3 bytes (alignment)
    int i;       // offset 4, size 4
    double d;    // offset 8, size 8
};               // total 16 bytes (alignment to 8)

聯合體:完全重疊


union Demo {
    char c;      // offset 0
    int i;       // offset 0
    double d;    // offset 0
};               // total 8 bytes (max member size, aligned)

經典案例:聯合體實現型別重疊


#include 

int main(void) {
    union {
        int i;
        struct {
            char first;
            char second;
        } half;
    } number;

    number.i = 0x4241;          // 0x42='B', 0x41='A' (little-endian)
    printf("%c%c\n", number.half.first, number.half.second);  // 輸出: AB

    number.half.first = 'a';    // 0x61
    number.half.second = 'b';   // 0x62
    printf("%x\n", number.i);   // 輸出: 6261 (little-endian: 0x6261)

    return 0;
}

解析:

  • 寫入 i 時,低位元組對應 first、次低位元組對應 second(小端序)
  • 寫入 first/second 時,i 的低兩位元組同步改變
  • 此技巧常用於:網路封包解析、檔案格式讀寫、型別雙關

進階用法:標籤聯合體 —— 安全的多態資料


typedef enum { TYPE_INT, TYPE_FLOAT, TYPE_STR } DataType;

typedef struct {
    DataType type;           // 標籤:指明當前有效成員
    union {
        int i;
        float f;
        char *s;
    } value;
} Variant;

void printVariant(Variant *v) {
    switch (v->type) {
        case TYPE_INT:    printf("int: %d\n", v->value.i); break;
        case TYPE_FLOAT:  printf("float: %f\n", v->value.f); break;
        case TYPE_STR:    printf("str: %s\n", v->value.s); break;
    }
}

這是 C 語言實現「代數資料型別」的標準模式,廣泛用於解析器、虛擬機、訊息協定。

對齊與大小陷阱

  • sizeof(union) 受最嚴格對齊要求的成員影響
  • 空結構體/聯合體在 C 標準中大小為 0,但 GCC/MSVC 擴展為 1
  • 位元欄位在聯合體中共用同一儲存單元,跨平台行為差異大,慎用

選擇指南

  1. 需要同時保存多個欄位 → 結構體
  2. 欄位互斥(同一時間只用一個) → 聯合體
  3. 需進行型別雙關(位元級重新解讀) → 聯合體
  4. 嵌入式系統極度節省 RAM → 聯合體 重疊緩衝區
  5. 需要標記當前型別 → 標籤聯合體

結語

結構體與聯合體是 C 語言「組合型別」的兩面:結構體代表並存,聯合體代表互斥/重疊。理解記憶體佈局差異,配合標籤欄位實現安全的變體型別,是系統程式設計、協定解析、嵌入式開發的核心技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved