【C++学習ノート】反復器と配列

12168 ワード

一、反復器
1.1ポインタとは異なり、反復器には反復器のタイプがあり、戻り反復器を持つメンバーがあります.たとえば、beginメンバーが最初の要素を指し、endメンバーがコンテナの最後の要素を指す次の位置を返す反復器があります.
1.1.1反復演算子
string s("some string");
auto it = s.begin();
while (it != s.end()){        //  s  
   *it = toupper(*it);        //           
   ++it;
}

1.1.2反復器タイプ  一般的にstringとvectorを知らないsize_typeメンバーがどんなタイプなのかはわかりませんが、反復器の正確なタイプも知る必要はありません.実際に反復器を持つ標準ライブラリタイプはiteratorとconst_を使用しています.iteratorは反復器のタイプを表します.
vector<int>::iterator it;        //it   vector   
string::iterator it2;            //it2   string      
vector<int>::const_iterator it3; //it3     ,     
string::const_iterator it4;      //it4     ,     

 beginとendが返す具体的なタイプは、オブジェクトが定数であるかどうかによって決定されます.オブジェクトが定数である場合、beginとendはconst_を返します.iterator、そうでなければiteratorを返します.オブジェクトが読み取り操作のみで書き込み操作が不要な場合(オブジェクト自体が定数であるかどうかにかかわらず)、const_を容易にするためにiteratorタイプの戻り値は、cbeginとcendを使用できます.
vector<int> v1;
const vector<int> v2;
auto it1 = v1.begin();          //it1    vector::iterator
auto it2 = v2.begin();          //it2    vector::const_iterator
auto it3 = v1.cbegin();         //it3    vector::const_iterator

1.1.3反復器は、反復器が指すオブジェクトを取得するために、反復器が指すオブジェクトを参照し、そのオブジェクトのタイプがクラスである場合、文字列からなるvectorオブジェクトなどのメンバーにさらにアクセスしたい場合があります.その要素が空であるかどうかを確認し、itをそのvectorオブジェクトの反復器にするには、次に、itが指す文字列が空であるかどうかを確認します.
(*it).empty()

  はC++で矢印演算子(->)を定義し、矢印演算子は解参照とメンバーアクセスの2つの操作、すなわちit->menと(*it)を結合する.men表現の意味は同じです.  注意しなければならないのは、vectorオブジェクトは動的に成長することができるが、forサイクルでvectorオブジェクトに要素を追加することはできないし、vectorオブジェクトの容量を変更する可能性のあるいずれかの操作でvectorオブジェクトの反復器が失効するため、反復器を使用する循環体は、反復器が属するコンテナに要素を追加しないことです.
1.2反復演算任意の標準ライブラリタイプの2つの有効な反復器を比較し、これらの演算を反復器演算と呼びます.
1.2.1反復器の算術演算
//         vi        
auto mid = vi.begin() + vi.size()/2;

二、配列
2.1組み込み配列の定義と初期化は複合タイプであり、配列内の要素の個数は配列タイプの一部に属し、コンパイル時に次元は既知であり、すなわち次元は定数式でなければならない.組み込みタイプの変数と同様に、関数内に組み込みタイプの配列が定義されている場合、デフォルトの初期化では、配列に未定義の値が含まれます.
unsigned v1 = 42;            //       
constexpr unsigned v2 = 42;  //      
int arr[10];                 //  10      
int *parr[v2];               //  42        
int bad[v1];                 //  ,v1       

2.1.1配列要素の初期化
const unsigned sz = 3;
int a1[sz] = {0,1,2};
int a2[] = {0,1,2};           //   3   
int a3[5] = {0,1,2};          //   a3[]={0,1,2,0,0}
int a4[3] = {"hi","bye"};     //   a4[]={"hi","bye",""}
int a5[2] = {0,1,2};          //  ,     

  文字列の文字面値で文字配列を初期化できることに注意する必要がありますが、文字列の文字面値の末尾に空の文字があり、配列の内容が他の配列にコピーされて初期値として使用されず、配列で他の配列に値を付与することもできません.
const char a6[6] = "daniel"   //  ,          
int a[] = {0,1,2};
int a7[] = a;                 //  ,                 
a7 = a;                       //  ,                  

2.1.2複雑な配列宣言
int *ptrs[10];                //ptrs   10        
int &refs[10] = /* ? */       //  ,        
int (*parray)[10] = &arr;     //parray      10      
int (&arrRef)[10] = arr;      //arrRef      10      
int *(&arry)[10] ptrs;        //arry      ,     10   

2.1.3アクセス配列要素  標準ライブラリタイプvectorとstringと同様に、配列の要素も範囲for文または下付き演算子を使用してアクセスできます.配列のインデックスは0から始まり、配列下付きを使用する場合、通常はsize_と定義されます.tタイプ、size_tは、メモリ内の任意のオブジェクトのサイズを表すのに十分な大きさに設計された機械に関連する符号なしタイプである.
unsigned scores[11] = {};     //    0
unsigned grade;
while (cin >> grade){
   if (grade <= 100)
      ++scores[grade/10];     //         1
}
for (auto j : scores)
   cout << j << " ";          //        
cout << endl;

2.2ポインタと配列 C++言語では、ポインタと配列が非常に密接に関連しており、配列を使用するときにコンパイラがポインタに変換するのが一般的です.通常、オブジェクトのポインタを取得するには、アドレスを使用します.
int nums[] = {1,2,3,4};
int *p = &nums[0];            //p  nums      
int *p2 = nums;               //   p2=&nums[0]
auto p3(nums);                //p3       ,  nums     
p3 = 42;                      //  ,p3     ,   int         

  decltypeキーワードを使用する場合、すなわちdecltype(nums)の場合に返されるタイプは、10個の整数からなる配列であることに注意してください.
decltype(nums) a = {0,1,2,3,4,5};
a = p;                        //  ,            
a[4] = j;                     //  , j    a      

2.2.1ポインタも反復器vectorとstringの反復器がサポートする演算であり、配列のポインタはすべてサポートされ、配列の中の要素をポインタで遍歴することができ、配列の最初の要素と最後の要素の次の位置を指すポインタを得ることを前提としている.
int arr[] = {0,1,2,3,4};
int *p = arr;                 //p  arr      
++p;                          //  p  arr[1]

1つのポインタに整数値を加算または減算した結果もポインタであり、新しいポインタが指す要素は元のポインタに比べて整数値の位置を前進または後退し、その結果ポインタを参照解除することができる.
constexpr size_t sz = 5;
int arr[sz] = {1,2,3,4,5};
int *p = arr;
int *p2 = p+4;               //p2  arr[5]
int *last = *(p+4);          //last    5

ジルコニウムは反復器と同様に、2つのポインタが減算された結果、それらの間の距離であり、演算に関与する2つのポインタは同じ配列の要素を指し示さなければならない.2つのポインタが減算された結果のタイプはptrdiff_です.tの標準ライブラリタイプ、size_t同様ptrdiff_tはcstdeffヘッダファイルに定義されたマシン関連のタイプでもあり、vectorやstringとは異なる記号付きタイプである.
int *p = &arr[2];          //p     2   
int k = p[-2];             //p[-2] arr[0]       

2.2.2標準ライブラリ関数beginとend
int a[] = {0,1,2,3,4,5,6};
int *beg = begin(a);           //  a      
int *last = end(a);            //  a           

参考文献:①C++Primer第五版.