static char *name[] = {
"Illegal month",
"January", "February", "March", "April",
"May", "June", "July", "August", "September",
"October", "November", "December"
};
の場合、nameが指すアドレスには、13個のcharのポインタが並んでいます。
nameと名前の付いたメモリ。13個のポインタが並んでる
0個目のポインタは、"Illegal month"へのアドレスが書いてある
1個目のポインタは、"January"へのアドレスが書いてある
2個目のポインタは、"February"へのアドレスが書いてある
以下略。
この時、実際の文字列は「固定の文字列が存在している、リードオンリーなどこかの領域」に存在します。
そして「13個のcharのポインタ」が静的領域にあろうが、動的領域にあろうが、そんな事はどうでも良くて「固定の文字列が存在している、リードオンリーなどこかの領域は不変」です。
つまり、文字列そのものは、nameにstaticを付けても付けなくても、消えて無くなったりはしません。
return文で返されるポインタは「固定の文字列が存在している、リードオンリーなどこかの領域」を指していますから、関数から戻った後でも、ポインタは有効です。
-----
static char name[13][10] = {
"NG",
"1st", "2nd", "3rd", "4th",
"5th", "6th", "7th", "8th", "9th",
"10th", "11th", "12th"
};
の場合、nameが指すアドレスには10バイトのcharが13個並んでいます。
そして、0~2バイト目が'N' 'G' '\0'に、
10~13バイト目が'1' 's' 't' '\0'に、
20~23バイト目が'2' 'n' 'd' '\0'に、順次、初期化されます。
初期化される場所は「static変数用に用意された、静的なメモリのどこか」です。
staticで宣言されているので、nameは「static変数用に用意された、静的なメモリのどこか」にあり、nameの中身は、関数から抜けても消えたりしません。return文で返されるポインタは「static変数用に用意された、静的なメモリのどこか」を指していますから、関数から戻った後でも、ポインタは有効です。
-----
char name[13][10] = {
"NG",
"1st", "2nd", "3rd", "4th",
"5th", "6th", "7th", "8th", "9th",
"10th", "11th", "12th"
};
の場合、nameが指すアドレスには10バイトのcharが13個並んでいます。
そして、0~2バイト目が'N' 'G' '\0'に、
10~13バイト目が'1' 's' 't' '\0'に、
20~23バイト目が'2' 'n' 'd' '\0'に、順次、初期化されます。
初期化される場所は「auto変数用に用意された、宣言した関数内でだけ有効な、動的なメモリのどこか」です。
autoで宣言されているので、nameは「auto変数用に用意された、宣言した関数内でだけ有効な、動的なメモリのどこか」にあり、nameの中身は、関数から抜けた瞬間に解放され、消えて無くなります。return文で返されるポインタは「auto変数用に用意された、宣言した関数内でだけ有効な、動的なメモリのどこか」を指していますから、関数から戻った瞬間、ポインタは無効になります。ポインタが指すメモリには、すでにname配列は存在しません。
お礼
詳しく説明していただいて、ありがとうございました。やっとポインタの意味が分かった気がします。