多次元配列を作成するときchar a[10][10]
、私の本によるとchar a[][10]
、配列を関数に渡すのと同様のパラメーターを使用する必要があると書かれています。
なぜ長さを指定しなければならないのですか?一緒にいるためにダブルポインターを渡しているだけではなく、そのダブルポインターは既に割り当てられたメモリを指していませんか? では、なぜパラメーターを にできないのchar **a
でしょうか? 2番目の10を指定して、新しいメモリを再割り当てしていますか?
多次元配列を作成するときchar a[10][10]
、私の本によるとchar a[][10]
、配列を関数に渡すのと同様のパラメーターを使用する必要があると書かれています。
なぜ長さを指定しなければならないのですか?一緒にいるためにダブルポインターを渡しているだけではなく、そのダブルポインターは既に割り当てられたメモリを指していませんか? では、なぜパラメーターを にできないのchar **a
でしょうか? 2番目の10を指定して、新しいメモリを再割り当てしていますか?
ポインタは配列ではありません
逆参照char **
されるオブジェクトは、タイプ のオブジェクトですchar *
。
逆参照char (*)[10]
されるオブジェクトは、タイプ のオブジェクトですchar [10]
。
配列はポインターではありません
この問題については c-faq エントリを参照してください。
あなたが持っていると仮定します
char **pp;
char (*pa)[10];
そして、議論のために、どちらも同じ場所 (0x420000) を指しています。
pp == 0x420000; /* true */
(pp + 1) == 0x420000 + sizeof(char*); /* true */
pa == 0x420000; /* true */
(pa + 1) == 0x420000 + sizeof(char[10]); /* true */
(pp + 1) != (pa + 1) /* true (very very likely true) */
これが、引数を type にすることができない理由char**
です。またchar**
、 とchar (*)[10]
は互換性のある型ではないため、引数の型 (減衰配列) はパラメーター (関数プロトタイプの型) と一致する必要があります。
C 言語標準、ドラフトn1256 :
6.3.2.1 左辺値、配列、および関数指定子
... 3演算子または単項演算子
のオペランドである場合、または配列の初期化に使用される文字列リテラルである場合を除き、 「型の配列」型を持つ式' は、配列オブジェクトの最初の要素を指し、左辺値ではない ''型へのポインター'' 型の式に変換されます。配列オブジェクトにレジスタ ストレージ クラスがある場合、動作は未定義です。sizeof
&
の宣言が与えられた場合
char a[10][10];
配列式の型a
は「10要素配列の10要素配列char
」です。上記の規則により、「10 要素配列へのポインタchar
」、またはchar (*)[10]
.
T a[N]
関数パラメーター宣言のコンテキストでは、とは;T a[]
と同じであることを思い出してください。T *a
したがって、T a[][10]
と同じですT (*a)[10]
。