
今、動的オブジェクトの勉強をしております。
動的の一次元配列の作り方として
#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]という配列が完成する
}
よろしくお願いします
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] と展開されることを狙っています。
・以上。今後の参考に!→マクロの副作用も注意しましょう。
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 さんのリストはアーキテクチャに優れてますね。
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
上のパート2]のとお礼の場所が逆になってしまいました。
マクロ関数の使う方法はちょっと難しそうですね・・・・
かなり勉強になりました。ありがとうございます
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数から配列を返すには?
-
c言語
-
C言語において、 配列要素をひ...
-
C#で配列が空かを判定するには?
-
define で 配列
-
C言語で重複組合せを全列挙
-
MFCのCArrayを使った二次元配列
-
コンボボックスでデフォルト値...
-
C言語 数値の連続入力について
-
2番目の最大値を求める
-
C#で構造体の配列を持った構造...
-
配列の要素数に変数を入れたい...
-
構造体を引数とする関数について
-
C言語の課題が出たのですが自力...
-
二次元配列による文字列の配列...
-
bmpやImageの配列を関数の引数...
-
callocで二次元配列を作成する...
-
C言語の2次元配列 容量が大き...
-
C言語 構造体でつまずいています
-
二次元配列について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
C言語において、 配列要素をひ...
-
c言語
-
C言語 ファイルの指定された行...
-
define で 配列
-
C#で構造体の配列を持った構造...
-
C言語の課題が出たのですが自力...
-
char型配列をint型に代入するには
-
C#で配列が空かを判定するには?
-
MFCのCArrayを使った二次元配列
-
コンボボックスでデフォルト値...
-
MFC - ダイアログボックスのPic...
-
c言語 構造体
-
2番目の最大値を求める
-
C言語から質問です。
-
Cのエラー
-
プログラミングに関する問題が...
-
C言語の2次元配列 容量が大き...
-
Visual C++を 用いたテキストフ...
おすすめ情報