1. ホーム
  2. c++

[解決済み] 配列とベクトル。入門編 似たようなもの、違うようなもの [終了しました]

2022-07-28 01:47:46

質問

C++の配列とベクトルの違いは何ですか?違いの例としては、含まれるライブラリ、シンボル、能力などが考えられます。

配列

<ブロッククオート

配列は特定の型の要素を特定の数だけ含む。プログラムのコンパイル時にコンパイラが必要な領域を確保できるように、配列の定義時にその型と含まれる要素の数を指定する必要があります。コンパイラは、プログラムがコンパイルされるときに、この値を決定できる必要があります。配列が定義されると、配列の識別子とインデックスを使って配列の特定の要素にアクセスします。[中略)配列はゼロインデックス、つまり最初の要素がインデックス0になります。このインデックス方式は、C++におけるポインタと配列の密接な関係と、この言語がポインタ演算に対して定義しているルールを示しています。

- C++ポケットリファレンス

ベクター

ベクターは動的な大きさのオブジェクトのシーケンスで、配列スタイルの operator[] ランダムアクセスを提供します。メンバー関数 push_back はコピーコンストラクタを介してその引数をコピーし、そのコピーをベクターの最後の項目として追加し、そのサイズを1つ増やします。 pop_back はその逆で、最後の要素を削除します。ベクトルの最後から項目を挿入したり削除したりするには償却された定数時間がかかり、それ以外の場所からの挿入や削除には線形時間がかかります。これがベクトルの基本です。他にもいろいろあります。ほとんどの場合、C言語の配列よりもベクトルを最初に選択すべきです。まず第一に、ベクトルは動的にサイズを変更することができ、必要に応じて大きくすることができます。C言語の配列のように、最適な静的サイズを見つけるためにいろいろと調べる必要はありません。ベクターは必要に応じて大きくなり、必要であれば手動でサイズを変更することができます。第二に、ベクターは at メンバ関数で境界チェックを行うことができます(ただし operator[] ) を使用することで、存在しないインデックスを参照した場合に、単にプログラムがクラッシュしたり、最悪の場合、破損したデータで実行を継続するのではなく、何かをすることができるようになります。

- C++クックブック

どのように解決するのですか?

の配列になります。

  • は組み込みの言語構成です。
  • は C89 からほとんど変更されていません。
  • 連続した、インデックス可能な一連の要素を提供します。 を提供します。
  • は固定サイズです。C++では配列のサイズを変更することはできません(ただし、PODの配列で malloc );
  • のサイズは、動的に割り当てられない限り、コンパイル時の定数でなければなりません。
  • 宣言したスコープに依存したストレージスペースを取ります。
  • 動的に割り当てられた場合、明示的に割り当てを解除する必要があります。
  • が動的に割り当てられている場合、ポインタを得るだけで、そのサイズを決定することはできません。それ以外の場合は sizeof を使うことができます (そのため、一般的な慣用句である sizeof(arr)/sizeof(*arr) しかし、ポインター上で不注意に使用された場合、それは無言で失敗します)。
  • は、ほとんどの状況で自動的にポインタに減衰します。特に、これは関数にそれらを渡すときに起こり、通常、それらのサイズのための別のパラメータを渡す必要があります。
  • は関数から返すことができません; (それがstd::arrayでない限り)
  • は直接コピー/割り当てができません。
  • オブジェクトの動的配列は、すべての要素が最初に構築されなければならないので、デフォルトのコンストラクタが必要です。

std::vector :

  • はテンプレートクラスです。
  • はC++のみのコンストラクトです。
  • として実装されています。 動的配列 ;
  • は動的に大きくなったり小さくなったりします。
  • 自動的にメモリを管理し、破棄時に解放される。
  • は関数に渡したり、関数から返したりすることができる(値によって)。
  • はコピー/割り当てが可能です(これは、格納されているすべての要素のディープコピーを実行します)。
  • はポインタに減衰しませんが、あなたは ができます。 はそのデータへのポインタを明示的に取得します ( &vec[0] は期待通りに動作することが保証されています)。
  • は常に内部の動的配列と一緒に サイズ (現在いくつの要素が格納されているか) と 容量 (何個の要素 を格納できる を格納できる数)。
  • 内部動的配列はオブジェクト自身の内部で割り当てられるのではなく (これは単にいくつかの "bookkeeping" フィールドを含む)、 関連するテンプレートパラメータで指定されたアロケータによって動的に割り当てられます。 デフォルトのものは、実際のオブジェクトがどこで割り当てられるかに関係なく、 フリーストア (いわゆるヒープ) からメモリを取得します。
  • このため、小さく短命なローカル配列の場合、通常の配列よりも効率が悪くなることがあります。
  • は、再割り当ての際に、オブジェクトが コピーされた (C++11では移動)されます。
  • は、格納されるオブジェクトのデフォルト コンストラクタを必要としません。
  • はいわゆる STL の残りの部分とよりよく統合されています (これは begin() / end() メソッド、通常のSTL typedef s, ...)

また、配列の代替となるquot;modern alternative"を考えてみましょう。 std::array ですでに説明しました。 別の答え との違いは std::vectorstd::array のような、曖昧な表現がありますが、一度ご覧になってみてください。