■
Cでの2次元配列は、行列である。どういうことかというと、普通行といえば、連続したメモリ領域を想像する。array[][]
はメモリアラインが[0][0]
, [0][1]
, ... [1][0]
, [1][1]
, ...となる。つまりarray[m][n]
は、 n この連続データが m 個という意味になる。だから、array
を行列に見立ててarray[i][j]
をi,j 要素と呼ぶのがふさわしい。ま、0オリジンだけど。
2次元配列を座標と考えると、ちょっと困る。画像データは大抵x軸方向に連続である。通常の感覚ではimage[x][y]
のように使いたくなる。しかし、実際はimage[y][x]
のようにアクセスしないといけない。たとえば、画像データを一気にメモリにロードする場合、この順でないといけない。また、こうでないとx軸方向の連続アクセスに不利である。しかし、xとyが逆転しているので気分が悪い。だから、1次元で確保して、array[x + width * y]
のように計算式を書く。せっかくの配列なのに。
Cの配列演算子(って言うんだっけ?)[]
は2次元配列に対して1つだけ使うと、その行の先頭要素を指す。その性質上、配列の宣言時に最初の要素数(行数)は省略できても2番目の要素数(列数)は省略できない。なぜなら、array[M][N]
と宣言された場合、array[m] == array + m * N + 1
であり、アドレッシングに必要だからである。同様にn次元配列でも、もっとも最初の要素数しか省略できない。
もっと自然な文法を導入したらどうか。[]
はその前の型の配列とする。たとえば、array[4][5]
は、(array[4])[5]
、4要素の配列が5つの配列を作っているというような。これはつまり、array[x][y]
で、xに対して連続なメモリ配置になる。この問題点は、たとえば2行目(y軸に2)の先頭を表わすポインタを取得するのに&array[0][2]
とか書かないといけない。元の文法に比べて、ちょっと見づらい。