はじめての C

Arrays and Pointers in C

2次元配列を サブルーチンに 渡す 方法は、どうすれば 可能なのか ?

C において、FORTRAN プロシージャや 別の C の ルーティンから 渡される 配列を 処理するための 選択肢には、下の 5つが あります。

/*
ここで さまざまな 方法で 宣言し 用いられる 配列には、short型 3x3 (整数 2組) の
配列を、例として あげています。

これら 5つ すべての 方法は、DEC の VAX/VMS 機で 作動します。
*/

#include <stdio.h>
#include <stdlib.h>

int func1();
int func2();
int func3();
int func4();
int func5();

main()
{
short mat[3][3], i, j;

for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
{
mat[i][j] = i * 10 + j;
}

printf("Initialized data to:");

for (i = 0; i < 3; i++)
{
printf("\n");
for (j = 0; j < 3; j++)
{
printf("%5.2d", mat[i][j]);
}
}
printf("\n");

func1(mat);
func2(mat);
func3(mat);
func4(mat);
func5(mat);
}

/*
方法 1 (トリックは 用いない。最初の 次元が 空の 配列)
最初の 次元を 指定することは 絶対厳禁 !
*/

int func1(short mat[][3])
{
register short i, j;

printf("Declare as matrix, explicitly specify second dimension:");

for (i = 0; i < 3; i++)
{
printf("\n");
for(j = 0; j < 3; j++)
{
printf("%5.2d", mat[i][j]);
}
}
printf("\n");

return;
}

/*
方法 2 (配列への ポインタ。 2つ目の 次元を 明示的に 指定)
*/

int func2(short (*mat)[3])
{
register short i, j;

printf("Declare as pointer to column, explicitly specify 2nd dim:");

for (i = 0; i < 3; i++)
{
printf("\n");
for (j = 0; j < 3; j++)
{
printf("%5.2d", mat[i][j]);
}
}
printf("\n");

return;
}

/*
方法 3 (シングルポインタを 使用。配列は "flattened" に)
この方法では、広い 用途をもつ ルーティンを つくることができる。
宣言の どこにも 次元が あらわれないため、引数の リストを 式に
とり込むことで、それらを つけ加えることが できる。
manual での 配列インデックスは、多分 その実行が 遅れるはず。
*/

int func3(short *mat)
{
register short i, j;

printf("Declare as single-pointer, manual offset computation:");

for (i = 0; i < 3; i++)
{
printf("\n");
for (j = 0; j < 3; j++)
{
printf("%5.2d", *(mat + 3 * i + j));
}
}
printf("\n");

return;
}

/*
方法 4 (ダブルポインタ。 ポインタ配列を 補助で 使用)
この方法は、インデックスを ランタイムに 割り当てることで、
広い 用途をもつ ルーティンを つくることができる。
次元は、引数のリストを 式に とり込むことで つけ加える。
*/

int func4(short **mat)
{
short i, j, *index[3];

for (i = 0; i < 3; i++)
index[i] = (short *)mat + 3 * i;

printf("Declare as double-pointer, use auxiliary pointer array:");

for (i = 0; i < 3; i++)
{
printf("\n");
for (j = 0; j < 3; j++)
{
printf("%5.2d", index[i][j]);
}
}
printf("\n");
}

/*
方法 5 (シングルポインタ。 ポインタ配列を 補助で 使用)
*/

int func5(short *mat[3])
{
short i, j, *index[3];

for (i = 0; i < 3; i++)
index[i] = (short *)mat + 3 * i;

printf("Declare as single-pointer, use auxiliary pointer array:");

for (i = 0; i < 3; i++)
{
printf("\n");
for (j = 0; j < 3; j++)
{
printf("%5.2d", index[i][j]);
}
}
printf("\n");

return;
}

コンパイルして 実行させると、mat[row][column] の 結果は すべて 次のように なります。
        matrix
+----+----+----+
| 00 | 01 | 02 |
+----+----+----+
| 10 | 11 | 12 |
+----+----+----+
| 20 | 21 | 22 |
+----+----+----+