Overblog
Editer l'article Suivre ce blog Administration + Créer mon blog
donaldmartinni.over-blog.com

維生素d 功能 手機 検査

維生素d 功能   手機   検査 WEBINAR:オンデマンドアプリケーションセキュリティテスト:DevOpsの不可欠な部分 環境:VC6 SP5、STLPort、Windows 2000 SP2  このC ++チュートリアルは、C ++プログラマーが標準のテンプレートクラスを把握するのに役立ちます. )ベクトルを使用する理由 C ++標準の最終的な技術的投票は1997年11月14日に行われました。それは5年以上前だった. しかし、標準の重要な部分、特に標準ライブラリは、多くのC ++ユーザーの間であまり一般的ではありません. CodeGuruのC ++フォーラムの絶え間ない読者は、多くの質問と回答が、標準ライブラリを使用して非常にエレガントに解決できる手作りのソリューションを暗示していることに、すぐに気づくだろう. 非常に頻繁に起こる1つの問題は、Cスタイルの配列の使用です。すべての問題と欠点があります. この記事では、私はベクトルをとり、よりアクセスしやすく理解できる方法で説明しようとします. ベクトルの概要Vectorは、古い古いCスタイルの配列を完全に置き換えるテンプレートクラスです. これは、プレーンな配列で使用されているのと同じ自然な構文を可能にしますが、C ++プログラマが割り当てられたメモリを世話せず、含まれているオブジェクトで一貫して動作するのを助ける一連のサービスを提供します. ベクトルを使用する最初のステップは、適切なヘッダをインクルードすることです:#includeヘッダファイル名には拡張子がありません。これはすべての標準ライブラリヘッダーファイルに当てはまります. 2番目に知っておくべきことは、すべての標準ライブラリが名前空間stdに存在することです. つまり、std ::をprependすることによって名前を解決する必要があります。std :: vector v;小規模なプロジェクトでは、cppファイルの上にusingディレクティブを挿入することで、名前空間std全体をスコープに入れることができます: #include 名前空間stdを使用します。ベクトルv;これは、あなたのcppファイルにusingディレクティブを書く限り、小規模なプロジェクトでは問題ありません. usingディレクティブをヘッダファイルに書き込まないでください!これは、そのヘッダーを含む各cppファイルに名前空間std全体を拡張します.
維生素d 功能 手機 検査 さいたま市
大規模なプロジェクトの場合は、それに応じてすべての名前を明示的に修飾する方がよい. 私は、適切な場合には、より良い可読性のためにいくつかのtypedefを例題で紹介します. さて、std :: vector v;とは何ですか?これは、Tsの配列をラップするテンプレートクラスです. この広く使用されている表記法では、「T」は、任意のデータ型、組み込み、またはユーザー定義のクラスを表します. ベクトルは、あなたのために扱う連続したメモリ領域にTsを格納し、Cスタイルの配列とまったく同じように、vを書くだけで個々のTsにアクセスできるようにします. 大きなプロジェクトでは、明示的な型のベクトルを繰り返し書き出すことが面倒であることに注意してください. 必要に応じてtypedefを使うことができます: typedef std :: vector int_vec_t; int_vec_t v;  マクロを使用しないでください! #define int_vec_t std :: vector;最初は、ベクトルが私たちのためにできることを見てみましょう. プレーン・アレイを使用していた場合は、静的配列または動的配列のいずれかがあります。 size_t size = 10; int sarray; int * darray =新しいint; for(int i = 0; i <10; ++ i){sarray = i;ダーリー=私; } delete []ダライ;  ベクトルを使って同じことをしよう: #include size_t size = 10; std :: vector配列(サイズ); for(int i = 0; i 維生素d 功能 手機 検査 ワ氏
STLPortは "vector"という単語を出力します.DinkumwareのVisual C ++の実装では、 "invalid vector subscript". 今、あなたが持つ要素の数が分からない場合はどうなりますか?要素を格納するためにCスタイルの配列を使用していた場合は、時々配列を拡張できるロジックを実装する必要があります。または、十分に大きい配列を割り当てます. そうではありません: #include #include std :: vector array; char c = 0; 一方、(c '=' x '){std :: cin >> c;アレイ. push_back(c); }  前の例では、push_back()は一度に1つの要素を配列に追加します. それが何であるかを理解するためには、ベクターがいわゆる「制御された配列」を有することを知る必要があります。そのシーケンスの一定量の割り当てられたストレージ. この配列を保持するために、vectorはいくつかのメモリを割り当てます。ほとんどの場合、必要以上にメモリが割り当てられます. 割り当てられたメモリが使い果たされるまで、要素をpush_back()することができます. 次に、ベクトルは再割り当てをトリガし、割り当てられたメモリブロックを拡張します. これは、制御されたシーケンスをより大きなブロックに移動(つまり、コピーする)する必要があることを意味します. 多数の要素をコピーすると、アプリケーションのパフォーマンスが大幅に低下する可能性があります. 再割り当てはあなたにとって絶対に透過的であることに注意してください(メモリからの致命的な失敗は避けてください). あなたは何もする必要はありません。ベクトルは、フードの下で取るものすべてを行います. もちろん、ベクトルがストレージをあまりにも頻繁に再割り当てするのを避けるためにできることがあります.
維生素d 功能 手機 検査 料金
使用されている標準ライブラリの実装に応じて、空のベクトルはメモリを割り当てても割り当てなくてもかまいません. "ベクターの記憶領域を頻繁に再割り当てすることを避けたい場合、そのreserve()メンバ関数を使うことができます: #include #include std :: vector array; アレイ. 予備(10); char c = 0; 一方、(c '=' x '){std :: cin >> c;アレイ. push_back(c); }  reserve()に渡すパラメータは、もちろんコンテキストに依存します. 関数reserve()は、この場合少なくとも10要素の余裕があることを保証します. ベクトルが既に必要な数の要素に余裕を持っている場合、reserve()は何もしません. つまり、reserve()は必要に応じてベクトルの割り当てられた格納領域を拡張しますが、縮小することはありません. 補足として、次の2つのコードスニペットは同じものではありません。std :: vector v(10); std :: vector v; v. 予備(10);  最初のスニペットは10個の整数を含むベクトルを定義し、デフォルト値(0)で初期化します。. もし整数ではなくユーザ定義のクラスがあれば、vectorはデフォルトのctorを10回呼び出し、すぐに構築された10個のオブジェクトを含みます. 2番目のスニペットは空のベクトルを定義し、10個の整数のための空き領域を作るように指示します. ベクトルは、少なくとも10の整数を保持するのに十分なメモリを割り当てますが、このメモリを初期化しません. 整数でなくユーザ定義のクラスがある場合、2番目のスニペットはそのクラスのインスタンスを構築しません. 現在割り当てられているベクトルの格納領域に収まる要素の数を調べるには、capacity()メンバ関数を使用します. 現在ベクターに含まれている要素の数を調べるには、size()メンバー関数を使用します。 #include #include std :: vector array; int i = 999;アレイ.
維生素d 功能 手機 検査 ツール
capacity()<< std :: endl; std :: cout <<配列. size()<< std :: endl;  これは印刷されます 10 1  つまり、再割り当てを引き起こさずにベクトルに追加できる要素の数は、常にcapacity() - size()です。. はい、reserve()を使用して少なくとも10個の要素の空きを確保しましたが、メモリは初期化されていません. intはビルトイン型なので、operator []で10個の要素をすべて書き込むと実際には動作しますが、size()は1を返すのでベクトルが矛盾した状態になります. 一見すると、これは不便に思えるかもしれませんが、これがなぜそうであるかを詳しく見てみましょう:ベクトルがユーザ定義クラスのオブジェクトを含んでいた場合、reserve()は任意のctor. まだ作成されていないオブジェクトへのアクセスには未定義の結果があり、いずれの場合もno-noです. 覚えておくべき重要なことは、reserve()の役割は潜在的な再割り当ての数を最小限に抑えることであり、制御されたシーケンスの要素数には影響しないことです. 現在のcapacity()より小さいパラメータでreserve()を呼び出すと、単純に何もしません. 含まれる要素の数を拡大する正しい方法は、ベクトルのメンバ関数resize()を呼び出すことである。. メンバ関数resize()には、次のプロパティがあります。 新しいサイズがベクトルの古いサイズより大きい場合、制御されたシーケンスに既に存在するすべての要素が保持されます。残りは第2のパラメータに従って初期化される. 新しいサイズが古いサイズよりも小さい場合、最初のnew_size要素のみが保持されます. 新しいサイズがcapacity()より大きい場合、new_size要素がすべて収まるようにストレージを再割り当てします. サイズ変更(6,1);制御される要素の数を増やす別の方法は、push_back()を使用して、. 次の例を見ると、ベクトルのフードの下でより詳しく見てみましょう: クラスX { void set(int val){val_ = val;} set(int val){val(int val);} プライベート:int val_; }; std :: vector ax;斧. サイズ変更(10); for(int i = 0; i <10; ++ i){ax. push_back(X(i)); }  2つのバージョンは同等です。つまり、同じ結果が得られます.
維生素d 功能 手機 検査 数値
最初のバージョンでは、resize()を使用して、制御されたシーケンスのサイズを10個の要素に拡大しました. これはベクトルストレージを再割り当てするだけでなく、Xのデフォルトctorを使用して10要素のシーケンスを構築します. resize()が終了すると、ベクトルにX型の有効なオブジェクトが10個あります。これらのオブジェクトはすべてval_ == 0です。これは、Xのデフォルトのctorが行うことになるからです. 2番目のステップでは、シーケンス内のすべてのXを選択し、X :: set()を使用してval_. 2番目のステップでは、2番目のctorを使用してX型のオブジェクトを10個作成し、それらに直接正しい値を与え、それらをベクトルにpush_back()します. どの方法がより効率的ですか?これはおそらく標準ライブラリの実装にも依存しますが、2番目のバージョンは、各要素に対してX :: set()を呼び出さないため、やや効率的です. ベクターを宣言する方法とそれを埋める方法を見てきたので、それをどのように操作できるかを見てみましょう. まず、Cスタイルの配列に類似したものから始めて、より良いまたはより安全な他の可能性を徐々に発見します. Cスタイルの配列にアクセスするには、添え字演算子を使う方法とポインタを使う方法の2通りがあります. また、Cスタイルの配列を関数に渡すことは、ポインタを最初の要素に渡すことを意味します. 小さな例を挙げる: #include double mean(double * array、size_t n) {double m = 0; for(size_t i = 0; i 維生素d 功能 手機 検査 料金
これは、vectorの最初の要素のアドレスを関数mean()に渡すことができ、それがうまくいくことを意味します: int main() {std :: vector a; a. push_back(5); std :: cout << mean(&a、5)<< std :: endl; 0を返します。 }  それは素晴らしいですが、まだそれほど同じではありません. Cスタイルの配列を直接初期化することはできましたが、要素をベクトルにpush_back()する必要がありました. ベクトルのイニシャライザリストを直接使うことはできませんが、中間配列を使うことができます: ダブルp [] = {1,2,3,4,5}。 std :: vector a(p、p + 5);  ここでは、vectorによって提供される別のコンストラクタを使用します. Cスタイルの配列の最初の要素へのポインタと、その配列の最後の要素を通るポインタへのポインタ. 2つのことが重要です:配列はコピーされ、何らかの形で新しく作成されたベクトルを保持しません。そして、私たちが提供する範囲は配列の最後の要素を越えた最初の要素から1つです. ベクトルやその他の標準的なコンテナを扱う場合は、2番目の点を理解することが重要です. 制御されたシーケンスは、常にctorsだけでなく、ある範囲の要素で動作するすべての関数. ベクトルに含まれている要素のアドレスをとるときに注意すべきことがあります:ベクトルの内部再配置は、あなたがその要素に保持しているポインタを無効にします. push_back(999); * pi = 333;前の例では、ベクトルの4番目の要素のアドレスをとり、それをpiに格納します. ブーム!これは、追加要素を保持するのに十分な大きさでない場合には、push_back()がvの内部ストレージの再割り当てをトリガーする可能性があるからです. piは、削除されたばかりのメモリアドレスを指し、それを使用すると結果は未定義です. 悪い知らせは、ベクトルが一般的なケースでは教えてくれない内部ストレージを再割り当てするかどうかということです. 解決策は、無効化された可能性のあるポインタを使用しないか、ベクトルが再割り当てされないことを確認することです.
維生素d 功能 手機 検査 つくば
後者は、ベクトルに定義された時間にメモリ(再)割り当てを処理させるためにreserve()を賢明に使用することを意味します. これまで見てきたメンバ関数から、push_back()とresize()だけがベクトルへのポインタを無効にすることができます. ポインタを無効にする他のメンバ関数があります。このチュートリアルで後で説明します. 添え字演算子とメンバ関数at()の両方がポインタをベクトルに無効化することはないことに注意してください. ベクトルへのポインタについて言えば、この時点で標準コンセプトを導入することができます:イテレータ. イテレーターは、標準ライブラリーがすべてのコンテナーvector、list、set、dequeなどの共通インターフェースをモデル化する方法です. その理由は、あるコンテナの「自然な」演算(ベクトルの添え字のような)は、他のコンテナには意味をなさない. 標準ライブラリには、反復、発見、ソートなどのアルゴリズムをすべてのコンテナに適用する一般的な方法が必要です。イテレータの概念. あなたが望むなら、あなたのお気に入りの教科書で正確な定義を見つけることができます. 重要なことは、イテレータを使用している場合、それを逆参照して、それが「ポイントする」要素を取得できることです(イテレータの最も自然な実装は実際にはプレーンなバニラ・ポインタですが、. 小さな例でイテレータを把握しましょう: #include #include int main() {std :: vector a; std :: vector :: const_iterator i; a.
維生素d 功能 手機 検査 料金
終わり(); ++ i){std :: cout <<(* i)<< std :: endl; } 0を返します。 }  この小さなプログラムを段階的に実行しましょう:std :: vector :: const_iterator i;これはベクトルのconst iterator iを宣言します. constイテレータを使用しているのは、ベクトルの内容を変更するつもりはないからです. メンバ関数begin()は、シーケンス内の最初の要素を「ポイントする」イテレータを返します. メンバー関数end()は、シーケンス内の最後の要素の1つを「ポイント」するイテレータを返します. end()によって返されたイテレータの逆参照は不正であり、結果は未定義であることに注意してください. ++ iイテレータをインクリメントすることで、ある要素から次の要素に進むことができます. 同じプログラムがイテレータの代わりにポインタを使用すると、非常によく似た構造になります。 #include #include int main() {std :: vector a; const double * p; a. push_back(5); (p =&a; p!=&a + 5; ++ p){std :: cout <<(* p)<< std :: endl; } 0を返します。 }  したがって、同じ方法で基本的に同じことを達成するためにポインタを使用できる場合は、イテレータを使用するのはどうしてですか?答えは、並べ替えのような標準的なアルゴリズムをベクトルに適用する場合は、イテレータを使用する必要があるということです. 標準ライブラリは、さまざまなコンテナのメンバ関数としてアルゴリズムを実装するのではなく、多くのコンテナで動作できる空きテンプレート関数として実装しています. 一般的な標準コンテナ(特にベクトル)と標準アルゴリズムの組み合わせは、非常に強力なツールです。残念なことに、あまりにもしばしばプログラマーによって無視される. これを使用すると、手作りでエラーが発生しやすいコードの大部分を避けることができ、コンパクトで移植性が高く保守可能なプログラムを書くことができます. ベクトルが提供するメンバー関数を見てみましょう:コンストラクタC ++コンストラクタ、C ++デストラクタ、およびコピー演算子の完全なセットが提供されています. 標準文字列のベクトルの例でそれらを見てみましょう: typedef std :: vector str_vec_t; str_vec_t v1; str_vec_t v2(10); str_vec_t v3(10、 "hello"); str_vec_t v4(v3); std :: list sl; sl.

