C プログラミング言語 (ANSI-C) に関する簡単な質問:
C の多次元配列はギザギザですか?
つまり、私たちは「配列の配列」(メモリ内の他のアドレスへのポインターの 1 つの配列)について話しているのでしょうか、それともこれは単に「長い 1 次元配列」(メモリ内に順番に格納される)のことでしょうか?
私が気になっているのは、次のことが確かだということです。
matrix[i][j]
は以下と同等である* ( * (matrix + i) + j)
ベストアンサー1
C の多次元配列は連続しています。次のようになります。
int m[4][5];
int[5]
メモリ内で隣り合って配置された4 つの で構成されます。
ポインタの配列:
int *m[4];
ギザギザです。各ポインタは、異なる長さの別々の配列(の最初の要素)を指すことができます。
m[i][j]
は と同等です*(*(m+i)+j)
。C11規格、セクション6.5.2.1:
添字演算子[]の定義は、E1[E2]が(*((E1)+(E2)))と同一であるということです。
したがって、はm[i][j]
と同等であり(*(m+i))[j]
、 は と同等です*(*(m+i)+j)
。
この同等性が存在するのは、ほとんどのコンテキストで配列型の式が最初の要素へのポインターに減少するためです (C11 標準、6.3.2.1)。m[i][j]
次のように解釈されます。
m
は配列の配列なので、m[0]
最初の部分配列へのポインタになります。m+i
i
は の 番目のサブ配列へのポインタですm
。m[i]
は と同等であり、の 番目のサブ配列*(m+i)
へのポインタを逆参照します。これは配列型の式なので、 へのポインタになります。i
m
m[i][0]
m[i][j]
は と同等であり、の 番目のサブ配列の 番目の要素*(*(m+i)+j)
へのポインタを逆参照します。j
i
m
配列へのポインターは、配列の最初の要素へのポインターとは異なることに注意してください。 はm+i
配列へのポインターです。配列型の式ではなく、ポインターへのポインターであろうと他の型であろうと、減衰しません。