我們都知道可以用下標運算來訪問string物件和vector物件。而另外還有一種更通用的方法也可以實現這樣的方法。名曰:迭代器(iterator)。
類似於指標,迭代器也提供了對物件的間接訪問。就迭代器而言,其物件是容器中的元素或者string中的字元。使用迭代器可以訪問某個元素,迭代器也能從乙個元素移動到另外乙個元素。迭代器有有效和無效之分,有效的迭代器指向某個元素或者容器中尾元素的下乙個位置。其他情況均為無效。
和指標不一樣的是,迭代器不是使用取址符,而是使用begin和end成員。
如下:auto a = v.begin(), b = v.end();
這裡的a表示v的第乙個元素,b表示v的最後乙個元素的下一位置的元素。
注:end成員返回指向容器「尾元素的下乙個位置」的迭代器,也就是說這個迭代器指示的內容是乙個根本不存在的元素,有時候也稱為尾後迭代器。這個迭代器沒有什麼實際含義,僅僅是個標記而已,表示我們已經處理完容器中的所有元素。如果容器為空,那麼begin和end返回的是同乙個迭代器。
一般來說,我們可能不清楚迭代器的型別是什麼,那麼使用auto關鍵字定義變數即可,如上面的例子就是使用這種方法。
迭代器的運算子:
*iter 返回迭代器所指向的元素的引用
iter->mem 獲取元素的成員。等價於(*iter).mem
++iter 指向容器的下乙個元素
--iter 指向容器的上乙個元素
==和!= 如果兩個迭代器指向的元素相同後者都指向同乙個容器的尾後迭代器,則相等
和指標相類似,迭代器也能夠通過接引用迭代器來獲取它所指示的元素,執行解引用的迭代器必須合法並確實指示著某個元素。試**引用乙個非法的迭代器或者尾後迭代器都是非法的行為。
下面給個例子如下:
string s(「good job」)
if(s.begin() != s.end()){ //確保s為非空的字串
auto it = s.begin(); //it表示s的第乙個字元
*it = toupper( *it ) //將字串的第乙個字元改成大寫,這裡必須要用引用,否則操作失敗
結合解引用和成員訪問操作
解引用迭代器可以獲得迭代器所指的物件,如果該物件的型別恰好是類,那麼就可以訪問這個類的成員。例如:
(*it).enpty();
這裡要注意*it一定要加圓括號,否則會出錯。如果不加,那麼這句話的意思就變成了訪問it的empty成員,但是it是個迭代器,沒有empty成員。c++11中提供了箭頭運算子->,箭頭運算子把解引用和成員訪問兩個操作結合在了一起。故iter->mem 等價於(*iter).mem。
強烈注意:一旦使用了迭代器的迴圈體,那就不要向迭代器所屬的容器新增元素。
迭代器的算術運算:
iter1 - iter2 兩個迭代器相減的結果是它們之間的距離。即所指向位置的距離。
,>= 迭代器關係運算子,如果某迭代器指向的容器位置在另乙個迭代器所指位置之前,則說前者小於後者。
C 迭代器學習筆記
1 istream iterator和ostream iterator的學習 istream iteratorin strm 其中表示輸入型別,strm為istream iterator指向的流 提供了輸入操作符 ostream iteratorout strm 輸出操作符 2.vector rev...
C 學習筆記(二) 迭代器
迭代器 每種容器都提供了若干共同工作的迭代器型別,與容器型別一樣,所有迭代器都具有相同的介面,即它們都支援某種操作 支援的操作有 iter 指向元素 iter mem 解引用 iter iter 自增 iter iter 自減 iter1 iter2 判斷相等 iter iter2 判斷不等 vec...
c 學習筆記之迭代器
vector迭代器持續有效,除非 1.使用著在較小的索引位置插入或者刪除元素。2.由於容量的變化引起的記憶體重新分配。list迭代器失效 1.將it指向的元素刪除,那麼it則失效 2.用erase刪除元素記得接收返回值,同時最好使用while迴圈。順序容器用乙個容器去初始化另乙個容器,以及用迭代器範...