有些結構的實例,可能包含不同型態的成員,然而,在某個時間點上,只會有一個成員是有效的,例如,你可能會設計一個磁頭結構,磁頭讀取磁帶中的資料並儲存為對應的資料型態:
#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
一次只儲存一種資料,不需要分別為 cvalue
、ivalue
、dvalue
各開一個記憶體空間。
你可以使用 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
的資料成員共用記憶體空間,存取當前具有合法值的資料成員,才能正確地取資料,