@paddyによる回答は次のとおりです。
const char * str[5] = {
"That means today is Monday! \n",
"That means today is Tuesday! \n",
"That means today is Wednesday! \n",
"That means today is Thursday! \n",
"That means today is Friday! \n"
};
土曜日と日曜日を追加するとどうなりますか? 5
を に変更する必要があり7
ます。良いニュース: 変更を忘れると、C コンパイラは、文字列の数が配列の宣言されたサイズと異なることに気付き、エラーが発生します。
しかし、うーん。では、なぜ配列の長さを指定する必要があるのでしょうか? Cコンパイラは、どれくらいの長さであるべきかを判断できませんか?
実際、そうです。数値を省略するだけで、C コンパイラが配列内の要素の数を数え、配列を正確にそのサイズにします。
しかし、文字列を印刷するとき、文字列の数をどのように知るのでしょうか? この問題を解決するには、2 つの一般的な方法があります。
1 つは、通常「センチネル」値と呼ばれる特別なマーカーを配列の末尾に配置することです。ここでの良い選択はNULL
.
それでは、例にこれらの変更を加えてみましょう: コンパイラにカウントさせ、最後にセンチネルを追加します。
@paddyによる回答は次のとおりです。
char const *str[] = {
"That means today is Monday! \n",
"That means today is Tuesday! \n",
"That means today is Wednesday! \n",
"That means today is Thursday! \n",
"That means today is Friday! \n",
NULL
};
これで、センチネル値をチェックするループを書き直すことができます。
for (i = 0; str[i]; ++i)
fputs(str[i], fp_out);
str[i]
これは、 の値が falseになるまでループして出力します。NULL
ポインターは false と評価され、ループが停止します。
リストに含まれているものの数を知るもう 1 つの方法は、もう少しトリッキーです。この機能を使用しsizeof()
て配列のサイズを調べることができますが、このサイズはsizeof(char)
(ほとんどのプラットフォームではバイトを意味します) 単位で与えられます。ただし、合計サイズを 1 つの要素のサイズで割ることはできます。これはうまくいきます:
static int const str_count = sizeof(str) / sizeof(char const *);
しかし、型を変更するとどうなるstr
でしょうか? 次に、で変更することを忘れないでくださいsizeof(char const *)
。str
より良いのは、要素のサイズを把握するためにそれ自体を使用できることです。そのようです:
static int const str_count = sizeof(str) / sizeof(str[0]);
これをマクロにまとめることもできます:
#define ARRAY_LEN(a) (sizeof(a) / sizeof((a)[0]))
static int const str_count = ARRAY_LEN(str);
ループは次のとおりです。
for (i = 0; i < str_count; ++i)
fputs(str[i], fp_out);
または、次のマクロを使用します。
for (i = 0; i < ARRAY_LEN(str); ++i)
fputs(str[i], fp_out);