union


有些結構的實例,可能包含不同型態的成員,然而,在某個時間點上,只會有一個成員是有效的,例如,你可能會設計一個磁頭結構,磁頭讀取磁帶中的資料並儲存為對應的資料型態:

#include <stdio.h>

typedef struct {
    char cvalue;
    int ivalue;
    double dvalue;

    enum {CHAR, INT, DOUBLE} type;
} Head;

void readChar(Head *head, char cvalue) {
    head->cvalue = cvalue;
    head->type = CHAR;
}

void readInt(Head *head, int ivalue) {
    head->ivalue = ivalue;
    head->type = INT;
}

void readDouble(Head *head, double dvalue) {
    head->dvalue = dvalue;
    head->type = DOUBLE;
}

void print(Head *head) {
    switch(head->type) {
        case CHAR:
            printf("%c\n", head->cvalue);
            break;
        case INT:
            printf("%d\n", head->ivalue);
            break;
        case DOUBLE:
            printf("%i\n", head->dvalue);
            break;
    }
}

int main() { 
    Head head;

    readInt(&head, 10);
    print(&head);

    readChar(&head, 'A');
    print(&head);

    return 0; 
} 

在上例中,Head 一次只儲存一種資料,並依 type 決定該寫出哪種資料,因為 Head 一次只儲存一種資料,不需要分別為 cvalueivaluedvalue 各開一個記憶體空間。

你可以使用 union,它是一種特殊的結構,維護足夠的空間來置放多個資料成員中的一種,而不是為每個資料成員配置各自空間,例如:

#include <stdio.h>

typedef struct {
    union {
        char cvalue;
        int ivalue;
        double dvalue;
    } value;

    enum {CHAR, INT, DOUBLE} type;
} Head;

void readChar(Head *head, char cvalue) {
    head->value.cvalue = cvalue;
    head->type = CHAR;
}

void readInt(Head *head, int ivalue) {
    head->value.ivalue = ivalue;
    head->type = INT;
}

void readDouble(Head *head, double dvalue) {
    head->value.dvalue = dvalue;
    head->type = DOUBLE;
}

void print(Head *head) {
    switch(head->type) {
        case CHAR:
            printf("%c\n", head->value.cvalue);
            break;
        case INT:
            printf("%d\n", head->value.ivalue);
            break;
        case DOUBLE:
            printf("%i\n", head->value.dvalue);
            break;
    }
}

...略

Head 中定義了匿名的 union 並建立了 value 成員,union 配置足夠大的空間以來容納最大長度的資料成員,以上例而言,最大長度是 double 型態,因此 value 成員的大小是 double 的長度,由於 union 的資料成員共用記憶體空間,存取當前具有合法值的資料成員,才能正確地取資料,