プログラミング言語 C
C の 初心者は ときどき 2次元配列と、例として でてきた name のような ポインタ配列との 違いについて 混乱することがある。
下のような 定義が 与えられたとする:
int a[10][20]; /* 2-dimensional array */
int *b[10]; /* pointer array */
このとき、a[3][4] と b[3][4] とでは 両方とも 構文としては 規則に適った ある単一の int を 参照している。
しかし a は 本物の 2次元配列なので 200個の int サイズの location が 別に 確保されていて、a[row, col] の element を 求めると 20 x row + column という お約束の 直交的な 添字計算が 実行される。
b では、しかしながら、定義によって 10個の ポインタが 割り当てられるだけで、それら (← location) は 初期化されていない。
初期化は、static あるいは コードによって 明確に 行なわないといけない。
b の それぞれの element が (実際 すべての) 20個の element の 配列を 指すためには、200個の int プラス、ポインタ用の cell が 別に 確保されることになる。
ポインタ配列の 有利な点で 重要なのは、配列に 含まれる row が 異なった長さでも かまわないことである。 つまり、b の それぞれの element が (すべて) 20個の element を もつ ベクタを 指す必要はない。 (ある row では) 2つの element を 指し、あるものは 50個、また まったく 何も指さなくても かまわない。
ここまでの 議論では 整数 (integer) に 関してのみ 扱ったが、ポインタ配列が しばしば 用いられるのは、関数 month_name のように 異なった長さの 文字列を 格納するときである。(p138-139)
ポインタ配列の 宣言と ベクタとを、同じく 2次元配列の それと 比較してみよう:
char *name[] = {"Illigal month", "Jan", "Feb", "Mar"};
(vector) name:
. -----> Illigal month\0
. -----> Jan\0
. -----> Feb\0
. -----> Mar\0
char aname[][15] = {"Illigal month", "Jan", "Feb", "Mar"};
aname:
Illigal month\0 Jan\0 Feb\0 Mar\0
0 15 30 45