まず、 「配列はポインタではない」ことを理解してください。
int p[] = (int []) {1,2,3,4,5,6};
上記の場合p
は整数の配列です。要素{1,2,3,4,5,6}
をにコピーしますp
。ここでは型キャストは必要ありません。整数配列であるrvalue
と型の両方が一致するため、エラーは発生しません。lvalue
int *p[] = (int *[]) {{1,2,3},{4,5,6}};
「最初のものでエラーが発生した理由がわかりません。..」
上記の場合、p
整数ポインターの配列。ただし、これ{{1,2,3},{4,5,6}}
は2次元配列(つまり、[] [])であり、ポインターの配列に型キャストすることはできません。-として初期化する必要があります
int p[][3] = { {1,2,3},{4,5,6} };
// ^^ First index of array is optional because with each column having 3 elements
// it is obvious that array has two rows which compiler can figure out.
しかし、なぜこのステートメントはコンパイルされたのですか?
char *p[] = {"one", "two"...};
文字列リテラルは整数リテラルとは異なります。この場合も、p
は文字ポインタの配列です。実際に言うと"one"
、配列にコピーするか、読み取り専用と見なしてその場所を指すことができます。
char cpy[] = "one" ;
cpy[0] = 't' ; // Not a problem
char *readOnly = "one" ;
readOnly[0] = 't' ; // Error because of copy of it is not made but pointing
// to a read only location.
文字列リテラルでは、上記のいずれの場合も可能です。だから、それがステートメントがコンパイルされた理由です。だが -
char *p[] = {"one", "two"...}; // All the string literals are stored in
// read only locations and at each of the array index
// stores the starting index of each string literal.
コンパイラにとっての配列の大きさは言いたくありません。
を使用してメモリを動的に割り当てることmalloc
が解決策です。
それが役に立てば幸い !