共用体

共用体(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