page15で構造体を扱いましたが、共用体も構造体と同じく、様々なデータをまとめて扱うことができるものです。
struct S { int a; int aa; char b; int c[2]; char d[4]; } union U { int a; int aa; char b; int c[2]; char d[4]; }
書き方もstructがunionになっただけでほとんど同じです。ただし、データの持ちかたは構造体と大きく異なります。
構造体はメンバのそれぞれが別の領域を使用します。
/* 構造体と共用体1 */ #include <stdio.h> int main(int argc, char* argv[]){ /* 構造体定義 */ struct S{ int a; int aa; char b; int c[2]; char d[4]; }; struct S MyS; MyS.a = 10; MyS.aa = 100; printf("%d\n",MyS.a); printf("%d\n",MyS.aa); return 0; }
結果はそれぞれ代入した値が出力され、
10 100
となります。
一方、共用体はメンバが共通の領域を使用します。そのため、
/* 構造体と共用体2 */ #include <stdio.h> int main(int argc, char* argv[]){ /* 共用体定義 */ struct S{ int a; int aa; char b; int c[2]; char d[4]; }; struct S MyS; MyS.a = 10; MyS.aa = 100; printf("%d\n",MyS.a); printf("%d\n",MyS.aa); return 0; }
の結果は、
100 100
となります。同じ領域を使用しているので、MyS.a == MyS.aaとなるのです。共用体の各メンバの使用する領域を以下に示します。すべて共用体の先頭アドレスから始まっていることに注目してください。
union U { int a; /* 共用体先頭アドレスから4バイト */ int aa; /* 共用体先頭アドレスから4バイト */ char b; /* 共用体先頭アドレスから1バイト */ int c[2]; /* 共用体先頭アドレスから4×2バイト */ char d[4]; /* 共用体先頭アドレスから1×4バイト */ }
なお、共用体のサイズはメンバの中でもっとも大きなものにあわせられます。上の例の場合、int c[2]のサイズと同じ8バイトが共用体のサイズになります。
扱いかたは構造体の時と同じです。アロー演算子も使用できます。
/* 共用体ポインタ */ #include <stdio.h> int main(int argc, char* argv[]){ /* 共用体定義 */ struct S{ int a; int aa; char b; int c[2]; char d[4]; }; struct S MyS[2]; struct S *p; p = &MyS[0]; MyS[0].a = 10; MyS[1].aa = 100; printf("%d\n",p->c[0]); printf("%d\n",(p+1)->a); return 0; }