投稿したコードはコンパイルされません。本から正確にコピーしたと確信していますか?
明らかな不足しているコンマを追加すると、最終的には次のようになります
char* words[1][40] =
{
"Goat"
"A herbivore",
"Dog"
"An omnivore",
"Fox"
"A carnivore",
"Bear"
"An omnivore",
"",
"",
NULL,
// this last line repeated 30 times...
};
それが意図されたものであるかどうかも疑わしい。(結果として、2 個だけでなく 30 個の null で終了するリストが生成されます。)
意味されていたのは、もなしだったと思い*
ます:
char words[][2][40] =
{
"Goat", "A herbivore",
"Dog", "An omnivore",
"Fox", "A carnivore",
"Bear", "An omnivore",
"", ""
};
これにより、 の配列 [40] の配列 [10] が生成されchar
ます。もちろん、これを明確に示す方がはるかに良いでしょう:
char words[][2][40] =
{
{ "Goat", "A herbivore" },
{ "Dog" , "An omnivore" },
{ "Fox" , "A carnivore" },
{ "Bear", "An omnivore" },
{ "" , "" },
};
「null」が何を意味するかについては、まだ問題があります。null ポインターの場合、ポインターがないため、このバージョンには存在しません (存在することもできません)。ヌル文字 ( '\0'
) の場合、文字列ごとに 1 つずつ、合計 10 あります。空の文字列の場合、作成者は非常に珍しく紛らわしい用語を使用しています。彼が空の文字列を意味する場合、彼は空の文字列と言うべきです。
必要なものは 2 つあります。その意図は、番兵を使用することだと思います。これを (C または C++ で) 記述する通常の方法は、
ポインターを使用して、次のように記述します。
char const* const words[][2] =
{
{ "Goat", "A herbivore" },
{ "Dog" , "An omnivore" },
{ "Fox" , "A carnivore" },
{ "Bear", "An omnivore" },
{ NULL , NULL }
};
この場合、おそらく 2 つの null を使用しますが、配列を初期化する最後の行は{}
、{ NULL }
、または{ NULL, NULL
}
;にすることができます。それらはすべて、コンパイラにとって同じ結果になります。
非ポインター バージョンでも、1 つの空の文字列で十分です。コンパイラは、すべての追加値にも空の文字列を入力します。
最後に、ヌル ポインターまたは空の文字列が必要な理由について説明します。C では、これらはセンチメンタルとして頻繁に使用されていました。それらに遭遇するまでループします。
for ( char const* const (*p)[2] = words; (*p)[0] != NULL; ++ p ) {
std::cout << (*p)[0] << " - " << (*p)[1] << std::endl;
}
C++ では、センティナルを使用することはほとんどありません。次のように記述できるからです。
for ( char const* const (*p)[2] = begin( words );
p != end( words );
++ p ) {
std::cout << (*p)[0] << " - " << (*p)[1] << std::endl;
}
C++11 では、それはstd::begin
andstd::end
になりますが、もちろん、C++11 より前は、誰もが個人用ツールキットにそれらを実装していました。C++11 では、以下も使用できますauto
。
for ( auto p = begin( words ); p != end( words ); ++ p ) {
std::cout << (*p)[0] << " - " << (*p)[1] << std::endl;
}
ただし、これが私たちに多くの利益をもたらすかどうかはわかりません。使用するときは、複雑な型を認識する必要があります。(auto
イテレータのように、基本的に使用するのは簡単であるが、綴りが難しい型がある場合は、多くのことを購入します。)
最後に、もちろん、C でも C++ でも、このために 2 次元配列を使用する人はいません。構造体を定義します:
struct Mapping
{
char const* animalName;
char const* eatingType;
};
Mapping const map[] =
{
{ "Goat", "A herbivore" },
{ "Dog" , "An omnivore" },
{ "Fox" , "A carnivore" },
{ "Bear", "An omnivore" },
{ NULL , NULL }
};
for ( Mapping const* p = map; p->animalName != NULL; ++ p ) {
// ...
}
(もちろん、センティナルの代わりに、C++ を使用して。begin
)end
ところで、この本をひどく誤って引用していない限り、捨ててください。著者は明らかに C も C++ も知りません。