2013-10-23 25 views
5

これらの宣言の違いは?cの文字列配列宣言

char **strings = {"abc", "bca", "rat", "tar", "far"}; 
char *strings[] = {"abc", "bca", "rat", "tar", "far"}; 
char strings[][] = {"abc", "bca", "rat", "tar", "far"}; 

のみ(2)有効な宣言です。これらのタイプの違いは何ですか?なぜ(1)と(3)は有効ではありませんか?

+3

で構成されなければなりませんか? –

+0

コンパイルして印刷しようとすると、2)しか動作しませんでした。 –

+0

それはあなたがどのように定義するかによって異なります。 「有効な宣言」として、それらはすべて有効です。 2 dim-arrの場合、有効なのは2つだけです。 –

答えて

11

char **stringscharへのポインタへのポインタです。これは有効な型ですが、配列初期化子で初期化することはできません。

char *strings[]は、charへのポインタの配列であり、その初期化は有効です。

char strings[][]は2次元配列を作成しようとしていますが、最も外側のものを除くすべての次元のサイズを指定する必要があるので間違いです(最も外側のサイズはイニシャライザから推測できます)。これは有効です:

char strings[][4] = {"abc", "bca", "rat", "tar", "far"}; 
1

1)char ** stringsは、ポインタへのポインタの宣言であり、文字列の配列ではなく数字の属性が必要です。

2)[]の内部サイズを定義してみてください:文字列* [5] = {....

3)再度、[X] [Y]、配列のサイズを定義するxは=要素数とy =最大要素の文字数

2

C99は複合リテラルをサポートしているため、配列初期化子を割り当てることができます。だから、ケース1は、とも結構です:型名がオブジェクト型または配列を指定しなければなら

char **strings = (char *[]) {"abc", "bca", "rat", "tar", "far"}; 

C99ドラフト、6.5.2.5、化合物リテラル

制約 サイズは不明ですが、可変長配列型ではありません。

2イニシャライザは、 リテラルで指定された名前のないオブジェクト全体に含まれる ではないオブジェクトに値を提供しようとしません。

3複合リテラルが関数本体の外側で発生した場合、 初期化子リストは、唯一の2が有効であることを言った定数式