127

C ++の配列とベクトルの違いは何ですか?違いの例としては、ライブラリ、シンボリズム、能力などがあります。

配列

配列には、特定のタイプの特定の数の要素が含まれています。プログラムのコンパイル時にコンパイラーが必要なスペースを予約できるようにするには、配列が定義されたときに配列に含まれる要素のタイプと数を指定する必要があります。コンパイラーは、プログラムのコンパイル時にこの値を判別できる必要があります。配列を定義したら、配列の識別子とインデックスを使用して、配列の特定の要素にアクセスします。[...]配列はゼロインデックスです。つまり、最初の要素はインデックス0にあります。このインデックススキームは、C ++でのポインタと配列の密接な関係と、言語がポインタ演算用に定義するルールを示しています。

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

ベクター

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

—C++クックブック

4

3 に答える 3

162

配列:

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

std::vector

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

また、配列の「最新の代替手段」も検討してください- std::array; との違いについては別の回答ですでに説明しましたが、ぜひご覧ください。std::vectorstd::array

于 2013-02-26T00:55:17.393 に答える
29

配列はC++の非常に低レベルの構造であり、「ロープを学ぶ」ときはできるだけ配列から離れるようにする必要があります。BjarneStroustrupでさえこれを推奨しています(彼はC ++の設計者です)。

ベクトルは配列と非常に近いパフォーマンスになりますが、非常に多くの便利さと安全機能を備えています。生の配列を処理するAPIとインターフェイスするとき、または独自のコレクションを構築するときに、おそらく配列の使用を開始します。

于 2013-02-26T00:28:09.940 に答える
14

それらの参照はほとんどあなたの質問に答えました。簡単に言えば、ベクトルの長さは動的ですが、配列のサイズは固定されています。配列を使用する場合は、宣言時にそのサイズを指定します。

int myArray[100];
myArray[0]=1;
myArray[1]=2;
myArray[2]=3;

ベクトルの場合は、それを宣言して要素を追加するだけです

vector<int> myVector;
myVector.push_back(1);
myVector.push_back(2);
myVector.push_back(3);
...

必要な要素の数がわからない場合があるため、このような状況ではベクトルが理想的です。

于 2013-02-26T00:21:53.377 に答える