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

C 語言聯合體與枚舉:記憶體共享與型別安全的選擇

     編輯:關於C語言

C 語言聯合體與枚舉:記憶體共享與型別安全的選擇

聯合體與枚舉是結構體之外的兩種重要構造型別。聯合體實現記憶體重疊共享,枚舉提供具名常數集合,兩者解決不同領域的問題。

聯合體:同一記憶體、多種解讀

typedef union {
    short count;    // 2 bytes
    float weight;   // 4 bytes
    float volume;   // 4 bytes
} Quantity;         // 大小 = max(2,4,4) = 4 bytes

核心特性

  • 大小 = 最大成員大小(對齊後)
  • 同一時間僅一個成員有效,寫入一個會覆蓋其他
  • 記憶體重疊:所有成員從相同位址開始

使用範例

typedef struct {
    const char *color;
    Quantity amount;
} Bike;

int main() {
    Bike b1 = {"Red", .amount.count = 5};           // 用 count
    Bike b2 = {"Blue", .amount.weight = 10.5f};     // 用 weight

    // 危險:寫入 weight 後讀取 count
    b2.amount.weight = 10.5f;
    printf("count: %d\n", b2.amount.count);  // 垃圾值!位元模式不同
    return 0;
}

關鍵風險:聯合體無型別標記,程式設計師需自行追蹤當前有效成員。誤讀導致未定義行為。

枚舉:具名整數常數集合

typedef enum {
    RED,      // 0
    BLACK,    // 1
    BLUE,     // 2
    GREEN     // 3
} Color;

Color favorite = BLUE;
printf("%d\n", favorite);  // 輸出 2

進階用法

// 自定義值
typedef enum {
    ERR_OK = 0,
    ERR_MEM = -1,
    ERR_IO = -2,
    ERR_NET = -3
} ErrorCode;

// 位元旗標 (配合位運算)
typedef enum {
    READ   = 1 << 0,  // 1
    WRITE  = 1 << 1,  // 2
    EXEC   = 1 << 2,  // 4
    ALL    = READ | WRITE | EXEC  // 7
} Permission;

聯合體 vs 枚舉:選擇指南

場景推薦理由
同一資料多種解讀(如 IPv4 地址:整數/4字節陣列)聯合體零開銷記憶體重疊
互斥的資料型別(訊息類型決定承載結構)聯合體 + 標記欄位手動實現 tagged union
固定集合的離散值(狀態碼、顏色、錯誤碼)枚舉型別安全、除錯器顯示名稱
位元旗標組合(權限、屬性標記)枚舉 + 位運算語意清晰、編譯期計算
需儲存多種不同型別資料同時存在結構體各成員獨立記憶體

標記聯結:安全使用聯合體的模式

typedef enum { INT_TYPE, FLOAT_TYPE, STR_TYPE } DataTag;

typedef struct {
    DataTag tag;
    union {
        int i;
        float f;
        char *s;
    } value;
} Variant;

void print_variant(Variant v) {
    switch (v.tag) {
        case INT_TYPE:    printf("%d\n", v.value.i); break;
        case FLOAT_TYPE:  printf("%f\n", v.value.f); break;
        case STR_TYPE:    printf("%s\n", v.value.s); break;
    }
}

此模式在 C 模擬多態、解析 JSON/協議緩衝區時極常見。

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