MochiuWiki : SUSE, EC, PCB
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
C++の基礎 - STL(array)のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
C++の基礎 - STL(array)
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == <code>std::array</code>は、C++11で追加された固定長配列のコンテナクラスである。<br> <code>std::vector</code>に存在する<code>size</code>メソッドや<code>back</code>メソッド等の便利な機能が使用できる。<br> <br><br> == データ構造 == <code>std::array</code>は、<code>std::vector</code>や<code>std::list</code>のようなデータ構造を持たず、通常配列と同じように要素のためにだけメモリを消費する。<br> <code>std::vector</code>と比較してメモリ効率が良いが、要素数が多い場合はその効果は期待できない。<br> <br> <code>std::array</code>の交換においては、中身のデータを交換するしかなく、O(N)の処理時間を要する。<br> <code>std::vector</code>等は、データ領域へのポインタを交換するだけであるため、O(1)の処理時間で済む。<br> <br><br> == 宣言と初期化 == ==== 宣言 ==== <code>std::array</code>は、以下のように宣言する。<br> 要素数は、0以上の整数を指定する。<br> <syntaxhighlight lang="c++"> #include <array> std::array<データ型, 要素数> <オブジェクト名>; </syntaxhighlight> <br> 以下の例では、int型の要素数10のオブジェクトを宣言している。<br> 宣言のみを行う場合、要素はデフォルト値(整数であれば0)に初期化される。<br> <syntaxhighlight lang="c++"> #include <array> std::array<int, 10> ar; // int型、要素数10 </syntaxhighlight> <br> ==== 初期化リストによる初期化 ==== 初期化リストを使って、各要素を初期化することができる。<br> <syntaxhighlight lang="c++"> std::array<int, 4> ar{1, 2, 3, 4}; // int型、要素 = {1, 2, 3, 4} </syntaxhighlight> <br> 初期化リストの要素数が配列要素数より少ない場合、デフォルト値で初期化される。<br> <syntaxhighlight lang="c++"> std::array<int, 4> ar{1, 2}; // ar[2], ar[3] は 0 で初期化される。 </syntaxhighlight> <br> 初期化リストの要素数が配列要素数より多いと、コンパイルエラーとなる。<br> <syntaxhighlight lang="c++"> std::array<int, 2> ar{1, 2, 3, 4}; // コンパイルエラーとなる </syntaxhighlight> <br> 通常の配列であれば、<code>int ar[] = {1, 2, 3, 4};</code>のように要素数を省略できるが、<code>std::array</code>では、要素数を省略できないことに注意すること。<br> <br> ==== コピーコンストラクタ ==== コピーコンストラクタとは、同じ型のオブジェクトを渡され、それと同様の内容のオブジェクトを生成するコンストラクタのことである。<br> <code>std::array</code>では、コピー元オブジェクトと生成するオブジェクトは同じデータ型かつ同一サイズであることに注意すること。<br> std::array<データ型, サイズ> オブジェクト名(コピー元のオブジェクト名); <br> 以下の例では、オブジェクトXをコピーして、{1, 2, 3}という値をもつオブジェクトYを生成している。<br> <syntaxhighlight lang="c++"> std::array<int, 3> X{1, 2, 3}; std::array<int, 3> Y(X); // コピーコンストラクタ </syntaxhighlight> <br><br> == 値の参照と代入 == <code>[]</code>演算子(<code>operator[](int)</code>)を使用して、通常の配列と同様に、配列要素値の参照・代入が可能である。<br> ここで、<code>operator[](int)</code>とは、通常の配列の要素にアクセスする時と同様の記述である。(例. ar[10])<br> <br> 以下の例では、配列要素値の参照と代入をしている。(通常の配列要素の参照・代入と同様)<br> <syntaxhighlight lang="c++"> constexpr int SZ = 10; // 要素数 std::array<int, SZ> ar{3, 1, 4, 1, 5, 9, 2, 6, 5, 3}; for (int i = 0; i < SZ; i++) { std::cout << ar[i]; // arのi番目の要素を表示 } </syntaxhighlight> <br> <syntaxhighlight lang="c++"> constexpr int SZ = 10; // 要素数 std::array<int, SZ> v; // 指定要素数でstd::arrayを生成 for (int i = 0; i < SZ; i++) { v[i] = i; // 要素を 0, 1, 2, 3, ... 9 に設定 } </syntaxhighlight> <br><br> == メンバ関数 == ==== std::arrayの状態を取得 ==== * <code>bool empty()</code> * <code>size_t size()</code> <br> <code>empty</code>メソッドは、配列が空かどうかを判定する。<br> 空ならばtrue、空でなければfalseを返す。<br> <br> これは、後述する<code>size() == 0</code>と判定するのと同等であるが、コンテナクラスによっては、<code>size</code>メソッドよりも<code>empty</code>メソッドの方が高速な場合があるため、<br> <code>std::array</code>等のコンテナクラスに対しては、<code>empty</code>メソッドを使用することが推奨されている。<br> <syntaxhighlight lang="c++"> if(!ar.empty()) { // arが空ではない場合 // ...処理 } </syntaxhighlight> <br> <code>size</code>メソッドは、要素数を返す関数である。(<code>size_t</code>型は、符号なし整数の組み込み型である)<br> <syntaxhighlight lang="c++"> for(int i = 0; i != ar.size(); i++) { // 全要素に対するループ // ...処理 } </syntaxhighlight> <br> ==== std::arrayの要素を取得 ==== * front() : 要素の型への参照 * back() : 要素の型への参照 * data() : 要素の型へのポインタ <br> <code>front</code>メソッドは、先頭要素への参照を返す。(<code>オブジェクト名[0]</code>と同等)<br> <br> <code>back</code>メソッドは、末尾要素への参照を返す。(<code>オブジェクト名[オブジェクト名.size() - 1]</code>と同等)<br> <syntaxhighlight lang="c++"> if(!ar.empty()) { auto f = ar.front(); // 最初の要素 auto b = ar.back(); // 最後の要素 // ...略 } </syntaxhighlight> <br> また、<code>front</code>メソッドおよび<code>back</code>メソッドは、先頭または末尾の要素への参照を返すため、先頭または末尾の要素へ代入することもできる。<br> <syntaxhighlight lang="c++"> std::array<int, 4> ar{1, 2, 3, 4}; ar.front() = 11; // 最初の要素を 11 に変更 ar.back() = 44; // 最後の要素を 44 に変更 </syntaxhighlight> <br> <code>data</code>メソッドは、<code>std::array</code>の先頭アドレスを返す。(<code>&オブジェクト名[0]</code>と同等)<br> <code>std::array</code>は、通常配列と同様にデータ領域が連続したアドレスだということが保証されているため、データアドレスを他の関数に渡して処理することもできる。<br> <syntaxhighlight lang="c++"> std::array<int, 4> ar{1, 2, 3, 4}; int *ptr = ar.data(); // ptrはarの先頭要素へのポインタ cout << *ptr << "\n"; // ptrが指す値(1)が表示される </syntaxhighlight> <br> ==== std::arrayの状態を変更 ==== * void fill(値) * void swap() * void fill(値) <br> fillメソッドは、std::arrayの全ての要素を指定した値にする。 <syntaxhighlight lang="c++"> std::array<int, 10> ar; ar.fill(123); // 全要素を123に変更する </syntaxhighlight> <br> swapメソッドは、引数で指定されたオブジェクトと内容を入れ替える。 入れ替えるstd::arrayオブジェクトは、型および要素数ともに同一であることに注意する。 <syntaxhighlight lang="c++"> std::array<int, 5> x{1, 2, 3, 4, 5}, y{6, 7, 8, 9, 10}; x.swap(y); // xとyの内容を入れ替える </syntaxhighlight> <br> <u>※注意</u><br> <u><code>std::vector</code>の場合、オブジェクトが持つデータ領域へのポインタ等を交換するだけであるため、処理時間はO(1)であるが、</u><br> <u><code>std::array</code>の場合、要素の全てを交換するため、処理時間はO(N)となる。</u><br> <br> ==== イテレータ ==== * begin() : iterator * end() : iterator * cbegin() : const_iterator * cend() : const_iterator <br> beginメソッドとendメソッド<br> beginメソッドは、最初の要素へのイテレータ、endメソッドは最後の要素の次へのイテレータを返す。<br> <syntaxhighlight lang="c++"> int i = 0; for(auto itr = ar.begin(); itr != ar.end(); itr++, i++) { *itr = i; } </syntaxhighlight> <br> cbeginメソッドとcendメソッド<br> cbeginメソッドは最初の要素へのconstイテレータ、cendメソッドは最後の要素の次のconstイテレータを返す。<br> 通常のイテレータの場合、*itr = 123;のように指している先の値を変更できるが、constイテレータの場合、*itr = 123;のように記述するとコンパイルエラーとなる。<br> <syntaxhighlight lang="c++"> for(auto itr = ar.cbegin(); itr != ar.cend(); ++itr) { // *itr = 123; // const イテレータの指す先への代入はコンパイルエラーとなる std::cout << *itr << "\n"; } </syntaxhighlight> <br><br> == アルゴリズム == C++には便利なアルゴリズムがいくつも用意されている。<br> http://www.cplusplus.com/reference/algorithm/<br> <br> <code>std::array</code>に対してよく使用されるアルゴリズムを、以下に記載する。<br> * accumulate(first, last, 初期値) : 要素型 * void sort(first, last) * void reverse(first, last) <br> ==== accumulate(first, last, 初期値) ==== <code>accumulate(<オブジェクト名>.begin(), <オブジェクト名>.end(), init)</code>メソッドは、コンテナの最初から最後までを要素を積算(全加算)する。<br> 第3引数は、初期値(通常は0)を指定する。<br> <br> なお、<code>accumulate</code>メソッドを使用するには、<code>#include <numeric></code>が必要である。<br> <syntaxhighlight lang="c++"> #include <numeric> int main() { std::array<int, 10> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; std::cout << std::accumulate(v.begin(), v.end(), 0) << "\n"; } </syntaxhighlight> <br> 一部だけを積算する場合、<code>accumulate(v.begin() + i, v.begin() + k, 0)</code>のように、イテレータで範囲を指定する。<br> また、<code>accumulate(&v[i], &v[k], 0)</code>のように、要素へのポインタで指定することも可能である。<br> <br> ==== sort(first, last) ==== <code>sort(<オブジェクト名>.begin(), <オブジェクト名>.end())</code>メソッドは、コンテナの要素を昇順にソートする。<br> なお、<code>sort</code>メソッドを使用するには、<code>#include <algorithm></code>が必要である。<br> <syntaxhighlight lang="c++"> #include <algorithm> int main() { std::array<int, 11> v{3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5}; std::sort(v.begin(), v.end()); return 0; } </syntaxhighlight> <br> 一部をソートする場合、<code>sort(v.begin() + i, v.begin() + k)</code>のように、イテレータで範囲を指定する。<br> また、<code>sort(&v[i], &v[k])</code>のように、要素へのポインタで指定することも可能である。<br> <br> ==== reverse(first, last) ==== <code>reverse(<オブジェクト名>.begin(), <オブジェクト名>.end())</code>メソッドは、コンテナの要素を逆順にする。<br> <syntaxhighlight lang="c++"> std::array<int, 11> v{3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5}; std::reverse(v.begin(), v.end()); // 順序反転 for(auto x : v) { std::cout << x << " "; } std::cout << "\n"; </syntaxhighlight> <br><br> __FORCETOC__ [[カテゴリ:C++]]
C++の基礎 - STL(array)
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse