最近、私は多くの例を見つけました。それらのほとんどはC++ 98に関するもので、とにかく単純な配列とループを作成しました( codepad ):
#include <iostream>
using namespace std;
int main ()
{
string texts[] = {"Apple", "Banana", "Orange"};
for( unsigned int a = 0; a < sizeof(texts); a = a + 1 )
{
cout << "value of a: " << texts[a] << endl;
}
return 0;
}
出力:
aの値:Apple aの値:Banana aの値:Orange Segmentation fault
最後のセグメンテーションフォールトを除き、正常に機能しています。
私の質問は、この配列/ループスルーは良い方法ですか?私はC++ 11を使用しているので、標準に適合し、より良い方法で実行できないことを確認したいですか?
C/C++ではsizeof
。オブジェクト全体のバイト数を常に与え、配列は1つのオブジェクトとして扱われます。注:sizeof
は、配列の最初の要素または単一のオブジェクトへのポインターであり、指すオブジェクトではなくpointerのサイズを与えます。いずれにしても、sizeof
はnot配列内の要素数(その長さ)を提供します。長さを取得するには、各要素のサイズで除算する必要があります。例えば。、
for( unsigned int a = 0; a < sizeof(texts)/sizeof(texts[0]); a = a + 1 )
それをC++ 11の方法で行う場合、それを行う最良の方法はおそらく
for(const string &text : texts)
cout << "value of text: " << text << endl;
これにより、コンパイラは必要な反復回数を把握できます。
編集:他の人が指摘したように、C++ 11ではstd::array
がraw配列よりも優先されます。しかし、他の回答はいずれもsizeof
がそのまま失敗する理由を扱っていないため、これがより良い答えだと思います。
string texts[] = {"Apple", "Banana", "Orange"};
for( unsigned int a = 0; a < sizeof(texts); a = a + 1 )
{
cout << "value of a: " << texts[a] << endl;
}
いや。配列を反復処理するまったく間違った方法です。 sizeof(texts)
は配列内の要素の数と等しくありません!
最新のC++ 11の方法は次のとおりです。
std::array
を使用します。またはstd::vector
を使用します次に、反復時にrange-forを使用します。
#include <iostream>
#include <array>
int main() {
std::array<std::string, 3> texts = {"Apple", "Banana", "Orange"};
// ^ An array of 3 elements with the type std::string
for(const auto& text : texts) { // Range-for!
std::cout << text << std::endl;
}
}
std::array
はol 'C配列よりもどのように優れているのでしょうか?答えは、他の標準ライブラリコンテナの追加の安全性と機能があり、ほとんどがstd::vector
に似ているということです。さらに、答えは、ポインターに減衰して型情報を失うという癖がないため、元の配列型を失うと、その上でrange-forまたはstd::begin/end
を使用できなくなります。
sizeof
は、要素の数ではなく、もののサイズを示します。あなたがやっていることを行うためのより多くのC++ 11の方法は次のとおりです:
#include <array>
#include <string>
#include <iostream>
int main()
{
std::array<std::string, 3> texts { "Apple", "Banana", "Orange" };
for (auto& text : texts) {
std::cout << text << '\n';
}
return 0;
}
ideoneデモ: http://ideone.com/6xmSrn
配列に停止値を追加します。
#include <iostream>
using namespace std;
int main ()
{
string texts[] = {"Apple", "Banana", "Orange", ""};
for( unsigned int a = 0; texts[a].length(); a = a + 1 )
{
cout << "value of a: " << texts[a] << endl;
}
return 0;
}
処理したい要素の非常に短いリストがある場合は、C++ 11で導入された std :: initializer_list をautoと一緒に使用できます。
#include <iostream>
int main(int, char*[])
{
for(const auto& ext : { ".slice", ".socket", ".service", ".target" })
std::cout << "Handling *" << ext << " systemd files" << std::endl;
return 0;
}
システム上のsizeof(texts)
は96と評価されました:配列とその文字列インスタンスに必要なバイト数。
他の場所で述べたように、sizeof(texts)/sizeof(texts[0])
は期待した3の値を与えます。