久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C++ 迭代器 基礎(chǔ)介紹

 Fredanf 2012-11-28

C++ 迭代器 基礎(chǔ)介紹

迭代器提供對一個(gè)容器中的對象的訪問方法,,并且定義了容器中對象的范圍,。迭代器就如同一個(gè)指針。事實(shí)上,,C++的指針也是一種迭代器,。但是,迭代器不僅僅是指針,,因此你不能認(rèn)為他們一定具有地址值,。例如,一個(gè)數(shù)組索引,,也可以認(rèn)為是一種迭代器,。

除了使用下標(biāo)來訪問 vector 對象的元素外,標(biāo)準(zhǔn)庫還提供了另一種訪問元素的方法:使用迭代器(iterator),。迭代器是一種檢查容器內(nèi)元素并遍歷元素的數(shù)據(jù)類型,。

標(biāo)準(zhǔn)庫為每一種標(biāo)準(zhǔn)容器(包括 vector)定義了一種迭代器類型。迭代器類型提供了比下標(biāo)操作更通用化的方法:所有的標(biāo)準(zhǔn)庫容器都定義了相應(yīng)的迭代器類型,,而只有少數(shù)的容器支持下標(biāo)操作,。因?yàn)榈鲗λ械娜萜鞫歼m用,現(xiàn)代 C++ 程序更傾向于使用迭代器而不是下標(biāo)操作訪問容器元素,,即使對支持下標(biāo)操作的 vector 類型也是這樣,。

容器的 iterator 類型

每種容器類型都定義了自己的迭代器類型,如 vector

     vector<int>::iterator iter;

這符語句定義了一個(gè)名為 iter 的變量,它的數(shù)據(jù)類型是 vector<int> 定義的 iterator 類型,。每個(gè)標(biāo)準(zhǔn)庫容器類型都定義了一個(gè)名為 iterator 的成員,,這里的 iterator 與迭代器實(shí)際類型的含義相同。

術(shù)語:迭代器和迭代器類型

程序員首次遇到有關(guān)迭代器的術(shù)語時(shí)可能會(huì)困惑不解,,原因之一是由于同一個(gè)術(shù)語 iterator 往往表示兩個(gè)不同的事物,。一般意義上指的是迭代器的概念;而具體而言時(shí)指的則是由容器定義的具體的 iterator 類型,,如 vector<int>,。

重點(diǎn)要理解的是,有許多用作迭代器的類型,,這些類型在概念上是相關(guān)的,。若一種類型支持一組確定的操作(這些操作可用來遍歷容器內(nèi)的元素,并訪問這些元素的值),,我們就稱這種類型為迭代器,。

各容器類都定義了自己的 iterator 類型,用于訪問容器內(nèi)的元素,。換句話說,,每個(gè)容器都定義了一個(gè)名為 iterator 的類型,而這種類型支持(概念上的)迭代器的各種操作,。

begin end 操作

每種容器都定義了一對命名為 begin end 的函數(shù),,用于返回迭代器。如果容器中有元素的話,,由 begin 返回的迭代器指向第一個(gè)元素:

     vector<int>::iterator iter = ivec.begin();

上述語句把 iter 初始化為由名為 vector 操作返回的值,。假設(shè) vector 不空,,初始化后,,iter 即指該元素為 ivec[0]

end 操作返回的迭代器指向 vector 的“末端元素的下一個(gè)”,?!俺瞿┒说鳌保?span lang="EN-US">off-the-end iterator)。表明它指向了一個(gè)不存在的元素,。如果 vector 為空,,begin 返回的迭代器與 end 返回的迭代器相同。

 

end 操作返回的迭代器并不指向 vector 中任何實(shí)際的元素,,相反,,它只是起一個(gè)哨兵(sentinel)的作用,表示我們已處理完 vector 中所有元素,。

vector 迭代器的自增和解引用運(yùn)算

迭代器類型定義了一些操作來獲取迭代器所指向的元素,,并允許程序員將迭代器從一個(gè)元素移動(dòng)到另一個(gè)元素。

迭代器類型可使用解引用操作符(dereference operator)(*)來訪問迭代器所指向的元素:

     *iter = 0;

