共用体には x という名前のメンバーがないため、メンバーの 1 つに値を割り当てると仮定すると、残りのメンバーはその値の一部を取ります。例えば:
union x
{
long longval;
char charvals[4];
short shortvals[2];
char oneCharVal;
short oneShortVal;
} obj;
obj.longval = 0x12fe6497;
printf( "c1: %x, c2: %x, c3: %x, c4: %x\n", obj.charvals[0], obj.charvals[1], obj.charvals[2], obj.charvals[3] );
printf( "s1: %x, s2: %x\n", obj.shortvals[0], obj.shortvals[1] );
printf( "oneCharVal: %x\n", obj.oneCharVal );
printf( "oneShortVal: %x\n", obj.oneShortVal );
印刷されます:
c1: 97, c2: 64, c3: fe, c4: 12
s1: 6497, s2: 12fe
oneCharVal: 97
oneShortVal: 6497
わかりやすくするために、意図的に拡張記号を無視しました。%x は、通常は 32 ビットの int を出力するため、出力前に char と short の両方を long に変換し、実際に出力します。
c1: ffffff97, c2: 64, c3: fffffffe, c4: 12
s1: 6497, s2: 12fe
oneCharVal: ffffff97
oneShortVal: 6497
最初に示した方法で数値を印刷するには、printf の書式設定を次のように変更する必要があります。
printf( "c1: %hhx, c2: %hhx, c3: %hhx, c4: %hhx\n", obj.charvals[0], obj.charvals[1], obj.charvals[2], obj.charvals[3] );
printf( "s1: %hx, s2: %hx\n", obj.shortvals[0], obj.shortvals[1] );
printf( "oneCharVal: %hhx\n", obj.oneCharVal );
printf( "oneShortVal: %hx\n", obj.oneShortVal );
この例では、各 2 桁が 1 バイト (8 ビット) であるため、数字がどのように区切られているかを明確にするために 16 進数を使用しました。
現在、これはプロセッサのエンディエンネスにも大きく依存しています。この例は、Intel プロセッサなどのリトル エンディエンに基づいています。ビッグ エンディエン プロセッサは、これらの数値を逆にします。
完全な共用体サイズよりも小さい値をメンバーに割り当てた場合、インスタンスが以前に使用されたことがない場合、残りのスペースは未定義であり、使用されていた場合は以前にあったものの残りが含まれます。前。コンパイラーは、書き込み先のメンバーが占有しているメモリーの部分にのみ書き込みを行い、それを妨害しないように残りをマスクします。次のコード:
printf( "\n" );
printf( "%x\n", obj.longval );
obj.charvals[2] = 0x193;
printf( "%x\n", obj.longval );
次の結果が得られます。
12fe6497
12936497
を書き込む代わりに0x193
、 のみ0x93
が書き込まれ、残りのデータは変更されないことに注意してください。