プログラムを実行時に、扱う問題のサイズなどがはじめて明らかになることが
あると思います。そのような場合には、前もって使用するデータを
配列として定義できません。かといって、どのような問題にも十分なサイズの配列を
確保しておくのは、メモリーの無駄遣いになりますのでお勧めしません。
そのような場合には、
このページで紹介するような動的な領域確保を行うようにしてください。
特に構造体の配列を確保する例を挙げて説明します。以下のような構造体を
考えます。
typedef struct ptcl_tab { int no; /* particle ナンバー */ double *x; /* particle の座標 n 次元 */ struct ptcl_tab *nb_p[2]; /* 近傍のparticle へのポインタ */ } Particle;
各パーティクルがそれ自身の位置と速度を持ち、隣接パーティクル(2つとしました)
へのポインタを持つようなものを考えます。
問題の次元 n とパーティクル数を動的に取れるように設計しましょう。
#include < stdio.h > typedef struct ptcl_tab { int no; /* particle ナンバー */ double *x; /* particle の座標 n 次元 */ struct ptcl_tab *nb_p[2]; /* 近傍のparticle へのポインタ */ } Particle; main(){ Particle *p; int num_p; int dim; int i; printf("Enter the dimension of X :"); scanf("%d",&dim); printf("Enter the number of particles :"); scanf("%d",&num_p); p =(Particle*) malloc(num_p*sizeof(Particle)); // ここでパーティクルを num_p 個確保している for(i=0; i < num_p; i++){ p[i].no = i; p[i].x = malloc(dim*sizeof(double)); // ここで構造体 p[i] のメンバ x (パーティクル i の位置を表す)のために // n 個分のdouble を確保している。 p[i].nb_p[0] = &p[(i-1+num_p)%num_p]; p[i].nb_p[1] = &p[(i+1)%num_p]; // パーティル番号が隣接するパーティクルのアドレスをポインタ変数に // 格納している。 } for(i=0; i%d\n", p[i].nb_p[0]->no, p[i].no, p[i].nb_p[1]->no); } // 隣接したパーティクルの表示 "." と "->" の使い分けに注意。 }
構造体のメンバーについても、その配列数などが前もって定まらない場合は、 そのメンバをポインタ(必要であればポインタのポインタ)にしておいて、 構造体を確保した後でそのメンバについて領域確保が必要なことに注意して ください。
次に、この領域確保を関数で行う場合を考えましょう。
-----------> 構造体の動的な確保2