私はいつもCでそれを信じていました:
int a[5][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
は配列の配列を参照し、メモリには 15 個の連続するブロックが格納されますがa[0]
、 はポインタでa[0][0]
ありa[1]
、 はポインタa[1][0]
です。だから、ポインタの配列に似ていると思いました。それらの違いは何ですか?
配列とポインターは、C (および C++) で非常に興味深い親密な関係にあります。ほとんどのコンテキストでは、「X の配列」であるものがあれば、配列の最初の要素を指す「X へのポインター」に静かに変換されます。
あなたの信念
int a[5][3];
配列の配列を作成することは完全に正しいです。宣言によると、これは でありarray of 5 arrays of 3 ints
、メモリ内で 15 個の連続した整数を占有します。
あなたが間違っているのはa[0]
、ポインターであると信じているところです。実際、a[0]
は の最初のサブ配列でa
あり、それ自体がarray of 3 ints
です。ただし、ポインターと配列の間の不思議な関係により、式a[0]
はほとんど常にポインターに変換されます。
配列の配列とポインターの配列の主な違いの 1 つは、配列要素が存在する場所です。配列の配列は常にメモリの連続したブロックを占有しますが、ポインターの配列内のポインターはそれぞれ独自の (多くの場合ばらばらの) メモリ ブロックを参照します。
配列とポインターは大まかに同じものと見なされます。配列 N long を宣言すると、N long (値型のサイズの倍) のメモリ ブロックが割り当てられ、最初の要素へのポインターが返されます。then のような式はarr[2]
、最初のポインターから順方向にカウントすることにより、そのメモリから値を取得します。配列の配列がある場合、最初の配列 (a
配列内) に格納しているのは、他の配列が格納されている場所へのポインターだけです。(とはいえ、あなたが言ったように、それらは連続したブロックにあるはずだと思います)
それは説明に多少役立ちますか?