C 速查手冊

聯合

聯合 (union) 為早期 C 語言為了解決記憶體不足而有的資料型態 (data type) ,其定義與宣告與結構 (structure) 類似,不同之處為聯合的所有成員佔用相同的記憶體空間,因此儲存到聯合的值會以該成員具有儲存範圍最大的資料型態為優先,也就是佔用到最多位元組數的資料型態。

聯合的定義格式如下圖

union name {
    datatype var1;
    ...
}

下例中替聯合 data 定義了兩個成員,分別是 intdouble 型態

#include <stdio.h>

union data {
    int vi;
    double vd;
};

int main(void)
{
    union data a;
    
    a.vi = 11;
    printf("a = (%d, %f)\n", a.vi, a.vd);
    
    a.vd = 22.0;
    printf("a = (%d, %f)\n", a.vi, a.vd);
    
    return 0;
}

/* 《程式語言教學誌》的範例程式
    http://kaiching.org/
    檔名:uniondata.c
    功能:示範聯合的使用
    作者:張凱慶 */

編譯後執行,結果如下

$ gcc uniondata.c
$ a.out
a = (11, 0.000000)
a = (0, 22.000000)
$

我們可以看出在 double 型態的成員被給值後, int 型態的成員自動被歸 0 。因此聯合的實際運用僅限於某一個成員,但實際仍須視編譯器、系統如何實作。

下例中利用 sizeof 運算子比較結構與聯合實際佔用記憶體空間的差異

#include <stdio.h>

union udata {
    int x;
    long y;
    double z;
    char *a;
};

struct sdata {
    int x;
    long y;
    double z;
    char *a;
};

int main(void)
{
    printf("%d\n", sizeof(union udata));
    printf("%d\n", sizeof(struct sdata));
    
    return 0;
}

/* 《程式語言教學誌》的範例程式
    http://kaiching.org/
    檔名:unionstruct.c
    功能:比較聯合與結構的大小
    作者:張凱慶 */

編譯後執行,結果如下

$ gcc unionstruct.c
$ a.out
8
32
$

由於 double 型態佔 8 個 byte 的位元組數,所以聯合變數 udata 就佔用 8byte 的位元組數。結構變數 sdata32byte 的位元組數,這是因為所有的成員 4 + 8 + 8 + 121 個位元組數,結構另有邊界對齊的狀況,所以此例中另外又加上 11 個位元組數。

回 C 速查手冊首頁