課題2についての補足


課題2について、何人かの学生から 「この関数仕様では lights[][] の 値の変更ができない。この配列を global にすれば可能である」 という指摘を受けた。

しかし、結論から言えば、現状の仕様でも問題なくプログラミングできる (Indy の cc コンパイラで動作を確認した)。

出題した仕様において lights という値は

「一列ぶんのデータ」 x 5 の配列
の先頭要素へのポインタである。

ただし、誤解を招きやすい仕様だったかも知れない(ごめんなさい)。

納得できない人のために、下のようなサンプルを作ったので検討せよ。


typedef int linedata[5];
void test_func( linedata lights[] )
/* void test_func( int lights[][5] ) */
/* void test_func( int lights[5][5] ) */
/* これら3つの関数の宣言はどれも正しく動作する */
{
    int i, x, y;
    int *line;

    /* 「一列ぶんのデータ」は5個べったり並んでいるので */
    /* 25個のフラットな int 配列としてもアクセスできる */
    for ( i = 0; i < 25; i++ ) {
	printf( "test [%d] =%d\t", i, (*lights)[i] );
	printf( "test [%d] =%d\n", i, *(*lights + i) );
    }

    for ( y = 0; y < 5; y++ ) {
	line = lights[y];
	for ( x = 0; x < 5; x++ )
	    printf( "test [%d][%d] =%d\n", y, x, line[x] );
    }

}

void main()
{
    int lights[5][5] = { 
	{0,0,0,0,0},
	{0,0,0,0,0},
	{1,0,1,0,1},
	{0,0,0,0,0},
	{0,0,0,0,0} };

    test_func( lights );
}

Takuya NISHIMOTO
Last modified: Mon Nov 11 15:48:52 1996