文字列のポインタとか配列とか文字列リテラルはややこしい

最近いろんな人が言及していたことの延長ですが,文字列の配列の初期化でつまづいたので自分なりにまとめる.

まず,文字列の初期化から

char *str1 = "foo";   /* (1) */
char sa1[] = "bar";   /* (2) */
char sa2[] = { 'b', 'a', 'r', '\0' };  /* (3) */


(1)はポインタ変数の文字列リテラルによる初期化
静的領域に4バイト確保されて,そこに 'f', 'o', 'o', '\0' っていう文字がそれぞれ入る.
さらにスタック領域にポインタ変数の領域として sizeof(char *) 分だけ確保されて,その初期値として静的領域に確保された4バイトの先頭アドレスが入る.


(2)と(3)はchar型による配列の初期化
スタック領域に配列としてsizeof(char) * 4バイト確保されて,そこにそれぞれ'b', 'a', 'r', '\0'が初期値として入る.

そして,文字列の配列の初期化

char *t[] = { "C", "C++", "Perl", "Python",
                    "Ruby", "Java", "Javascript" };

これは,char型のポインタを要素とする配列の,文字列リテラルによる初期化
静的領域にそれぞれ,"C", "C++", "Perl", "Python", "Ruby", "Java", "Javascript" が文字列リテラルとして確保される.
スタック領域に配列としてsizeof (char *) * 7 バイト確保されて,配列の各要素が,静的領域に確保された文字列リテラルの先頭アドレスで初期化される.


ちなみに,

char t[][11] = { "C", "C++", "Perl", "Python",
                        "Ruby", "Java", "Javascript" };

こうすることで,二次元配列としてすべてスタック領域に確保される


自分の理解はこんな感じ
つっこみとかあればぜひお願いしますm(__)m