迭代器:訪問string物件和vector物件
我們都知道可以用下標運算來訪問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).empty();
這裡要注意*it一定要加圓括號,否則會出錯。如果不加,那麼這句話的意思就變成了訪問it的empty成員,但是it是個迭代器,沒有empty成員。C++11中提供了箭頭運算子->,箭頭運算子把解引用和成員訪問兩個操作結合在了一起。故iter->mem 等價於(*iter).mem。
強烈注意:一旦使用了迭代器的迴圈體,那就不要向迭代器所屬的容器新增元素。
迭代器的算術運算:
iter + n 迭代器加上一個整數後仍是一個迭代器,在這裡迭代器和指標很像,可以理解成地址上的加減。
iter1 - iter2 兩個迭代器相減的結果是它們之間的距離。即所指向位置的距離。
<,<=,>,>= 迭代器關係運算符,如果某迭代器指向的容器位置在另一個迭代器所指位置之前,則說前者小於後者。