0

ユニオンのサイズは、その最大のメンバーのサイズであることを知っています。それがどのように表現されているかを推測することはできません。状況を考慮する

union x
{
    int a;
    char b;
    short int c;
}obj;
   int main()
   {
        obj.a=3;
        printf("%d %c %d",obj.a,obj.b,obj.c);
   }

出力は何になり、どのように生成されますか? 前もって感謝します

4

1 に答える 1

1

共用体には 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が書き込まれ、残りのデータは変更されないことに注意してください。

于 2013-05-23T21:19:54.270 に答える