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