それはランダムな設計上の選択にすぎないのでしょうか、それとも C が列優先ではなく行優先をサポートする特定の理由がありますか? Fortran は列優先を使用することを知っています。では、これらのデザインの選択の背後にある理由 (もしあれば) は何ですか?
3 に答える
質問へのコメントのいくつかと他の回答(および私自身の反省のいくつか-ただし、特にC言語の設計プロセスに関する知識はまったくありません...)に基づいて私の答えを基にすると、これは単に基づいた選択だと思いますこの決定を下す人々 (Ritchie?) が必要としていたもの。
多次元配列のインデックスを行列のインデックスとして解釈する場合、最初のインデックスを行のインデックスとして、2 番目のインデックスを列のインデックスとして持つのが理にかなっています。つまり、列優先の構造です。アプリケーションが線形代数やその他の行列を多用する計算に重きを置く場合、一度に 1 列ずつトラバースするのが効率的な方法でこれらの構造を格納することも理にかなっています。これは、多くのアルゴリズムがこれを行うためです。このため、Matlab や Fortran などのプログラミング言語は、列優先であることの恩恵を受けています。これにより、行列や行列アルゴリズムを念頭に置いて効率的なコードを簡単に記述できるようになります。
一方、C は、Matlab や Fortran などよりもはるかに汎用的です。int**
特にmatricesに使用しない場合は、どのインデックスがどれであるかは問題ではありません。a
そして、 ifが anint**
である場合に an を返し、 a[2]
anint*
をa[2][1]
返すのは当然のように思われますint
- 多次元配列を「深く掘り下げる」のです。効率のために、それを取り出してa[2]
反復したい場合は、効率的にキャッシュする必要があるだけです。プログラマであるあなたがa[2]
行列の行または行列の列に関連付けているかどうかは問題ではありません - 私たちは行列を扱っていません!
したがって、C が列優先であるという確固たる根拠はありません (私が頭のてっぺんから理解できることです)。最初のバージョンを実装した時点では、行優先にする方が簡単だったかもしれません。おそらく、基礎となる低レベル言語 (アセンブラー?) がすでに行優先だったからです。
C配列要素は連続したメモリ要素であることが保証されており、2次元配列は配列の配列int a[10][20]
です。a[0]
はそれ自体が配列であり、その要素は連続している必要があります。同様a[0]
に と隣接していa[1]
ます。
C は配列を定義するだけで、配列の要素を配列にすることもできます。配列の配列の場合、最初のインデックスは配列要素を選択し、2 番目のインデックスはその配列の値要素を選択します。意味を逆にすると、非論理的な文法が作成されます。
最初のインデックスを行番号として解釈し、2 番目のインデックスを列番号として 2D マトリックス データ構造に解釈することは、まさに解釈です。
Fortran の (列優先) 配列は、2 つの個別のインデックス演算子を適用してインデックス付けされないことに注意してください。
編集: 信頼できる引用を与えるために、C 標準は、§6.5.2.1 (C99) で、多次元配列に添字を付けた結果が n-1 次元配列である方法を説明した後に述べています。
このことから、配列は行優先順に格納されることがわかります。
(私のものを強調)