全て、
これはしばらくの間私を悩ませてきました。C\C++ (Java と .NET も同様だと思います) では、多次元配列で行インデックスを指定する必要はありません。したがって、たとえば、int の配列を次のように宣言できます。
int 配列[][100];
一般に、静的配列はスタック上の連続したメモリとして表されると思います。では、列優先の表現を使用すると、次元の 1 つが欠落している上記のケースで、コンパイラーはどのようにして割り当てるメモリ量を知るのでしょうか?
全て、
これはしばらくの間私を悩ませてきました。C\C++ (Java と .NET も同様だと思います) では、多次元配列で行インデックスを指定する必要はありません。したがって、たとえば、int の配列を次のように宣言できます。
int 配列[][100];
一般に、静的配列はスタック上の連続したメモリとして表されると思います。では、列優先の表現を使用すると、次元の 1 つが欠落している上記のケースで、コンパイラーはどのようにして割り当てるメモリ量を知るのでしょうか?
C++ 言語では、ただ行うことはできません
int Array[][100]; /* ERROR: incomplete type */
これは不完全な型のオブジェクトの定義であり、C++ では明らかに違法であるためです。それを非定義宣言で使用できます
extern int Array[][100];
(またはクラスの静的メンバーとして)、ただし、同じ配列オブジェクトの実際の定義になると、両方のサイズを明示的に指定する (または明示的な初期化子から派生させる) 必要があります。
C では、C では仮の定義などを記述できることを除いて、状況はそれほど変わりません。
int Array[][100];
ただし、この点に関する暫定的な定義は、非定義宣言と非常に似ているため、許可されています。最終的には、同じ翻訳単位で明示的に指定されたサイズで同じオブジェクトを定義する必要があります (一部のコンパイラは、非標準拡張としてそれを必要としません)。暫定的な定義でそのようなことを試みると、エラーが発生します
static int Array[][100]; /* ERROR: incomplete type */
したがって、考えてみれば、暫定的な定義を除けば、C と C++ の状況は大差ありません。これらの言語で不完全な型のオブジェクトを定義することは違法であり、サイズが指定されていない配列は不完全な型です。
Java と .NET では、「スタック」について考えないでください。オブジェクトはヒープ上に存在します。C では、これは単なる宣言です。実際にメモリを予約するのは定義だけです。したがって、それは受け入れられる定義ではありません-ファイル内の唯一の行として配置するとa.c:
$ gcc -c a.c
a.c:1: warning: array ‘Array’ assumed to have one element
int Array[1][100];そのため、gcc は、実行していることを警告するので、それをあたかも であるかのように扱っています。
割り当てるメモリの量はわかりません。彼が知っているのarray[]は、配列がポインタ (のようなint *array) であることです。array[][100](私が間違っていたら誰か訂正してください) は と同じarray[100]です。