解引用操作符返回迭代器當(dāng)前所指向的元素。假設(shè) iter 指向 vector 對象 ivec 的第一元素,,那么 *iter ivec[0] 就是指向同一個(gè)元素,。上面這個(gè)語句的效果就是把這個(gè)元素的值賦為 0

迭代器使用自增操作符向前移動(dòng)迭代器指向容器中下一個(gè)元素,。從邏輯上說,,迭代器的自增操作和 int 型對象的自增操作類似。對 int 對象來說,,操作結(jié)果就是把 int 型值“加 1”,,而對迭代器對象則是把容器中的迭代器“向前移動(dòng)一個(gè)位置”。因此,,如果 iter 指向第一個(gè)元素,,則 ++iter 指向第二個(gè)元素。

由于 end 操作返回的迭代器不指向任何元素,,因此不能對它進(jìn)行解引用或自增操作,。

迭代器的其他操作

另一對可執(zhí)行于迭代器的操作就是比較:用 == != 操作符來比較兩個(gè)迭代器,如果兩個(gè)迭代器對象指向同一個(gè)元素,,則它們相等,,否則就不相等。

迭代器應(yīng)用的程序示例

假設(shè)已聲明了一個(gè) vector<int> 型的 ivec 變量,,要把它所有元素值重置為 0,,可以用下標(biāo)操作來完成:

   // reset all the elements in ivec to 0

   for (vector<int>::size_type ix = 0; ix != ivec.size(); ++ix)

             ivec[ix] = 0;

上述程序用 for 循環(huán)遍歷 ivec 的元素,for 循環(huán)定義了一個(gè)索引 ix ,,每循環(huán)迭代一次 ix 就自增 1,。for 循環(huán)體將 ivec 的每個(gè)元素賦值為 0

更典型的做法是用迭代器來編寫循環(huán):

   // equivalent loop using iterators to reset all the elements in ivec to 0

for (vector<int>::iterator iter = ivec.begin();iter != ivec.end(); ++iter)

         *iter = 0;  // set element to which iter refers to 0

 

for 循環(huán)首先定義了 iter,,并將它初始化為指向 ivec 的第一個(gè)元素,。for 循環(huán)的條件測試 iter 是否與 end 操作返回的迭代器不等。每次迭代 iter 都自增 1,,這個(gè) for 循環(huán)的效果是從 ivec 第一個(gè)元素開始,,順序處理 vector 中的每一元素。最后,, iter 將指向 ivec 中的最后一個(gè)元素,,處理完最后一個(gè)元素后,iter 再增加 1,,就會(huì)與 end 操作的返回值相等,,在這種情況下,循環(huán)終止,。

for 循環(huán)體內(nèi)的語句用解引用操作符來訪問當(dāng)前元素的值,。和下標(biāo)操作符一樣,解引用操作符的返回值是一個(gè)左值,因此可以對它進(jìn)行賦值來改變它的值,。上述循環(huán)的效果就是把 ivec 中所有元素都賦值為 0,。

通過上述對代碼的詳細(xì)分析,可以看出這段程序與用下標(biāo)操作符的版本達(dá)到相同的操作效果:從 vector 的第一個(gè)元素開始,,把 vector 中每個(gè)元素都置為 0,。

本節(jié)給出的例子程序,如果 vector 為空,,程序是安全的,。如果 ivec 為空,則 begin 返回的迭代器不指向任何元素——由于沒有元素,,所以它不能指向任何元素,。在這種情況下,從 begin 操作返回的迭代器與從 end 操作返回的迭代器的值相同,,因此 for 語句中的測試條件立即失敗,。

const_iterator

前面的程序用 vector::iterator 改變 vector 中的元素值。每種容器類型還定義了一種名為 const_iterator 的類型,,該類型只能用于讀取容器內(nèi)元素,,但不能改變其值。

當(dāng)我們對普通 iterator 類型解引用時(shí),,得到對某個(gè)元素的非 const2.5 節(jié)),。而如果我們對 const_iterator 類型解引用時(shí),則可以得到一個(gè)指向 const 對象的引用(2.4 節(jié)),,如同任何常量一樣,,該對象不能進(jìn)行重寫。

例如,,如果 text vector<string> 類型,,程序員想要遍歷它,輸出每個(gè)元素,,可以這樣編寫程序:

   // use const_iterator because we won't change the elements

  for (vector<string>::const_iterator iter = text.begin();iter != text.end(); ++iter)

  cout << *iter << endl; // print each element in text

