- ベストアンサー
callocで二次元配列を作成するには?
今、動的オブジェクトの勉強をしております。 動的の一次元配列の作り方として #include <stdio.h> #include <stdlib.h> int main(void) { int *a; int x; printf("配列の大きさX入力>"); scanf("%d",&x); a=calloc(x,sizeof(int)); return (0); } これでいいと思うんですが動的な2次元配列を 作りたいときはどのようにすればよろしいのでしょうか? (↓作りたい二次元配列の例(1)↓) int main(void) { int *a; int x , y; printf("配列の大きさX入力>"); scanf("%d",&x); //5と入力 printf("配列の大きさY入力>"); scanf("%d",&y); //10と入力 上のように入力するとa[5][10]という配列が完成する } よろしくお願いします
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
★動的な2次配列の作り方。パート2 ・マクロ関数のバージョンも載せておきます。 // これがマクロ関数 #define MacroCell(a,x,y) ((a)[(y) * arrayX + (x)]) サンプル: int main( void ) { int *a; int arrayX; ←この名前とマクロ関数の定義を対応させること。 int arrayY; printf( "配列の大きさX入力>" ); scanf( "%d", &arrayX ); //5と入力 printf( "配列の大きさY入力>" ); scanf( "%d", &arrayY ); //10と入力 if ( (a = (int *)calloc((arrayX * arrayY),sizeof(int))) != NULL ){ MacroCell(a,0,0)⇒X=0、Y=0 MacroCell(a,4,0)⇒X=4、Y=0 : MacroCell(a,0,9)⇒X=0、Y=9 MacroCell(a,4,9)⇒X=4、Y=9 MacroCell(a,4,9) = 12345; ←代入時 printf( "a[9][4] = %d\n", MacroCell(a,4,9) ); ←参照時 free( a ); } return 0; } その他: ・マクロ関数を作るときの注意点として、仮引数になる部分にカッコを付けます。 つまり、(y) とか、(x) とか、(a) とすること。カッコをなくして y、x、a とすると マクロの呼び出しで MacroCell( a, 3, 2 + 3 ) となっている場合に a[ 2 + 3 * arrayX + 3 ] と展開されます。すると a[ 3 * arrayX + 5 ] と計算されてしまいます。このためカッコをつけておくと a[ (2 + 3) * arrayX + (3) ] と展開されて正しく a[ 5 * arrayX + 3 ] と解釈されます。 ・また、配列名を表す a にも括弧を付けます。 これも同様にマクロ関数の呼び出しで MacroCell( a + 5, X, Y ) とした場合に正しく (a + 5)[Y * arrayX + X] と展開されることを狙っています。 ・以上。今後の参考に!→マクロの副作用も注意しましょう。
その他の回答 (2)
Oh-Orange さんの完璧ですね・・・(驚) 私だったら、 #include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <windows.h> #define cell(X,Y,a,x)(a+X+x*Y) // X=1次側、Y=2次側、a=配列先頭ポインタ,x=配列の大きさのX int main(void) { int *a; int x , y , X , Y, data; printf("配列の大きさX入力>"); scanf("%d",&x); printf("配列の大きさY入力>"); scanf("%d",&y); a=(int*)calloc(x*y,sizeof(int)); X=1,Y=4; *cell(X,Y,a,x)=2; data=*cell(X,Y,a,x); printf("%d\r\n",data); free(a); return 0; } のようにします。 Oh-Orange さんのリストはアーキテクチャに優れてますね。
お礼
ご回答ありがとうございます。参考にします
- Oh-Orange
- ベストアンサー率63% (854/1345)
★動的な2次配列の作り方。 ・文章での説明が苦手なのでサンプルを載せます。 サンプル: int main( void ) { int *a; int **aa; ←これ追加。 int i, x, y; printf( "配列の大きさX入力>" ); scanf( "%d", &x ); //5と入力 printf( "配列の大きさY入力>" ); scanf( "%d", &y ); //10と入力 if ( (a = (int *)calloc((x * y),sizeof(int))) != NULL ){ if ( (aa = (int **)calloc(y,sizeof(int*))) != NULL ){ for ( i = 0 ; i < y ; i++ ){ aa[ i ] = &a[ i * x ]; } aa[0][0]⇒X=0、Y=0 aa[0][4]⇒X=4、Y=0 : aa[9][0]⇒X=0、Y=9 aa[9][4]⇒X=4、Y=9 free( aa ); } free( a ); } return 0; } その他: ・a は X、Y の全体のメモリを確保しています。 aa は a のメモリ領域の Y 軸のポインタを格納した配列です。 よって、aa[Y][X] としてアクセスすればよい。 ・他にも方法はありますが、この方法が一番メモリの使用量や確保回数が少ないと思います。 あとマクロ関数を利用すれば a のメモリ領域だけを確保してマクロ関数でアクセスする 方法がメモリ量を一番抑えることが出来ます。 ・以上。おわり。→3次元配列の考え方は同じに出来ます。
お礼
上のパート2]のとお礼の場所が逆になってしまいました。 マクロ関数の使う方法はちょっと難しそうですね・・・・ かなり勉強になりました。ありがとうございます
お礼
完全解決しました。ありがとうございます。 ポインタのポインタを使うという考え方が思いつきませんでした。