維生素d 功能 手機 検査 数値

終わり()); v1 = v5; assign()関数assign()関数はベクトルを再初期化します. 最初の、最後のイテレータを使用して有効な要素範囲を渡すか、または作成する要素の数と要素の値を指定できます. assign(3、 "hello");割り当てによって、ベクトルの要素が完全に変更されます. 古い要素(存在する場合)は破棄され、ベクトルのサイズは割り当てられた要素の数に設定されます. 対応する関数pop_back()があり、制御されたシーケンスの最後の要素を削除します. pop_back();  pop_back()はcapacity()を縮小しないことに注意してください。. また、rbegin()とrend()があり、逆順シーケンスの最後から1つ前の要素をそれぞれ指しています. rbegin()とrend()の両方がiterator(それぞれconst_iterator)と同じではないreverse_iterator(またはconstバージョンのconst_reverse_iterator)型を返します。. 逆イテレータから「通常の」イテレータを得るには、reverse_iteratorのbase()メンバ関数を使用します。 std :: vector v; v. push_back(999); std :: vector :: reverse_iterator r = v. rbegin(); std :: vector :: iterator i = r. ベース();要素のアクセス未チェックのアクセスを提供する添字演算子[]と、渡されたインデックスが無効な場合にstd :: out_of_range型のオブジェクトをスローするメンバ関数at()があります. 2つの他のメンバ関数、front()とback()が存在し、制御されたシーケンスの最初の要素、最後の要素. 彼らはイテレータを返さないことに注意してください! std :: vector v; v.
維生素d 功能 手機 検査 タイミング
リスト操作ベクトルによって提供されるいくつかの操作は、実際にはリストのネイティブです. それらはほとんどのコンテナによって提供され、制御されたシーケンスの途中で要素の挿入と消去を処理します. いくつかの例でそれらを示しましょう: #include #include int main() {std :: vector q; q. push_back(12); std :: vector v; for(int i = 0; i :: iterator it = v. clear(); 0を返します。 }  insert()とerase()の両方が、保持しているイテレータを無効にする可能性があることに注意してください. insert()の最初のバージョンは、挿入された要素を指すイテレータを返します. 再配置が発生しない場合(挿入前のreserve()など)、挿入ポイントとシーケンスの最後の間に出力されるイテレータのみが無効になります. 要素を消去することは決して再割り当てを引き起こすことはなく、それはcapacity()にも影響しません。. ただし、消去された最初の要素とシーケンスの最後を指すイテレータはすべて無効になります. clear()を呼び出すと、制御されたシーケンスからすべての要素が削除されます。. insert()とerase()の両方がベクトルにはあま​​り効率的ではないことに注意してください. アプリケーションで挿入や消去が頻繁に使用される場合は、ベクターがおそらくあなたのための最良の選択肢ではありません. 比較演算子演算子==、!=およびを使用して、要素ごとに2つのベクトルの内容を比較できます。 . 2つの等しいベクトルのcapacity()は同じである必要はないことに注意してください. 内容の入れ替え時には、2つのベクトルの内容を入れ替えることができるのが実用的です.

