彼の著書The C++ Programming Languageで、Bjarne Stroustrup は次のように述べています (C.7.2; p. 838 of the Special Edition、2000):
...ma
次のように初期化できます。
void int_ma() {
for(int i=0; i<3; i++)
for(int j=0; j<5; j++) ma[i][j] = 10 * i + j; }
...
配列は、あたかも 5 の 3 つの配列であるかのようにアクセスするma
単純な 15のs です。特に、メモリには行列である単一のオブジェクトはなく、要素のみが格納されます。次元 3 と 5 は、コンパイラ ソースにのみ存在します。int
int
ma
(強調鉱山)。
つまり、表記法[][]...[]
はコンパイラの構造です。必要に応じて構文糖衣。
娯楽目的で、次のコードを書きました。
#include<cstdlib>
#include<iostream>
#include<iterator>
#include<algorithm>
int main() {
double ma[5][3]; double *beg = &ma[0][0]; // case 1
//double ma[3][5]; double *beg = &ma[0][0]; // case 2
//double ma[15]; double *beg = &ma[0]; // case 3
double *end = beg + 15;
// fill array with random numbers
std::generate(beg, end, std::rand);
// display array contents
std::copy(beg, end, std::ostream_iterator<double>(std::cout, " "));
std::cout<<std::endl;
return 0;
}
また、コンパイル コマンド (GCC 4.7.2) を使用して、3 つのケースで生成されたアセンブリを比較しました。
g++ test.cpp -O3 -S -oc1.s
ケースはc1.s
、c2.s
、および と呼ばれc3.s
ます。コマンドの出力shasum *.s
は次のとおりです。
5360e2438aebea682d88277da69c88a3f4af10f3 c1.s
5360e2438aebea682d88277da69c88a3f4af10f3 c2.s
5360e2438aebea682d88277da69c88a3f4af10f3 c3.s
ここで、最も自然な構成は の 1 次元宣言ma
、つまりのように思われることを述べておかなければなりませんdouble ma[N]
。最初の位置は単純ma
に であり、最終的な位置は単純に であるからですma + N
(これは、最初の配列の要素)。
この場合、C++ 標準ライブラリ ヘッダーによって提供されるアルゴリズムが<algorithm>
はるかにぴったりと適合することがわかりました。
最後に、可能であればstd::array
orの使用を検討することをお勧めします。std::vector
乾杯。