共用体(union)は構造体と似ているけど、メンバ変数が同じメモリ領域を共有するもの。メモリを共有するメンバ変数が同じ型である必要はないけど、同時に使うことは出来ない。
定義の方法も構造体とよく似ていいて、一般的な形式は次のとおり。
union タグ名 { 型 メンバ1; 型 メンバ2; ... 型 メンバN; } 変数リスト;
「タグ名」と「変数リスト」のどちらかを省くことができるのも構造体と一緒。
次の共用体は、整数、文字配列、double 型の3つのメンバを持つ。
union u_type { int i; char c[4]; double d; } sample;
このとき、各メンバはメモリ領域を共有していて、d(double 型、8バイト)の上位4バイトを i (int 型、4バイト)が共有している。また、同時に同じ上位4バイトの領域を c[4] も共有している。各メンバが別々のメモリ領域を占めるのではない。
共用体のサイズはコンパイル時に決定され、最大のメンバが入る大紀佐の憑依機が割り当てられる。サイズを求めるときには sizeof 演算子を使うこと。メンバのうちの最大サイズが共用体のサイズとは限らない。環境によってはワード境界に揃えられることがあるから(ワード境界ってなんだ?)。
共用体のメンバにアクセスするには、構造体と同様にドット演算子を使う。
sample.d = 123.456;
また、ポインタを介してのアクセスにはアロー演算子だ。
p->i = 10;
なんとなくわかったような気がするけど、どうも使いドコロがわからないな。
次のプログラムは、整数(short int)の上下バイトを入れ替えて暗号化・復号化する。暗号化・復号化するためのデータとして共用体を使っている。
#include short encode(short i); int main(void) { short i; i = encode(10); printf ("Encode 10 -> %d\n", i); i = encode(i); printf("Decode i -> %d\n", i); return 0; } short encode(short i) { union crypt_type { short num; char c[2]; } crypt; unsigned char ch; crypt.num = i; /* Swap bytes of short int */ ch = crypt.c[0]; crypt.c[0] = crypt.c[1]; crypt.c[1] = ch; return crypt.num; }
takatoh@nightschool $ ./sample_10_5 Encode 10 -> 2560 Decode i -> 10