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的数据成员共用内存空间,访问当前具有合法值的数据成员,才能正确地取数据,


展开阅读全文