この連載の第4回で配列を取り上げたとき,C言語のポインタに触れて『ポインタは同じ型のデータが並んでいる状態――すなわち配列を扱うための便利な機能なのだ』と説明した。ポインタと配列は密接な関係にある。第4回では,文字列の扱いを例にchar型配列をポインタで効率的に扱えることを示した。では,もっと複雑な配列ではどうなるのだろう?さらに他のデータ構造では…?そんなわけで今回は,ポインタの持つ便利な機能を追加調査した。

メモリー上に規則正しくデータが並ぶ

 まずは,ポインタを使った配列操作の基本を簡単におさらいしておこう。配列は同じ型のデータが一列に並んでいることに大きな意味があった。

 例えば,Cでshort int型のデータが6個並んだ配列numを宣言するには,以下のように記述する。

 short int num[6];

 配列の個々の要素は,添え字(インデックス)を使って明示できる。変数名に続けて,[ ]内に添え字を指定する。Cの配列では,先頭の要素番号は0なので,この配列の個々の要素はnum[0]~num[5]で参照できる*1

 Cでは,配列の各要素は必ずメモリー上の連続した領域に配置される。このため,先頭要素のアドレスがわかれば,そこを起点にして,そのポインタ値を1ずつ増やしていくことで配列のすべての要素を参照できる(図1)。

図1●short int型のデータが6個並んだ配列numのメモリーの状態
図1●short int型のデータが6個並んだ配列numのメモリーの状態
[画像のクリックで拡大表示]

 以下のようなコードでshort int型の変数を6個宣言した場合にも,short int型のデータを6個格納できる領域が確保される。

 short int a, b, c, d, e, f;

 しかし,この場合はメモリー上の連続した領域が確保されるとは限らない*2。つまり,配列のように一つのポインタ値を起点にしてアクセスすることはできない。図1のように規則正しく並んだ状態であるからこそ,効率的に扱うことができるわけだ。

ポインタ経由で多次元配列にアクセスする

図2●1次元/2次元/3次元配列のイメージ
図2●1次元/2次元/3次元配列のイメージ
[画像のクリックで拡大表示]

 先の例の配列は,同じ型のデータが1列に並んだ「1次元配列」である。配列には,同じ型のデータが横に1列並び,さらにその列が複数の行を作る形の2次元配列,2次元配列を複数重ねた形の3次元配列など,多様な形態がある。これらをまとめて「多次元配列」と呼ぶ。

 1次元配列は,配列名と1個の添え字ですべての要素にアクセスでき,直感的にわかりやすい。これに比べると,多次元配列を理解するにはちょいと頭をひねる必要がある。2次元配列や3次元配列は,表計算ソフトを思い浮かべればわかりやすいだろう。1次元配列は横方向に並んだ列,2次元配列は横方向の列と縦方向の行で構成された表(ワークシート),3次元配列は同じ形式のワークシートの集合(Excelなら「ブック」)――と,とらえればいい(図2)。もちろん,4次元以上の配列もあり得るわけだが,実務でそこまで複雑なデータ構造を用いることは極めてまれだ*3