struct A { int A0; double A1; int * A2; };
は、A0,A1,A2全てを要素にもつデータ構造です。
一方で、
union B { int B0; double B1; int * B2; };
は、B0,B1,B2のいずれかを要素にもつデータ構造です。
例えば、あるデータ構造は、中身が int, double, int* のどれかなんだけど、という時に使います。
tag と言われる中身の種類を表すための札(フダ)と一緒に使われることが多いです
(ソース)
。
/* もう一度 enum 登場 */
typedef enum { tagInt, tagDouble, tagSymbol, tagComposite } tagSData_t;
typedef struct SData { /* この SData は、 */
tagSData_t tag; /* 中身の種類を tag で表し */
union {
int valInt; /* valInt や、、、のいずれかを */
double valDouble;
char * valSymbol;
SDataList_tp valComposite;
} body; /* body のなかに格納している。*/
} SData_t, * SData_tp;
/*
* pretty print という中身を綺麗に表示する関数をつくります
*/
void pprintrint_SDataInt(SData_tp data) { /* SData が Int の場合の pretty print */
printf("SData as Int %d\n",data->body.valInt);
}
void pprintrint_SDataDouble(SData_tp data) { /* SData が Double の場合の pretty print */
printf("SData as Double %f\n",data->body.valDouble);
}
void pprintrint_SDataSymbol(SData_tp data) { /* SData が Symbol の場合の pretty print */
printf("SData as Symbol %s\n",data->body.valSymbol);
}
void pprintrint_SDataComposite(SData_tp data) { /* SData が Composite の場合の pretty print */
printf("SData as Composite\n");
}
void pprintrint_SData(SData_tp data) { /* tag に応じて、各関数を呼び出す dispatch関数 */
switch(data->tag) {
case tagInt: /* Int の場合 */
pprintrint_SDataInt(SData_tp data);
break;
case tagDouble: /* Double の場合 */
pprintrint_SDataDouble(SData_tp data);
break;
case tagSymbol: /* Symbol の場合 */
pprintrint_SDataSymbol(SData_tp data);
break;
case tagComposite: /* Composite の場合 */
pprintrint_SDataComposite(SData_tp data);
break;
default:
error(1);
}
}
2001.11.20/ Tomio KAMADA: kamada@cs.kobe-u.ac.jp