• ベストアンサー

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]という配列が完成する } よろしくお願いします

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.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] と展開されることを狙っています。 ・以上。今後の参考に!→マクロの副作用も注意しましょう。

JIF0131
質問者

お礼

完全解決しました。ありがとうございます。 ポインタのポインタを使うという考え方が思いつきませんでした。

その他の回答 (2)

noname#50176
noname#50176
回答No.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 さんのリストはアーキテクチャに優れてますね。

JIF0131
質問者

お礼

ご回答ありがとうございます。参考にします

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.1

★動的な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次元配列の考え方は同じに出来ます。

参考URL:
http://oshiete1.goo.ne.jp/qa3002995.html
JIF0131
質問者

お礼

上のパート2]のとお礼の場所が逆になってしまいました。 マクロ関数の使う方法はちょっと難しそうですね・・・・ かなり勉強になりました。ありがとうございます

関連するQ&A