維生素d 功能 手機 検査 さいたま市

一般的なアプリケーションは、ベクトルが保持しているメモリを解放するように強制します. 要素を消去するか、またはベクトルをクリアすることがその容量()に影響を与えないこと(つまり、割り当てられたメモリ)が、. 我々は小さなトリックをする必要があります: std :: vector v; v. スワップ(std :: vector(v));  通常は(以下を参照)、ベクトルは単純にそれらの勇気を交換する. 一時オブジェクトはvによって保持されるメモリ全体を受け取り、vは一時オブジェクトによって保持されるメモリを受け取ります。これは作成時に何も割り当てない可能性があります. 一時的に生成されたベクトルは、上記のステートメントの最後で破棄され、vによって正式に保持されているすべてのメモリが解放されます. ベクトルクラステンプレートには、2番目のデフォルトテンプレートパラメータがあります。 テンプレート>クラスベクトル . アロケータは、その要素にメモリを割り当てたり解放したりするためにコンテナが使用する関数を提供するクラスです. このチュートリアルでは、デフォルトのアロケータがあると仮定していますが、引き続きこれを仮定します. 完全性のために、両方のアロケータが同じであれば、swap()は一定の時間内に実行されることに注意してください(単純に2つのベクトルの隙間を入れ替えます). この最初のチュートリアルでは、標準ライブラリの表面を傷つけ、std :: vectorを満たしています. 次のチュートリアルでは、ベクトルに関連するより高度なトピックをそれぞれ見て、標準アルゴリズムを適用し、オブジェクトをいつ保存するか、ベクターへのオブジェクトへのポインタを格納するタイミングなどの設計上の決定について説明します.
Partager cet article
Repost0
Pour être informé des derniers articles, inscrivez vous :
Commenter cet article