あなたの質問に適切に答えるには、多次元配列が C でどのように格納されるかを示す行優先順を読んでください。ウィキペディアの記事は少し簡潔すぎますが、次のいずれかがより明確になる可能性があります。
http://webster.cs.ucr.edu/AoA/Windows/HTML/Arraysa2.html
http://archive.gamedev.net/archive/reference/articles/article1697.html
http://www.ibiblio.org/ pub/languages/fortran/append-c.html
このSOの質問もあります。
行優先のストレージがどのように機能するかを知っていると仮定して、あなたのポイントへの直接的な答えとして:
int A[5][2][3]
5*2*3 int の長さのメモリの連続領域を宣言します。それぞれ 3 つの int の 2 つの配列からなる 5 つの配列です。配列は線形メモリに隣り合って格納されるため、
&A[0][0][0] == A
&A[0][0][1] == A+1
&A[0][1][0] == A+(1*3)
&A[3][1][2] == A+(3*(2*3))+(1*3)+2
A[1]
技術的にはポインタではなく配列です。それはint [2][3]
配列です。A[5][2][3]
しかし、長さが 30 int のフラットなメモリ領域を考えるよりも、考えるのがはるかに明確ではないことがわかりました。
A[0][0][0] is the first integer in that region.
A[0][0][1] is the second integer.
A[0][0][2] is the third integer.
A[0][1][0] is the fourth integer in this flat region.
A[0][1][1] is the fifth integer.
And so on until A[1][0][0] is the eleventh integer.
したがって、 のアドレスA[1][0][0]
は の 10 個の整数A[0][0][0]
です。すなわち、&A[1][0][0] - &A[0][0][0] == 10
。C 言語は配列とポインターの違いについて非常に緩いため、A[1]
実際には「2 つの配列からなる 5 つの配列からなる配列の最初の要素」を意味するにもかかわらず、式で使用するとアドレスであるかのように解釈されます。 3 つの整数」は、「3 つの整数の 2 つの配列の配列」です。
結論は、ポインターを格納するのではA[1]
なく、ポインターです。から までのすべてのメモリ アドレスは、多次元配列に整数を格納します。&A[0][0][0]
&A[5][2][3]-1
ポイント (2) と (3) で考えているのは、arrays へのポインターの配列であり、これは別のものです。
これは、図を使って説明する方がはるかに簡単です。そのため、C 配列に関する適切な教科書や記事を見つける必要があります。
一般に、C のポインターと配列について学習するときは、言語自体のことは一時的に忘れて、56kb のフラット RAM を搭載した PDP-11 コンピューターで Dennis Ritchie が C を発明しているふりをすることをお勧めします。大きな方眼紙を用意し、そのセルに連続して番号を付け、それが RAM を表し、各セルが 1 バイトであると仮定します。鉛筆と紙を使ってポインタ計算を行うことができます。
C はその環境で発明されたものであり、その起源を理解することで、現代の言語がより賢明になります。
補足として、この回答を書き込もうとしたときに、スタック オーバーフローのマークアップ言語が繰り返し変更され、上記の配列の例のインデックスが台無しになりました。そのため、配列の範囲外と思われる数値が表示された場合、それはエディターによって導入された間違いです。