C ++ベクトルの使用方法

How Use C Vector



序章

配列は、連続するメモリ位置にある一連の同じオブジェクトタイプです。配列は鉱石の長さを減らすことはできません。ベクトルは配列に似ていますが、その長さは増減できます。したがって、ベクトルには配列よりもはるかに多くの操作があります。

C ++には多くのライブラリがあり、そのすべてがC ++標準ライブラリを形成しています。これらのライブラリの1つは、コンテナライブラリです。コンテナはオブジェクトのコレクションであり、コレクションに対して特定の操作を実行できます。 C ++コンテナーは、シーケンスコンテナーと連想コンテナーの2つのセットにグループ化できます。シーケンスコンテナは、vector、array(前に説明したのと同じ配列ではありません)、deque、forward_list、およびlistです。これらは異なるコレクション(配列のようなデータ構造)であり、それぞれが異なるトレードオフを提供します。







プログラマーは、ベクトル、配列、両端キュー、forward_list、またはリストのどれを使用するかを決定する方法を知っている必要があります。プログラマーが通常の配列に関連付けられている操作よりも多くの操作を必要とする構造を必要とする場合は、通常の配列を使用しないでください。



タスクがシーケンスの途中で頻繁な挿入と削除を伴う場合は、listまたはforward_listを使用する必要があります。タスクがシーケンスの最初または最後に頻繁な挿入と削除を伴う場合は、両端キューを使用する必要があります。これらの種類の操作が必要ない場合は、ベクトルを使用する必要があります。



この記事では、C ++ベクトルの使用方法を説明します。この記事を理解するには、C ++ポインター、参照、および配列に関する知識が必要です。





クラスとオブジェクト

クラスは、一緒に機能する変数と関数のセットであり、変数には値が割り当てられていません。変数に値が割り当てられると、クラスがオブジェクトになります。同じクラスに異なる値を指定すると、オブジェクトも異なります。つまり、異なるオブジェクトが同じクラスである可能性がありますが、値は異なります。クラスからオブジェクトを作成することは、オブジェクトのインスタンス化とも呼ばれます。

ベクトルという用語は、クラスを表します。ベクトルから作成されたオブジェクトには、プログラマーが選択した名前が付いています。



クラスからオブジェクトをインスタンス化するには、クラスに属する関数が必要です。 C ++では、その関数の名前はクラスの名前と同じです。クラスから作成(インスタンス化)されたさまざまなオブジェクトには、プログラマーによってそれぞれに異なる名前が付けられています。

クラスからオブジェクトを作成するということは、オブジェクトを作成することを意味します。また、オブジェクトをインスタンス化することも意味します。

ベクトルクラス

ベクトルクラスはすでに定義されており、ライブラリにあります。ベクトルクラスを使用するには、プログラマーは次の前処理ディレクティブを使用してファイルにベクトルヘッダーを含める必要があります。

#含む

ヘッダーが含まれると、すべてのベクター機能(データメンバーとメンバー関数)にアクセスできるようになります。 countオブジェクトを使用して端末(コンソール)にデータを出力するには、オブジェクトヘッダーも含める必要があります。ベクトルを使用してプログラムを作成するには、少なくとも次のヘッダーを含める必要があります。

#含む
#含む

ベクトルのインスタンス化

intfoo[10];

上記は、fooという名前と要素数10の配列の宣言です。これは整数の配列です。ベクトルの宣言も同様です。ベクトルの場合、ベクトルの長さは増減する可能性があるため、要素の数はオプションです。

プログラムのこの時点で、ベクタークラスはライブラリですでに定義されており、ヘッダーが含まれています。ベクトルは次のようにインスタンス化できます。

