2D配列を実装したい場合; 次のどの技術を好むか
1.行メジャー/列メジャー 2.ポインターの配列
この本Numerical Recipes in C
(オンライン版) の 20 ~ 23 ページに、2 次元配列の実装方法について説明している章があります。
2D 配列の使用が複数の関数で使用されている場合、またはサイズが大きすぎる場合は、以下のようにポインター変数を使用して 2D 配列を動的に割り当てることができます。
int *a;
a = (int *)malloc(ROWSIZE * COLSIZE * sizeof(int));
//This 2D dynamic array should be accessed like below
for (i = 0; i < ROWSIZE; i++)
{
for (j = 0; j < COLSIZE; j++)
{
a[(i * ROWSIZE) + j] = i + j;
}
}
または、以下のようにダブルポインター変数を使用することもできます
int **a;
a = (int **)malloc(ROWSIZE * sizeof(int*));
for(i = 0; i < ROWSIZE; i++)
{
a[i] = (int *)malloc(COLSIZE * sizeof(int));
}
//This 2D dynamic array should be accessed like below
for (i = 0; i < ROWSIZE; i++)
{
for (j = 0; j < COLSIZE; j++)
{
a[i][j] = i + j; //readability is more in this method
}
}
2D 配列の使用が関数内のみで、サイズが大きすぎない場合は、ローカル 2D 配列を使用できます。動的メモリ割り当てはコストのかかるプロセスであるためです。
int a[ROWSIZE][COLSIZE];
注:nullチェックに注意してくださいmalloc
確かに、ポインターの配列アプローチは、古き良き C 構文、つまり a[3][4] で配列の要素をアドレス指定できるという優れた構文上の利点を提供します。また、プロジェクトに適合する場合は、各行を異なる長さにすることができます。ただし、メモリ管理は努力する価値がないと思います。アクセスごとに2つの逆参照手順が必要になるため、パフォーマンスが低下する可能性があります。行を割り当てていると仮定すると、それらをC配列として扱い、パフォーマンスを最適化できますが、列は常に便利ですが遅い方法で索引付けする必要があります。
単一の割り当て方法での行または列の主要な順序に関しては、これは何をしたいかによって完全に異なります。連続した行が必要になる可能性が高い場合は、行優先を使用します。線形代数を行っている場合は、列を操作することがより一般的であるため、列優先の方が便利です。
数値計算ソフトウェアでかなりの量の作業を行った結果、単一の割り当て方法が最適であることがわかりました。Fortran とのインターフェースが簡単なため、私は通常、列優先を使用します。