2

この回答がreinterpret_cast規則に違反していることは知っていますが、サブ配列が線形に割り当てられることも前提としています。

これは保証されていないと信じていましたが、標準を検索すると、自信が揺らいでいます。次のように、2D 配列を静的に割り当てる場合:

int foo[][4] = { { 5, 7, 8 },
                 { 6, 6 },
                 {},
                 { 5, 6, 8, 9 } };

すべての要素が線形に割り当てられると仮定してもよろしいですか? つまりfoo[0]、 がアドレス 0x00000042 にある場合、次のようになります。

  • foo[1]アドレス 0x00000052 にあります
  • foo[2]アドレス 0x00000062 にあります
  • foo[3]アドレス 0x00000072 にあります

これらのアドレスは 16 進数であり、はい、4 要素のサブ配列にスペースを提供していsizeof(int) == 4ます。それらはゼロで初期化される場合とされない場合があります。

4

2 に答える 2

5

サブアレイは線形に割り当てられることが保証されていますか?

はい。配列の要素がサブ配列であろうと非配列オブジェクトであろうと、メモリに連続して格納されることが保証されます。

完全を期すために、標準的な引用を次に示します。

[dcl.配列]

  1. [中略] 配列型のオブジェクトには、連続して割り当てられた、型 T の N 個の部分オブジェクトの空でないセットが含まれています。[中略]

Tが配列の場合も例外ではありません。


したがって、これが の場合であるとは限りませんconst char[4]

それどころか、これが他のタイプで保証されているのと同じように、オブジェクトで保証されていることはわかっています。char[4]

例: const char first[] = "foo"; char foo[][4] = {"bar", "foo", "", "baz"}

first次のようにメモリに格納されます。

{'f', 'o', 'o', '\0'}

foo次のように保存されます。

{'b', 'a', 'r', '\0', 'f', 'o', 'o', '\0', '\0', '\0', '\0', '\0', 'b', 'a', 'z', '\0'}

では、これが int に対して保証されていると言えるのはなぜですか?

int[4]char[4]およびあなたが想像できる他のタイプに対して保証されています。

于 2016-06-27T15:04:14.727 に答える
3

C 言語標準 ISO/IEC 9899 §6.2.5 Types/p20 ( Emphasis Mine ) から:

配列型は、要素型と呼ばれる特定のメンバー オブジェクト型を持つ連続して割り当てられた空でないオブジェクトのセットを記述します。

また、C 言語標準 ISO/IEC 9899 §6.5.2.1/p3 配列添え字( Emphasis Mine ) から:

連続する添字演算子は、多次元配列オブジェクトの要素を指定します。がE次元 の n 次元配列 (n >= 2)の場合i x j x . . . x kE(左辺値以外として使用) は次元 の(n - 1)次元配列へのポインタに変換されますj x . . . x k。添字付けの結果として単項演算*子がこのポインターに明示的または暗黙的に適用された場合、結果は、指す(n - 1)次元の配列になり、左辺値以外として使用された場合は、それ自体がポインターに変換されます。このことから、配列は行優先順で格納されます (最後の添え字が最も速く変化します)。

上記から、2D 配列は実際には行優先順で格納された 1D 配列であると結論付けることができます。

したがって、サブ配列の要素はメモリに連続して格納されていると想定しても問題ありません

于 2016-06-27T15:23:31.363 に答える