時間:::ベクター <int>>vtr((8)。;

ここで、ベクトルは特別なコンストラクター関数のものです。ベクトルが保持するデータのタイプは、山括弧内のintです。 vtrという用語は、プログラマーがベクトル用に選択した名前です。最後に、括弧内の8は、ベクトルが持つ整数の暫定的な数です。

stdという用語は、標準の名前空間を表します。このコンテキストでは、この用語の後に二重コロンを付ける必要があります。誰でも独自のベクトルクラスライブラリを作成して使用できます。ただし、C ++には、ベクターを含む標準名の標準ライブラリがすでにあります。標準名を使用するには、標準名の前にstd ::を付ける必要があります。 std ::と入力しないようにするために、プログラムで標準名を指定するたびに、プログラムファイルを次のように開始できます。

#含む
#含む
名前空間stdを使用する;

関数のオーバーロード

2つ以上の異なる関数シグネチャが同じ名前を持っている場合、その名前はオーバーロードされていると言われます。 1つの関数が呼び出されると、引数の数とタイプによって、実行される関数が決まります。

ベクトルの構築

ベクトルを構築するということは、ベクトルオブジェクトをインスタンス化(作成)することを意味します。コンストラクター関数は次のようにオーバーロードされます。

ベクトル名

これにより、長さがゼロでタイプTのベクトルが作成されます。次のステートメントは、vtrという名前のタイプfloatの長さがゼロのベクトルを作成します。

ベクター<浮く>>vtr;

ベクトル名(n)

これにより、タイプTのn個の要素を持つベクトルが作成されます。4つのfloat要素を持つこのベクトルのステートメントは次のとおりです。

ベクター<浮く>>vtr((4)。;

ベクトル名(n、t)

これにより、値tに初期化されたn個の要素のベクトルが作成されます。次のステートメントは、5つの要素のベクトルを作成します。各要素の値は3.4です。

ベクター<浮く>>vtr((5 3.43.4)。;

初期化による構築

次の2つの方法のいずれかで、ベクトルの作成(作成)と初期化を同時に行うことができます。

ベクター<浮く>>vtr= {{1.1 2.2 3.3 4.4};

または

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};

オブジェクト名の直後には括弧がないことに注意してください。オブジェクト名の直後に使用される括弧には、次のように初期化子リストが含まれている必要があります。

ベクター<浮く>>vtr(({{1.1 2.2 3.3 4.4})。;

ベクトルは、後でイニシャライザリストを使用して作成および初期化できます。この場合、括弧は使用されません。

ベクター<浮く>>vtr;
vtr= {{1.1 2.2 3.3 4.4};

ベクトルV2(V1)

これはコピーコンストラクタです。ベクトルV1のコピーとしてベクトルV2を作成します。次のコードはこれを示しています。

ベクター<浮く>>vtr1((5 3.43.4)。;
ベクター<浮く>>vtr2((vtr1)。;

構築中にベクトルを割り当てる

構築中に、次のように、別のベクトルが割り当てられている間に空のベクトルを作成できます。

ベクター<浮く>>vtr1{{1.1 2.2 3.3 4.4};
ベクター<浮く>>vtr2=vtr1;

2番目のステートメントは次と同等です。

ベクター<浮く>>vtr2= {{1.1 2.2 3.3 4.4};

const Vector

constベクトルは、要素を変更できないベクトルです。このベクトルの値は読み取り専用です。作成すると、ベクトルは次のように表示されます。

constベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};

このベクトルタイプでは、要素を追加または削除することはできません。また、値を変更することはできません。

イテレータを使用した構築

テンプレートは、データ型の一般的な表現を提供します。イテレータは、コンテナの値をスキャンする一般的な表現を提供します。イテレータを使用してベクトルを作成するための構文は次のとおりです。

レンプレート<クラスInputIterator>>
ベクター((最初にInputIteratorInputIterator最後constアロケータ =アロケータ(()。)。;

これにより、指定されたアロケータを使用して範囲[first、last)のベクトルが作成されます。これについては、この記事の後半で説明します。

ベクトルを破壊する

ベクトルを破棄するには、ベクターがスコープ外になるのを許可するだけで、破棄が自動的に処理されます。

ベクトル容量

size_typecapacity()const noexcept

再割り当てを必要とせずにベクトルが保持できる要素の総数は、容量メンバー関数によって返されます。このためのコードセグメントは次のとおりです。

ベクター<浮く>>vtr((4)。;
int1つに=vtr。容量(()。;
費用<<1つに<< 'NS';

出力は4です。

リザーブ(n)

メモリスペースは常に自由に利用できるとは限りません。予備のスペースは事前に予約できます。次のコードセグメントについて考えてみます。

ベクター<浮く>>vtr((4)。;
vtr。予約((6)。;
費用<<vtr。容量(()。 << 'NS';

出力は6です。したがって、予約されている余分なスペースは6 – 4 = 2要素です。関数はvoidを返します。

size()const noexcept

これは、ベクトル内の要素の数を返します。次のコードは、この関数を示しています。

ベクター<浮く>>vtr((4)。;
浮くNS=vtr。サイズ(()。;
費用<<NS<< 'NS';

出力は4です。

シュリンク_to_fit()

reserved()関数を使用してベクトルに追加の容量を与えた後、元のサイズに合うようにベクトルのサイズを小さくすることができます。次のコードはこれを示しています。

ベクター<浮く>>vtr((4)。;
vtr。予約((6)。;
vtr。シュリンクトゥフィット(()。;
intNS=vtr。サイズ(()。;
費用<<NS<< 'NS';

出力は6ではなく4です。関数はvoidを返します。

サイズ変更(sz)、サイズ変更(sz、c)

これにより、ベクトルのサイズが変更されます。新しいサイズが古いサイズよりも小さい場合、最後の方の要素が消去されます。新しいサイズが長い場合は、最後にデフォルト値が追加されます。特定の値を追加するには、2つの引数を指定してresize()関数を使用します。次のコードセグメントは、これら2つの関数の使用法を示しています。

ベクター<浮く>>vtr1{{1.1 2.2 3.3 4.4};
vtr1。サイズ変更((2)。;
費用<< 'vtr1の新しいサイズ:' <<vtr1。サイズ(()。 << 'NS';
ベクター<浮く>>vtr2{{1.1 2.2};
vtr2。サイズ変更((4 8.8)。;
費用<< 'vtr2:'<<vtr2[0] <<''<<vtr2[1] <<'
'
<<vtr2[2] <<''<<vtr2[3] << 'NS';

出力は次のとおりです。

vtr1の新しいサイズ:2
vtr2:1.1 2.2 8.8 8.8

関数はvoidを返します。

empty()const noexcept

この関数は、ベクトルに要素がない場合はtrueの場合は1を返し、ベクトルが空の場合はfalseを返します。ベクトルにfloatなどの特定のタイプのデータ用の4つの場所があり、float値がない場合、そのベクトルは空ではありません。次のコードはこれを示しています。

ベクター<浮く>>vtr;
費用<<vtr。空の(()。 << 'NS';
ベクター<浮く>>vt((4)。;
費用<<となることによって空の(()。 << 'NS';

ベクター<浮く>>v((43.5)。;
費用<<v。空の(()。 << 'NS';

出力は次のとおりです。

1
0
0

ベクトル要素へのアクセス

ベクトルは、配列のようにサブスクリプト(インデックス)を付けることができます。インデックスのカウントはゼロから始まります。

vectorName [i]

演算vectorName [i]は、iの要素への参照を返しますNSベクトルのインデックス。次のコードは、上記のベクトルに対して3.3を出力します。

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
浮くfl=vtr[2];
費用<<fl<< 'NS';

vectorName [i] const

ベクトルが定数ベクトルの場合、vectorName [i]の代わりにvectorName [i] const演算が実行されます。この操作は、次のコードで使用されます。

constベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
浮くfl=vtr[2];
費用<<fl<< 'NS';

式は、iへの定数参照を返しますNSベクトルの要素。

添え字付きの値の割り当て

次のように、値を非定数ベクトルに割り当てることができます。

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
vtr[2] = 8.8;
費用<<vtr[2] << 'NS';

出力は8.8です。

vectorName.at(i)

vectorName.at(i)はvectorName [i]に似ていますが、vectorName.at(i)の方が信頼性が高くなります。次のコードは、このベクトルの使用方法を示しています。

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
浮くfl=vtr。((2)。;
費用<<fl<< 'NS';
(()。ベクトルメンバーです関数

vectorName.at(i)const

vectorName.at(i)constはvectorName [i] constに似ていますが、vectorName.at(i)constの方が信頼性が高くなります。ベクトルが定数ベクトルの場合、vectorName.at(i)の代わりにvectorName.at(i)constが実行されます。このベクトルは、次のコードで使用されます。

constベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
浮くfl=vtr。((2)。;
費用<<fl<< 'NS';
(()。 constベクトルメンバーです関数

at()関数を使用した値の割り当て

次のように、at()関数を使用して非定数ベクトルに値を割り当てることができます。

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
vtr。((2)。 = 8.8;
費用<<vtr[2] << 'NS';

出力は8.8です。

サブスクリプトの問題

サブスクリプト(インデックス作成)の問題は、インデックスが範囲外の場合、ゼロが返されるか、実行時にエラーが発行される可能性があることです。

フロント()

これにより、要素を削除せずに、ベクトルの最初の要素への参照が返されます。次のコードの出力は1.1です。

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
浮くfl=vtr。フロント(()。;
費用<<fl<< 'NS';

要素はベクトルから削除されません。

front()const

ベクトル構築の前にconstが付いている場合、front()の代わりに式front()constが実行されます。これは、次のコードで使用されます。

constベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
浮くfl=vtr。フロント(()。;
費用<<fl<< 'NS';

定数参照が返されます。要素はベクトルから削除されません。

戻る()

これにより、要素を削除せずに、ベクトルの最後の要素への参照が返されます。次のコードの出力は4.4です。

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
浮くfl=vtr。戻る(()。;
費用<<fl<< 'NS';

back()const

ベクトル構築の前にconstが付いている場合、式back()constがback()の代わりに実行されます。これは、次のコードで使用されます。

constベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
浮くfl=vtr。戻る(()。;
費用<<fl<< 'NS';

定数参照が返されます。要素はベクトルから削除されません。

ベクターデータアクセス

data()noexcept; data()const noexcept;

これらのいずれかは、[data()、data()+ size())が有効な範囲であるようなポインターを返します。

これについては、この記事の後半で詳しく説明します。

イテレータとベクトルを返す

イテレータはポインタに似ていますが、ポインタよりも多くの機能を備えています。

begin()noexcept

次のコードセグメントのように、ベクトルの最初の要素を指すイテレータを返します。

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
ベクター<浮く> ::イテレータiter=vtr。始める(()。;
費用<< *iter<< 'NS';

出力は1.1です。イテレータを受け取る宣言が宣言されていることに注意してください。イテレータは、ポインタが逆参照されるのと同じ方法で値を取得するために、戻り式で逆参照されます。

begin()const noexcept;

ベクトルの最初の要素を指すイテレータを返します。ベクトル構築の前にconstが付いている場合、式begin()constがbegin()の代わりに実行されます。この状態では、ベクトル内の対応する要素を変更することはできません。これは、次のコードで使用されます。

constベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
ベクター<浮く> ::const_iteratoriter=vtr。始める(()。;
費用<< *iter<< 'NS';

出力は1.1です。今回は、返されたイテレータを受け取るために、イテレータだけでなくconst_iteratorが使用されていることに注意してください。

end()noexcept

ベクトルの最後の要素のすぐ先を指すイテレータを返します。次のコードセグメントについて考えてみます。

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
ベクター<浮く> ::イテレータiter=vtr。終わり(()。;
費用<< *iter<< 'NS';

最後の要素以外に具体的な要素がないため、出力は0です。これは意味がありません。

end()const noexcept

ベクトルの最後の要素のすぐ先を指すイテレータを返します。ベクトル構築の前にconstが付いている場合、end()の代わりに式end()constが実行されます。次のコードセグメントについて考えてみます。

constベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
ベクター<浮く> ::const_iteratoriter=vtr。終わり(()。;
費用<< *iter<< 'NS';

出力は0です。今回は、返されたイテレーターを受け取るために、イテレーターだけでなくconst_iteratorが使用されていることに注意してください。

逆反復

末尾から最初の要素の直前まで反復するイテレータを持つことができます。

rbegin()noexcept

次のコードセグメントのように、ベクトルの最後の要素を指すイテレータを返します。

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
ベクター<浮く> ::reverse_iteratorライター=vtr。rbegin(()。;
費用<< *ライター<< 'NS';

出力は4.4です。

逆イテレータを受け取る宣言が宣言されていることに注意してください。イテレータは、ポインタが逆参照されるのと同じ方法で値を取得するために、戻り式で逆参照されます。

rbegin()const noexcept;

ベクトルの最後の要素を指すイテレータを返します。ベクトル構築の前にconstが付いている場合、rbegin()の代わりに式rbegin()constが実行されます。この状態では、ベクトル内の対応する要素を変更することはできません。この機能は、次のコードで使用されます。

constベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
ベクター<浮く> ::const_reverse_iteratorライター=vtr。rbegin(()。;
費用<< *ライター<< 'NS';

出力は4.4です。

今回は、reverse_iteratorだけでなく、const_reverse_iteratorを使用して、返されたイテレーターを受信して​​いることに注意してください。

レンダリング()noexcept

ベクトルの最初の要素の直前を指すイテレータを返します。次のコードセグメントについて考えてみます。

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
ベクター<浮く> ::reverse_iteratorライター=vtr。作る(()。;
費用<< *ライター<< 'NS';

出力は0ですが、最初の要素の直前に具体的な要素がないため、意味がありません。

render()const noexcept

ベクトルの最初の要素の直前を指すイテレータを返します。ベクトル構築の前にconstが付いている場合、式rend()constがrend()の代わりに実行されます。次のコードセグメントについて考えてみます。

constベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
ベクター<浮く> ::const_reverse_iteratorライター=vtr。作る(()。;
費用<< *ライター<< 'NS';

出力は0です。

今回は、reverse_iteratorだけでなく、const_reverse_iteratorを使用して、返されたイテレーターを受信して​​いることに注意してください。

ベクトル修飾子

ベクトルを変更する修飾子は、イテレーターを取得または返すことができます。

a.emplace(p、args)

std :: forward(args)…で構築されたタイプTのオブジェクトをpの前に挿入します。

詳細については、後で参照してください

insert(iteratorPosition、value)

ベクトルのイテレータ位置に値のコピーを挿入します。コピーが配置されたベクトル内のイテレータ(位置)を返します。次のコードは、値が配置されている場所を示しています。

ベクター<int>>vtr{{10 20 30 40};
ベクター<int> ::イテレータiter=vtr。始める(()。;
++iter;
++iter;
vtr。入れる((iter 25)。;
費用<<vtr[1] << '' <<vtr[2]<< '
'
<<vtr[3] << 'NS';

出力は次のとおりです:20 2530。

イテレータはポインタと同じように進められた(インクリメントされた)ことに注意してください。

次のコードが示すように、イニシャライザリストを挿入することもできます。

ベクター<int>>vtr{{10 20 30 40};
ベクター<int> ::イテレータiter=vtr。始める(()。;
++iter;
++iter;
vtr。入れる((iter {{25 28})。;

費用<<vtr[1] << '' <<vtr[2]<< '
'
<<vtr[3]<< '' <<vtr[4] << 'NS';

出力は次のとおりです。20252830。

消去(位置)

イテレータが指す位置にある要素を削除してから、イテレータの位置を返します。次のコードはこれを示しています。

ベクター<int>>vtr{{10 20 30 40};
ベクター<int> ::イテレータiter=vtr。始める(()。;
++iter;
++iter;
vtr。消去((iter)。;
費用<<vtr[0] << '' <<vtr[1] << '
'
<<vtr[2]<< 'NS';

出力は次のとおりです。102040

push_back(t)、push_back(rv)

ベクトルの最後に単一の要素を追加するために使用されます。次のようにpush_back(t)を使用します。

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
vtr。push_back((5.5)。;
浮くfl=vtr[4];
費用<<fl<< 'NS';

出力は5.5です。

push_back((rv)。 -後で参照してください。

pop_back()

最後の要素を返さずに削除します。ベクトルのサイズは1つ小さくなります。次のコードはこれを示しています。

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
vtr。pop_back(()。;
浮くNS=vtr。サイズ(()。;
費用<<NS<< 'NS';

出力は3です。

a.swap(b)

次のコードセグメントに示すように、2つのベクトルを交換できます。

ベクター<浮く>>vtr1{{1.1 2.2 3.3 4.4};
ベクター<浮く>>vtr2{{10 20};
vtr1。スワップ((vtr2)。;
費用<< 'vtr1:'<<vtr1[0] <<''<<vtr1[1] <<'
'
<<vtr1[2] <<''<<vtr1[3] << 'NS';

費用<< 'vtr2:'<<vtr2[0] <<''<<vtr2[1] <<'
'
<<vtr2[2] <<''<<vtr2[3] << 'NS';

出力は次のとおりです。

vtr1 10 20 0 0
vtr2 1.1 2.2 3.3 4.4

必要に応じて、ベクトルの長さが長くなることに注意してください。また、置換がなかった値は、デフォルト値に置き換えられます。

クリア()

次のコードセグメントが示すように、ベクトルからすべての要素を削除します。

ベクター<浮く>>vtr{{1.1 2.2 3.3 4.4};
vtr。クリア(()。;
費用<<vtr。サイズ(()。 << 'NS';

出力は0です。

ベクトルの等式および関係演算子

==演算子

2つのベクトルのサイズが同じで、対応する要素が等しい場合、trueの場合は1を返します。それ以外の場合は、falseの場合は0を返します。例えば:

ベクター<int>>U{{1 2 3};
ベクター<int>>V{{4 5 6};
bool bl=U==V;
費用<<bl<< 'NS';

出力は0です。

!=演算子

2つのベクトルのサイズが同じでない場合や、対応する要素が等しくない場合は、trueの場合は1を返します。それ以外の場合は、falseの場合は0を返します。例えば:

ベクター<int>>U{{1 2 3};
ベクター<int>>V{{4 5 6};
bool bl=U!=V;
費用<<bl<< 'NS';

出力は1です。

NS

最初のベクトルが2番目のベクトルの最初のサブセットであり、2つの等しい部分の要素が同じで同じ順序である場合、trueの場合は1を返します。両方のベクトルが同じサイズで左から右に移動し、最初のベクトルで2番目のベクトルの対応する要素よりも小さい要素が検出された場合でも、1が返されます。それ以外の場合は、falseの場合は0が返されます。例えば:

ベクター<int>>U{{3 1 1};
ベクター<int>>V{{3 2 1};
bool bl=U<V;
費用<<bl<< 'NS';

出力は1です。

>演算子

返品!(U

NS<= Operator

Uを返します<= V, where U is the first vector and V is the second vector, according to the above definitions.

> =演算子

返品!(U<= V), where U is the first vector and V is the second vector, according to the above definitions.

結論

ベクトルは、シーケンスコンテナの例です。ベクトルは通常の配列のより良い形式であり、クラスからインスタンス化されます。ベクトルには、構築と代入、容量、要素アクセス、データアクセス、イテレーター、修飾子、および数値のオーバーロード演算子に分類されるメソッドがあります。

list、forward_list、arrayと呼ばれる他のシーケンスコンテナがあります。タスクがシーケンスの途中で頻繁な挿入と削除を伴う場合は、listまたはforward_listを使用する必要があります。タスクにシーケンスの最初または最後で頻繁な挿入と削除が含まれる場合は、両端キューを使用する必要があります。したがって、ベクトルは、これらの種類の操作が重要でない場合にのみ使用する必要があります。