有些结构的实例,可能包含不同类型的成员,然而,在某个时间点上,只会有一个成员是有效的,例如,你可能会设计一个磁头结构,磁头读取磁带中的数据并存储为对应的数据类型:
#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
的数据成员共用内存空间,访问当前具有合法值的数据成员,才能正确地取数据,