プロが教えるわが家の防犯対策術!

今、動的オブジェクトの勉強をしております。
動的の一次元配列の作り方として
#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]という配列が完成する
}


よろしくお願いします

A 回答 (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] と展開されることを狙っています。
・以上。今後の参考に!→マクロの副作用も注意しましょう。
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/05/23 20:04

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 さんのリストはアーキテクチャに優れてますね。
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/05/23 20:05

★動的な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
    • good
    • 0
この回答へのお礼

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

お礼日時:2007/05/24 01:19

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!