- ベストアンサー
引数に二重配列のある関数について
void calc(int *a,int b,int c){ a[0]=b+c; a[1]=b-c; } void main(void){ int x[2]; int y=2,z=5; calc(x,y,z); printf("x[0]=%d,x[1]=%d\n",x[0],x[1]); } 上のように引数が普通の配列の関数ならできるのですが, 引数が下のような多重配列になるとエラーが出てしまいできません。 void keisan(int **a,int b,int c){ a[0][0]=b+c; a[0][1]=b-c; a[1][0]=b*c; a[1][1]=b/c; } void main(void){ int x[2][2]; keisan(x,6,2); printf("x[0][0]=%d,x[0][1]=%d\n",x[0][0],x[0][1]); printf("x[1][0]=%d,x[1][1]=%d\n",x[1][0],x[1][1]); } 引数に多重配列を使った場合の関数の作り方について教えてください. お願いいたします.
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
2次元配列というのは、2つの添え字を使って表のイメージでデータを扱えるので大変便利なのですが、結局メモリの中では1次元配列と同じように、直線的にデータが配置されています。 つまり int x[2][2]; x[0][0] = 1; x[0][1] = 2; x[1][0] = 3; x[1][1] = 4; と定義されているとすると、メモリの中では、 x 1 2 3 4 となっています。 ためしに x[0][2] を表示してみると、3 が表示されます。 この2次元配列xは、1次元目(1番右)の要素数が2個であると宣言されているので、x[1][0] とアクセスするだけで、xから3番目のデータを取り出すことができるわけです。 ところが関数keisanで宣言されている int **a には、この「要素数の情報」がないため、 a[1][0] がメモリのどこにアクセスすればよいのか分からないので、エラーとなってしまうのです。 これを解決するには、2次元配列を受け取る変数の宣言に、1次元目の要素数情報を与えてやればよいわけです。宣言方法は次の通りです。 void keisan(int a[ ][2], int b, int c); 仮引数の宣言で配列を宣言しても、同等の配列へのポインタになるので、配列が丸々コピーされることはありません。 2次元目の要素が空になっていますが、配列が用意されるわけではないので、ここには2を入れても全く意味がありません。入れても無視されます。 ちなみにsssoheiさんの int a[2][ ] や、int a[2][ ] は文法違反です。 また int *a[2] という宣言は、ポインタ配列を受け取る場合の書き方で、やはりこの場合はエラーになります。 3次元以上の配列の場合でも、考え方は同じです。ただし要素数を省略できるのは、1番左だけということを覚えておいてください。 下記は、int x[2][3][4]; と宣言された変数aを受け取るための引数の宣言です。 void func(int a[ ][3][4]);
その他の回答 (3)
int* a[2] は駄目だけど, int (*a)[2] なら OK (もちろん int a[][2] でも OK) int型の大きさ 2の配列 2個からなる二重配列 x[2][2] の配列名 xを単独で書いた時の型は int** 型ではなく, int (*)[2] または int a[][2] 型 なのでこう書かなければいけない. int** はint型の値を指すポインタのポインタの型, int(*)[n] はint型の値をn個並べた配列へのポインタの型, で両者は全く異なる型である. ついでに,main の返却値は void でなく int が正しいと思います。
- sssohei
- ベストアンサー率33% (33/98)
int ** ではコンパイラはどのくらいの大きさの 配列なのかが分からないので、コンパイルエラーが出ます。 そこで、 int a[2][] のように、記述する必要があります。 三重の場合は int a[2][2][] の様に記述します。 もちろん、 int a[2][2] の様に記述しても構いませんし、 int* a[2] でも大丈夫だと思います^^; 記憶の中のものなので、実際試してみてください^^;
コンパイルかけてみたところ、以下のようなエラーでした。 ==================================================================================== "test.c", 54 行目: 警告: 1 番目の引数は、プロトタイプ宣言の型と互換性がありません: プロトタイプ: pointer to pointer to int : "test.c", 41 行目 引数 : pointer to array[2] of int ==================================================================================== 関数のほうはintのポインタのポインタを引数として求めているのに、 mainはintの配列を引数として渡しているからこのエラーが出たのだと思います。 そこで以下のように関数の宣言を変えてみたところ、うまくいきました。 void keisan(int **a,int b,int c) ↓ void keisan(int a[2][2],int b,int c)