除了是從迭代器讀取元素值而不是對它進(jìn)行賦值之外,,這個(gè)循環(huán)與前一個(gè)相似。由于這里只需要借助迭代器進(jìn)行讀,,不需要寫,這里把 iter 定義為 const_iterator 類型,。當(dāng)對 const_iterator 類型解引用時(shí),,返回的是一個(gè) const 值。不允許用 const_iterator: 進(jìn)行賦值

     for (vector<string>::const_iterator iter = text.begin();iter != text.end(); ++ iter)

      *iter = " ";     // error: *iter is const

 

使用 const_iterator 類型時(shí),,我們可以得到一個(gè)迭代器,,它自身的值可以改變,但不能用來改變其所指向的元素的值??梢詫Φ鬟M(jìn)行自增以及使用解引用操作符來讀取值,,但不能對該元素賦值。

不要把 const_iterator 對象與 const iterator 對象混淆起來,。聲明一個(gè) const 迭代器時(shí),,必須初始化迭代器。一旦被初始化后,,就不能改變它的值:

  vector<int> nums(10);  // nums is nonconst

  const vector<int>::iterator cit = nums.begin();

  *cit = 1;  // ok: cit can change its underlying element

   ++cit;  // error: can't change the value of cit

const_iterator 對象可以用于 const vector 或非 const vector,,因?yàn)椴荒芨膶懺刂怠?span lang="EN-US">const 迭代器這種類型幾乎沒什么用處:一旦它被初始化后,只能用它來改寫其指向的元素,,但不能使它指向任何其他元素,。

  const vector<int> nines(10, 9);  // cannot change elements in nines

  // error: cit2 could change the element it refers to and nines is const

  const vector<int>::iterator cit2 = nines.begin();

  // ok: it can't change an element value, so it can be used with a const vector<int>

  vector<int>::const_iterator it = nines.begin();

  *it = 10; // error: *it is const

  ++it;     // ok: it isn't const so we can change its value

   // an iterator that cannot write elements

   vector<int>::const_iterator

   // an iterator whose value cannot change

   const vector<int>::iterator

迭代器的算術(shù)操作

除了一次移動(dòng)迭代器的一個(gè)元素的增量操作符外,vector 迭代器(其他標(biāo)準(zhǔn)庫容器迭代器很少)也支持其他的算術(shù)操作,。這些操作稱為迭代器算術(shù)操作(iterator arithmetic),,包括:

iter + n

iter - n

可以對迭代器對象加上或減去一個(gè)整形值。這樣做將產(chǎn)生一個(gè)新的迭代器,,其位置在 iter 所指元素之前(加)或之后(減) n 個(gè)元素的位置,。加或減之后的結(jié)果必須指向 iter 所指 vector 中的某個(gè)元素,或者是 vector 末端的后一個(gè)元素,。加上或減去的值的類型應(yīng)該是 vector size_type difference_type 類型(參考下面的解釋),。

iter1 - iter2

該表達(dá)式用來計(jì)算兩個(gè)迭代器對象的距離,該距離是名為 difference_type signed 類型 size_type 的值,,這里的 difference_type signed 類型,,因?yàn)闇p法運(yùn)算可能產(chǎn)生負(fù)數(shù)的結(jié)果。該類型可以保證足夠大以存儲(chǔ)任何兩個(gè)迭代器對象間的距離,。iter1 iter2 兩者必須都指向同一 vector 中的元素,,或者指向 vector 末端之后的下一個(gè)元素。

可以用迭代器算術(shù)操作來移動(dòng)迭代器直接指向某個(gè)元素,,例如,,下面語句直接定位于 vector 中間元素:

 vector<int>::iterator mid = vi.begin() + vi.size() / 2;

上述代碼用來初始化 mid 使其指向 vi 中最靠近正中間的元素。這種直接計(jì)算迭代器的方法,,與用迭代器逐個(gè)元素自增操作到達(dá)中間元素的方法是等價(jià)的,,但前者的效率要高得多。

任何改變 vector 長度的操作都會(huì)使已存在的迭代器失效,。例如,,在調(diào)用 push_back 之后,就不能再信賴指向 vector 的迭代器的值了,。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多