標準庫型別vector表示物件的集合,其中所有物件的型別都相同。集合中的每個物件都有乙個與之對應的索引,索引用於訪問物件。因為vector 「容納著」其他物件,所 以它也常被稱作容器(container)。
要想使用vector,必須包含適當的標頭檔案。在後續的例+中,都將假定做了如下 using宣告:
#include定義和初始化vector物件using std::vector;
和任何一種類型別一樣,vector模板控制著定義和初始化向量的方法。表3.4列出 了定義vector物件的常用方法。當然也可以在定義vector物件時指定元素的初始值。例如,允許把乙個vector對 象的元素拷貝給另外乙個vector物件。此時,新vector物件的元素就是原vector 物件對應元素的副本。注意兩個vector物件的型別必須相同:
vectorivec; //相始狀態為空c++11新標準還提供了另外一種為vector物件的元素賦初值的方法,即列表初始化。此時,用花括號括起來的0個或多個初始元素值被賦給vector物件://在此處給ivec新增一些值
vectorivec2(ivec); //
把ivec的元素拷貝給ivec2
vectorivec3 = ivec; //
把ivec的元素拷貝給ivec3
vectorsvec(ivec2); //
錯誤:svec的元素是string物件,不是int
列表初始化vector物件
vectorarticles = ;向vector物件屮新增元素對vector物件來說,直接初始化的方式迠用於三種情況:初始值已知且數量較少、 初始值是另乙個vector物件的副本、所有元素的初始值都一樣。然而更常見的情況是: 建立乙個vector物件時並不清楚實際所需的元素個數,元素的值也經常無法確定。還有些時候即使元素的初值已知,但如果這些值總量較大而各不相同,那麼在建立vector對 象的時候執行初始化操作也會顯得過於煩瑣。更好的處理方法是先建立乙個空vector,然後在執行時再利用vector的成員函式 push_back向其中新增元素。push_back負責把乙個值當成vector物件的尾元素「壓到(push)」 vector物件的「尾端(back)」。例如:
vectorv2; // 空 vector 物件for (int i = 0; i != 100; ++i)
v2 .push_back(i);//依次把整數值放到v2尾端 //迴圈結束後v2有100個元素,值從0到99在上例中,儘管知道vector物件最後會包含100個元素,但在一開始還是把它宣告成空 vector,在每次迭代時才順序地把乙個整數作為v2的新元素新增給它。其他vector操作除了 push_back之外,vector還提供了兒種其他操作,大多數都和string的相 關操作類似,£3.5列出了其中比較重要的一些。訪m vector物件中兀素的方法和訪問string物件中字元的方法差不多,也是通過 元素在vector物件中的位置。例如,可以使用範圍for語句處理vector物件中的所有元素:
vectorv;for (auto &i : v) //對於v中的每個元素(注意:i是乙個引用)
i *= i; //求元素值的平方for (auto i : v) //對於v中的每個元素cout « i « ""; //輸出該元素cout << endl;注意:在這裡for()屬於基於範圍的for語句。第乙個迴圈把控制變數i定義成引用型別,這樣就能通過i給v的元素賦值,其中i的 型別由auto關鍵字指定。這裡用到了一種新的復合賦值運算子。 如我們所知,+=把左側運算物件和右側運算物件相加,結果存入左側運算物件;類似的, *=把左側運算物件和右側運算物件相乘,結果存入左側運算物件。最後,第二個迴圈輸出所有元素。
計算vector內物件的索引使用下標運算子能獲取到指定的元素。和string一樣, vector物件的下標也是從0開始計起,下標的型別是相應的size_type型別。只要 vector物件不是乙個常量,就能向下標運算子返回的元素賦值。此時,也能通過計算得到vector內物件的索引,然後直接獲取索引位置 上的元素。//使用下標for(decltype(vstr.size()) in=0;in!=vstr.size();in++)cout
迭代器介紹我們已經知道可以使用下標運算子來汸問string物件的字元或vector物件的元素,還有另外一種更通用的機制也可以實現同樣的目的,這就是迭代器(iterator)。除了vector之外,標準庫還定義了其他幾種容器。所有標準庫容器 都可以使用迭代器,但是其中只有少數幾種才同時支援下標運算子。嚴格來說,string 物件不屬於容器型別,但是string支援很多與容器型別類似的操作。vector支援下標運算子,這點和string一樣;string支援迭代器,這也和vector是一樣的。類似於指標型別,迭代器也提供了對物件的間接訪問。就迭代器而自,其物件是容器中的元素或者string物件中的字元。使用迭代器可以訪問某個元素,迭代器也能從乙個元素移動到另外乙個元素。迭代器有有效和無效之分,這一點和指標差不多。有效的迭代器或者指向某個元素,或者指向容器中尾元素的下一位置:其他所有情況都屬於無效。
使用迭代器
和指標不一樣的是,獲取迭代器不是使用取位址符,有迭代器的型別問時擁有返回迭 代器的成員。比如,這些型別都擁有名為begin和end的成員,其中begin成員負責返回指向第乙個元素(或第乙個字元)的迭代器。如有下述語句:
//由編譯器決定b和e的型別end成員則負責返回指向容器(或string物件)「尾元素的下一位置(one past the end)」 的迭代器,也就是說,該迭代器指示的是容器的乙個本不存在的「尾後(off the end)」元素。這樣的迭代器沒什麼實際含義,僅是個標記而己,表示我們己經處理完了容器中的所 有元素。end成員返問的迭代器常被稱作尾後迭代器(off-the-end iterator)或者簡稱為尾 迭代器(end iterator)。特殊情況下如果容器為空,貝lj begin和end返回的是同乙個迭 代器。// b表示v的第乙個元素,e表示v尾元素的下一位置
auto b = v.begin(), e = v.end(>; //b 和 e 的型別相同
如果容器為空,則begin和end返回的是同乙個迭代器,都是尾後迭代器。迭代器運算子表列舉了迭代器支援的一些運算。使用==和!=來比較兩個合法的迭代器是否相等,如果兩個迭代器指向的元素相同或者都是同乙個容器的尾後迭代器,則它們相等;否則就說這兩個迭代器不相等。和指標類似,也能通過解引用迭代器來獲取它所指示的元素,執行解引用的迭代器必須合法並確實指示著某個元素。試**引用乙個非法迭代器或 者尾後迭代器都是未被定義的行為。
舉個例子,利用下標運算子把string物件的第乙個字 付改為了大寫形式,下面利用迭代器實現同樣的功能:string s("some string");if (s .begin ()!= s • end ())
程式例子:#include#include
using std::cin;
using std::cout;
using std::vector;
using std::string;
int main(void)
cout< }
cout<
//使用下標
for(decltype(vstr.size()) in=0;in!=vstr.size();in++)
cout< }
cout<
//使用迭代器
for(auto it=vstr.begin();it!=vstr.end();it++)
cout<
cout<
return 0; }
輸出結果:
c primer 3 標準庫型別
3.1 命名空間的using宣告 using宣告是對某個命名空間做引入。主要作用是簡化 編寫。比如用cout的三種方式 using namespace std using std cout std cout 3.2 標準庫string型別 定義和初始化 include using std strin...
C Primer 學習筆記(二) 標準庫型別
一 命名空間的using指示與using宣告 1 using宣告 1 乙個using宣告一次只引入乙個命名空間成員。2 using宣告的作用域為 從using宣告點開始,直到包含該using宣告的作用域的末尾,名字都是可見的。類作用域中的using宣告侷限於被定義類的基類中定義的名字。using s...
c primer學習筆記2 標準庫型別
1 string.size 的返回值型別為string size type,而不是int,不要把size的返回值賦給乙個int變數,可能溢位 實際上很多庫型別size操作的返回值型別都是size type型別,這是一種類似unsigned int的型別 同樣在進行索引時索引值也是size type型...