5

私は非常に時折、多次元配列を使用し、配列に対して宣言されたものよりも少ない「次元」でのインデックス付けの動作について、標準 (C11 および/または C++11) が何と言っているかに興味を持ちました。

与えられた:

int a[2][2][2] = {{{1, 2}, {3, 4}}, {{5, 6}, {7, 8}}};

標準は、型a[1]が何であるか、またはa[0][1]合法であるか、および期待どおりにサブ配列に適切にインデックスを付ける必要があるかどうかを示していますか?

auto& b = a[1];

std::cout << b[1][1];
4

4 に答える 4

5

m[1]はただのタイプint[2][2]です。同様m[0][1]にちょうどint[2]です。はい、サブ配列としてのインデックス付けは、あなたが思うように機能します。

于 2013-08-01T13:52:37.550 に答える
3

a[i]標準はwhere aisの型を定義していますT [M][N]か?

もちろん。標準では基本的にすべての式の型が定義されており、定義されていない場合は不具合報告となります。しかし、あなたはそのタイプが何であるかについてもっと興味があると思います...

標準はあなたのケースを明示的に言及していないかもしれませんが、ルールは述べられており、 typeaN要素の配列が与えられた場合T、式a[0]は type の左辺値式ですT。変数の宣言int a[2][2]では、 の型はatypeの 2 つの要素の配列 型の 2 つの要素の配列 ですint。これは、上記の規則を適用することは、それが 2 つの要素の配列の左辺値でa[0]あることを意味します。つまり、プログラムで入力する必要があります。余分な寸法を追加しても、メカニズムには影響しません。int (&)[2]

于 2013-08-01T14:10:57.483 に答える
1

覚えておくべき重要な点は、C と C++ の両方で、多次元配列は単に配列の配列であるということです (つまり、3 次元配列は配列の配列の配列です)。多次元配列のすべての構文とセマンティクスは、(もちろん、言語の他の規則からも) それに従っています。

したがって、オブジェクト定義が与えられた場合:

int m[2][2][2];

m型のオブジェクトですint[2][2][2](それぞれが 2 つの要素で構成され、それぞれが 2 つの要素で構成され、それぞれが 2 つの配列である 2 つintの配列の配列)。

あなたが書くときm[1][1][1]、あなたはすでに評価していますmm[1]そしてm[1][1]

mは、 type の配列オブジェクトを参照する左辺値int[2][2][2]です。

ではm[1]、配列式mは配列の最初の要素へのポインタに暗黙的に変換 (「減衰」) されます。このポインタの型は でint(*)[2][2]、 の 2 要素配列の 2 要素配列へのポインタですintm[1]定義上、 と同等*(m+1)です。は1 要素分+1進みm、結果のポインター値を逆参照します。Som[1]型のオブジェクト(それぞれが 2 つの要素int[2][2]で構成される 2 つの配列の配列) を参照します。int

(配列のインデックス演算子は、配列ではなくポインター[]を操作するように定義されています。 のような一般的なケースでは、ポインターはたまたま配列からポインターへの暗黙的な変換の結果です。)arr[42]

に対してプロセスを繰り返し、(タイプ の) m[1][1]2 つの の配列へのポインタを与えます。intint(*)[2]

最後に、m[1][1][1]評価の結果を受け取り、m[1][1]プロセスをもう一度繰り返して、 type のオブジェクトを参照する左辺値を提供しますint。これが多次元配列の仕組みです。

軽薄さに加えて、式のような式はfoo[index1][index2][index3]、配列だけでなくポインターでも直接機能します。つまり、ポインターと任意のサイズの割り当てを使用して、(ほぼ) 真の多次元配列のように機能するものを構築できるということです。これにより、行ごとに異なる数の要素を持つ「不規則な」配列、または行と要素が欠落している可能性さえあります。ただし、各行または各要素の割り当てと割り当て解除を管理するのはあなた次第です。

推奨される読み物: comp.lang.c FAQのセクション 6 。

補足: 多次元配列が配列の配列ではない言語があります。たとえば、(配列のインデックス付けに角括弧ではなく括弧を使用する) Ada では、 のようにインデックス付けされた配列の配列を使用したり、 のようarr(i)(j)にインデックス付けされた 2 次元配列を使用したりできますarr(i, j)。C は異なります。C には、多次元配列に対する直接の組み込みサポートはありませんが、それらを自分で作成するためのツールが提供されます。

于 2013-08-01T15:25:57.897 に答える