多次元配列が関数に渡されるとき、なぜ C++ は最初の次元を除くすべてをパラメーター li で指定する必要があるのですか?
4 に答える
これを尋ねるより良い方法は、C++ が最初の次元を指定する必要がない理由を尋ねることです。
その理由は、すべての配列について、配列を値で関数に渡すことができないためです。配列を取る関数を宣言しようとすると、コンパイラは宣言を対応するポインター型に調整します。
これは、ディメンションが関数シグネチャの一部を形成しないため、どのディメンションを指定しても問題ないことを意味します。
たとえば、これらはすべてまったく同じ関数を宣言しています。
void f(int *p);
void f(int p[]);
void f(int p[10]);
void f(int p[100]);
関数内で が指す配列をナビゲートする場合p
、コンパイラが必要とする唯一の情報は、配列要素のサイズです。つまりsizeof(int)
、この場合です。
より複雑な配列の場合、まったく同じことが当てはまります。これらはすべて同じです。
void g(Type p[][10][20]);
void g(Type (*p)[10][20]);
void g(Type p[10][10][20]);
void g(Type p[99][10][20]);
しかし、これらはすべて次のものとは異なります。
void g(Type p[][5][20]);
外側の配列次元以外の次元を調整すると、(少なくとも) 外側の配列の要素のサイズに影響するため、配列をナビゲートするためのポインター演算を変更する必要があることを意味します。
たとえばint a[n][m]
、型がint
長さの配列である配列ですm
。つまり、配列の長さはその型の一部です。また、すべての関数パラメーターについて、コンパイラーはその型を知る必要があります。
C++ には多次元配列のようなものはありません。それはそれのように見える単なる構文です。Inint a[4]
とint b[5]
a と b は異なる型です。
静的割り当てを参照すると、これは簡単です。メモリのブロックが連続しているため、メモリ セルが次々に配置され、コンパイラは次のセルがメモリ内のどこにあるかを認識します。
メモリ内の一次元配列は次のようになります。
http://cplusplus.com/doc/tutorial/arrays/arrays3.gif
メモリ内の 2 次元配列は次のようになります。