プログラミング言語 C の新機能 Part XX: ARR#0:可変長配列: 関数引数
(1999/09/06 [月])
関数ブロックの中に、可変長配列を宣言することができますが、もちろん関数の引数にも使うことができます。例えば、(1)のようにして使用します。可変長配列の中に使う変数は、そこで使用する以前に他で宣言されていて、コンパイラに対して可視になっている必要があります。したがって、void sumup(int data[m][n], int m, int n){ ... } のような関数定義は、ファイルスコープレベルで m や n という整数変数が宣言されていない限りエラーになります。
この関数に対するプロトタイプ宣言は、次の(2)のように記述することができます。特に、可変長配列であることを特に変数を示すことなく宣言できるようにするため、[*] という記述方式を使うことができます。この書き方はプロトタイプ宣言の中だけで使用することができ、関数定義では使用することができません。
しかし、(2)の例では、別に [*] を使わなくてもプロトタイプ宣言をすることができます。どうして、[*] という表記が必要なのでしょうか? そのための例を (3) に示します。
この関数のプロトタイプの宣言を単純に記述すると、(4.1) のように記述することになりますが、この場合、m や n は data の中で参照する前で宣言されていないので問題になります。そのような時、(4.2) のように [*] という記述方法を使用することでそのエラーを回避することができるのです。
//(1)関数本体の定義 void sumup(int m, int n, int data[m][n]) { int i, j, r = 0; for(i = 0; i < m; i++) for(j = 0; j < n; j++) r += data[i][j]; return r; } |
この関数に対するプロトタイプ宣言は、次の(2)のように記述することができます。特に、可変長配列であることを特に変数を示すことなく宣言できるようにするため、[*] という記述方式を使うことができます。この書き方はプロトタイプ宣言の中だけで使用することができ、関数定義では使用することができません。
//(2)プロトタイプ宣言 void sumup(int m, int n, int data[m][n]); void sumup(int m, int n, int data[*][*]); void sumup(int m, int n, int data[ ][*]); void sumup(int m, int n, int data[ ][n]); |
しかし、(2)の例では、別に [*] を使わなくてもプロトタイプ宣言をすることができます。どうして、[*] という表記が必要なのでしょうか? そのための例を (3) に示します。
//(3)* がないと困る例 void sumup(data, n, m) int n, m; int data[m][n]; { ... } //(4)↑のプロトタイプ void sumup(int data[m][n], int m, int n);//(4.1)m,n の宣言より前の参照! void sumup(int data[*][*], int m, int n);//(4.2)OK |
この関数のプロトタイプの宣言を単純に記述すると、(4.1) のように記述することになりますが、この場合、m や n は data の中で参照する前で宣言されていないので問題になります。そのような時、(4.2) のように [*] という記述方法を使用することでそのエラーを回避することができるのです。
by seclan