HEXA BLOG

プログラム

HEXA BLOGプログラム2008.10.27

突撃!STL!!

ここ最近ぐっと冷え込み、虫の鳴く声もよく聞くようになりました。るんるん
10月も終わりに近づき、秋らしさを日々実感しちゃいますね。アート
こんにちは、ハラです。
今日は、STL(Standard Template Library)について書いてみたいと思います。
STLとは、C++の標準ライブラリにも含まれているコンテナと
アルゴリズムに関するライブラリのことです。
コンテナは、動的な配列やリスト、連想配列などのデータの入れ物ビール
アルゴリズムは、ソートやマージなどなど、上のコンテナに使うものですひらめき
上手く使えば、短い時間で良いプログラムが書けてしまう便利なものですぴかぴか(新しい)
そこで、STLの機能を知っていて使おうかなと思っている方、もしくは使い始めたばかりの方向けに、コンテナの1つ、vectorについての小ネタを書いてみます耳
それでは、小ネタに移ってみましょう~グッド(上向き矢印)
1ループの際に一時変数に入れるとお得
vectorは配列の代わりに使うことが多いため、下のようなループを書くことがあります。

void TestFunc(std::vector< Data >& dataVec)
{
for( size_t i = 0; i < dataVec.size(); i++ ) {
dataVec[i].get();
//  何かの処理
dataVec[i].set();
}
}

ループの中身は、sizeメソッドの呼び出しを除いて普通の配列と同じかと思います。
でも、この見慣れたコードに対してデバッグを行うと見慣れないことが起きるかもしれませんexclamation&question
環境によっては、デバッガで「dataVec[i]」の値を直接見ることが出来ない場合があるのですあせあせ(飛び散る汗)
ちなみに、私の手元の環境では見れませんでしたもうやだ〜(悲しい顔)
この状況を解決するため、以下の変更を加えてみましたひらめき

void TestFunc(std::vector< Data >& dataVec)
{
for( size_t i = 0; i < dataVec.size(); i++ ) {
Data&    data = dataVec[i];    // ここで一時変数に入れてます
data.get();
//  何かの処理
data.set();
}
}

これは、以前の日記で書かれていたことと同じ変更ですが、
今回は、デバッガで値が見れるようにもなりますひらめき
このコードをデバッガで動かすと、「dataVec[i]」の値は見れなくとも「data」の値は見ることが出来るため、中身の確認が出来るようになるというわけです。
1行追加することで意外な効果がありますね。
2reserveメソッドでサイズの自動拡張を防ぐ
vectorには、push_backメソッドという、末端に要素を追加する便利な機能があります。
便利ではありますが、vectorには格納できる要素数を超えた場合、
自動でサイズを拡張する性質があるのでちょっと注意が必要ですあせあせ(飛び散る汗)
例えば・・・・

std::vector< int >    valueVec;
for( int = 0; i < 1000; i++ ) {
valueVec.push_back(i);
}

と書いた場合、ループを抜けるまでに複数回のサイズの拡張が行われることになります。
サイズの拡張とは、

    ・新しいメモリ領域の確保<img src="https://blog.sakura.ne.jp/images_e/160.gif" alt="exclamation×2" width="15" height="15" border="0" />
・古いメモリから新しいメモリへのコピー<img src="https://blog.sakura.ne.jp/images_e/159.gif" alt="exclamation&amp;question" width="15" height="15" border="0" />
・古いメモリ領域の開放<img src="https://blog.sakura.ne.jp/images_e/159.gif" alt="exclamation&amp;question" width="15" height="15" border="0" />

が1セットとなって行われます。
う~~ん、出来れば避けたいものですもうやだ〜(悲しい顔)
そこで、reserveメソッドを使って事前に格納できる要素数を増やしておきます。

std::vector< int >    valueVec;
valueVec.reserve(1000);
for( int = 0; i < 1000; i++ ) {
valueVec.push_back(i);
}

この変更を加えると、1000個までの要素を格納できるので、ループの中でサイズの拡張が行われることはなくなりますわーい(嬉しい顔)
ちなみに、許容量を増やすだけなのでreserveメソッドを呼んだ直後の要素数は0ということにご注意ください。
3使わないという選択肢も忘れずに
ここまで書いておいてなぜexclamation&questionという気もしますが、使わないことも選択肢の1つです。
vectorは、通常の配列と同じ使い方が出来る上に、サイズの取得や
要素の追加・削除、動的な拡張などが行える便利な物です。
便利なだけに「まずは使ってみよう」と考えてしまいますが、
立ち止まってみて、本当に必要か考えてみるのも良いかもしれません。
初めから必要なサイズが固定とわかっているなら、普通の配列という選択肢がありますし、
要素の追加削除が頻繁に行われるならlistという選択肢もあります。
必要な機能と状況に合わせて、使うかどうかを決めてみてくださいわーい(嬉しい顔)
STLのvectorを使おうと思っている方、使い始めた方、ちょっとは参考になったでしょうか?
機会があれば、他の機能についても触れてみたいと思います。

RECRUIT

大阪・東京共にスタッフを募集しています。
特にキャリア採用のプログラマー・アーティストに興味がある方は下のボタンをクリックしてください

RECRUIT SITE 

NEWS