はじめての C
基本に 戻って、K&R 2nd を 再チェック、
http://www4.kcn.ne.jp/~yoitiro/hatena/knr2nd_6.txt
2次元配列を 関数に 渡す場合は、列の数 number of columns が なければならない。 渡されるのは 行 row の 配列のポインタだから、行の数 number of rows は 無関係である。
func(int daytab[][13]) { .... }
あるいは
と 書ける。 これは 13個の 配列のポインタで あることを 示している。(p136-137)
func(int (*daytab)[13]) { .... }
下のような 定義が 与えられたとする、
int a[10][20]; /* 2次元配列 */
int *b[10]; /* ポインタ配列 */
このとき
a[3][4]
とb[3][4]
とは 両方とも 構文としては 規則にかなった ある単一の int を 参照している。しかし a は 本物の 2次元配列なので 200個の int サイズの 場所 location が 別に 確保されていて、
a[row][column]
の 要素 element を 求めると、という お約束の 直交的な 添字計算が 実行される。
20 x row + column
b では、しかしながら 10個の ポインタが 割り当てられるだけで、それら - location - は 初期化されていない。
初期化は、static あるいは コードによって 明確に 行わないといけない。
b の それぞれの element が 20個の 要素を 指すためには、200個の int プラス、ポインタ用の cell が 別に 確保されることになる。
ポインタ配列の 有利な点で 重要なのは、配列に 含まれる 行 row が 異なった 長さでも かまわないことである。
つまり、b の それぞれの element が 20個の element をもつ vector を (すべて) 指す 必要がない。
(ある 行 row では) 2つの element を 指し、あるものは 50個、また まったく 何も 指さなくても かまわない。(p138)
これが、「index (補助の ポインタ配列) を 実行時 runtime に 割り当てる」ための 理由か ...
2次元配列を ダブルポインタに 渡す 場合では、
#include <stdio.h>
#include <stdlib.h>int func();
main()
{
short mat[3][4], i, j;
for (i = 0; i < 3; i++)
for (j = 0; j < 4; j++)
mat[i][j] = i * 10 + j;
func(mat);
}
int func(short **mat)
{
short i, j, *index[4];
for (i = 0; i < 3; i++)
index[i] = (short *)mat + 4 * i;
for (i = 0; i < 3; i++) {
printf("\n");
for (j = 0; j < 4; j++)
printf("%5.2d", index[i][j]);
}
printf("\n");
return;
}