7

私は C++ チャットで誰かと言語にとらわれない議論をしましたが、彼は配列の配列と多次元配列は 2 つのことだと言いました。

しかし、私が学んだことから、多次元配列はすべて同じサイズの他の配列の配列にすぎません。特に彼はこう言っています

まあ、それらは一種のCであり、ネストされた配列で複数の次元をシミュレートしますが、それはCが実際に複数の次元配列をサポートしていないためです.

「多次元配列」の標準的なコンピューターサイエンスの定義とは何か、そしてなぜC(または抽象的な定義「配列の配列」)がその定義に適合しないのかを誰かが説明できますか?

4

5 に答える 5

8

これをうまく説明する .NET 配列を見てみましょう。

C# では、ネストされた方法で定義されたジャグ配列が区別されます。

int[][] jagged = new int[3][];

ネストされた各配列の長さは異なる場合があります。

jagged[0] = new int[3];
jagged[1] = new int[4];

(そして、ネストされた配列の 1 つがまったく初期化されていないことに注意してください。つまり、null.)

対照的に、多次元配列は次のように定義されます。

int[,] multidim = new int[3, 4];

ここで、ネストされた配列について話すのは意味がありません。実際にアクセスしようとするmultidim[0]と、コンパイル時のエラーになります。すべての次元を指定してアクセスする必要がありますmultidim[0, 1]

上記の宣言が示すように、それらのタイプも異なります。

さらに、それらの扱いはまったく異なります。たとえば、タイプ のオブジェクトを使用して、上記のジャグ配列を反復処理できますint[]

foreach (int[] x in jagged) …

ただし、多次元配列の反復処理は type の項目で行われますint:

foreach (int x in multidim) …

概念的には、ジャグ配列は配列の配列(配列の配列の… 無限大)Tあり、多次元配列はアクセス パターンが設定された配列ですT(つまり、インデックスはタプルです)。

于 2012-06-24T13:08:01.643 に答える
1

ウィキペディアから:

多次元配列

要素を指定するために必要なインデックスの数は、配列型の次元、次元、またはランクと呼ばれます。(この命名法は、要素の数である線形代数の次元の概念 [5] と矛盾します。したがって、5 行 4 列、つまり 20 要素の数値の配列は、コンピューティング コンテキストでは次元 2 を持つと言われます。ですが、数学では 4 行 5 列または 20 次元の行列を表します。また、コンピューター サイエンスにおける「ランク」の意味は、テンソル代数での意味と似ていますが、線形代数の行列のランクの概念とは似ていません)。

多くの言語では、1 次元配列のみがサポートされています。これらの言語では、通常、多次元配列は Iliffe ベクトル (1 次元少ない配列への参照の 1 次元配列) で表されます。特に、2 次元配列は、その行へのポインターのベクトルとして実装されます。したがって、配列 A の行 i および列 j の要素は、二重インデックス (一般的な表記法では A[i][j]) によってアクセスされます。多次元配列をエミュレートするこの方法により、各行のサイズが異なる不規則またはギザギザの配列を作成できます。または、一般に、各インデックスの有効な範囲は先行するすべてのインデックスの値に依存します。

多次元配列のこの表現は、C および C++ ソフトウェアで非常に一般的です。ただし、C および C++ では、従来の int **A の代わりに、int A[10][20] または int A[m][n] などで宣言された多次元配列に対して線形インデックス式を使用します。 [6]:p.81

多次元配列をサポートする言語の例については、こちらを参照してください。

于 2012-06-24T13:08:19.640 に答える
1

C には多次元配列はありませんが、C には配列の配列があります。

標準では多次元配列という表現が使用されていますが、C 多次元配列は実際には配列の配列です。Kernighan & Ritchie より:

「C では、2 次元配列は実際には 1 次元配列であり、その各要素は配列です。」

一部の言語では、多次元配列がファースト クラスの型としてサポートされています。「Expert C Programming」ブックには、配列の配列と多次元配列の両方をサポートする Ada の例が示されています。

于 2012-06-24T13:18:36.670 に答える
1

私は彼の主張を理解しています。彼は実際には実装の観点からそれらを区別していますが、どちらも多次元配列と言うには実際には有効です。

「配列の配列」の種類は、言語レベルでは複数のインデックスを介して参照されますが、実際には 1 次元配列として実装されるため、線形インデックスを使用します。例、C:

int a[5][5];

実際には次と同じ構造になります。

int a[25];

コンパイラは、次のようなアクセスを変換します。

a[i][j]

に:

a[i * jDimensionWidth + j]

上記の例では jDimensionWidth = 5 です。また、次のようにアクセスすることもできます。

int* b = (int*) a;
printf("%d\n",b[12] == a[2][2]); // should output 1

「多次元配列」の種類は、彼が言ったように Iliffe ベクトルを介して実装されます。ベクトルは通常、ヒープ オブジェクトとして実装されるため、アドレスも線形ではないため、インデックスを線形化することはできません。この種の多次元配列は次の式に適合しません (2 次元配列の場合):

addr(a[i + 1]) = addr(a[i]) + (a[i].width * sizeof(a[i][j].datatype))

これは、「配列の配列」の種類によって実現されます。

于 2012-06-24T13:19:47.780 に答える
1

多次元配列には、「次元数を教えてください」、「特定の列を提供してください」、「特定のサブビューを提供してください」などの操作が提供されることを期待しています。C 配列はこれらの操作を提供しません。

于 2012-06-24T13:03:44.720 に答える