14
int main()
{
  union {
    struct {
      char c[2];
      char ch[2]; 
    } s;
    struct {
       int i;
       int j; 
    } st;
  } u = { (12, 1), (15, 1) };

  printf("%d %d ", u.st.i, u.st.j);
}

上記はなぜ「257 0」を出力しているのでしょうか。

{}の代わりに を使用すると、どのような違いが生まれ()ますか?

4

4 に答える 4

14

{}サブオブジェクトの初期化を意味します。

()式をグループ化する演算子です。例:(1+3)*2。紛らわしいことに、左側のオペランドを破棄して右側のオペランドを返すコンマ演算子を使用しました。(12,1)と同じ1です。

aを初期化すると、union常に最初のメンバーが設定され、他のメンバーは無視されます。これは、一度に1つのメンバーのみが値を格納できるためです。

初期化に渡す場合のように、スカラー値を使用して配列サブオブジェクトを1初期化するc[2]と、自動的に配列にジャンプします。これはブレースエリジオンと呼ばれます。next1は、配列の2番目のメンバーを初期化します。

1の各文字に割り当ててからc[2]、結果のバイト文字列をリトルエンディアンとして読み戻しますint。アレイch[2]は明示的に初期化されていません。C ++ではゼロに設定されますが、Cでは完全にはわかりません。

明らかに、中括弧の省略が最初に全体を閉じると解釈するため、初期化子{ {12, 1}, {15, 1} }は機能しません。}union

イニシャライザ{{ {12, 1}, {15, 1} }}は、中括弧の省略を回避し、両方の配列を設定します。{ 12, 1, 15, 1 }同じことをする必要があります。

スカラー値とバイト文字列の間の変換は実装定義であることに注意してください。特に、エンディアンとのサイズによって異なりますint

于 2012-12-19T08:07:28.957 に答える
3

との両方(12, 1)(15, 1)(奇妙なことに) に単純化し1ます。これは、Omkant が言ったように、コンマ演算子を使用しているためです。これは、除算された各式を実行しますが、最終的な式の値を返します。ウィキペディアのエントリは、実際にこれをかなりよく説明しています。

その結果、u.s.c[0]最初の 1 でu.s.c[1]満たされ、2 番目の 1 で満たされます。ユニオンは intu.st.iu.c[2]and にオーバーレイするためu.ch[2](8 ビット文字と 32 ビット整数を想定)、アーキテクチャはリトルエンディアンです (結果からわかる) )、u.st.iの値に対して、 の最下位バイトに 1 があり、2 番目に低いバイトに 1 があります256*1 + 1 = 257

一方、 のメモリには値が書き込まれていないu.st.jため、2 番目の出力は 0 です。

于 2012-12-19T08:10:16.247 に答える
0
what the difference will it create if i use {} instead of ().

を使用している場合は(),になりComma operator、割り当てられた値は括弧内の右端の値になります。

ただし、{} ,isの場合、Comma seperator個々の値は対応するメンバーに割り当てられます。ただし、この場合、コンパイルされてエラーがスローされることはありません。

extra brace group at end of initializer.

于 2012-12-19T07:55:40.463 に答える
0

ユニオンのポイントを誤解しているようです。ユニオン内のオブジェクトはメモリを共有しているため、両方ではなく一方のオブジェクトのみを初期化できます。つまり、基になるメモリは同じであり、他の回答で述べたように、常にユニオンを初期化します。最初のメンバーを設定するため、2番目のメンバーを初期化する場合は、C99指定の初期化子を使用できます。

u = {.st={15, 1} };

そして、最初の構造体で配列を初期化するには:

u = { .s={{12, 1}, {15, 1}} };

または.s最初の構造体なし:

u = { {{12, 1}, {15, 1}} };
于 2012-12-19T08:23:37.693 に答える