C++基礎之迭代器iterator

C++基礎之迭代器iterator

咱們已經知道可使用下標運算符來訪問string對象的字符或vector對象的元素,還有另外一種更通用的機制也能夠實現一樣的目的,這就是迭代器(iterator)算法

標準庫容器均可以使用迭代器,可是隻有少數幾種才同時支持下標運算符。指針

相似於指針類型,迭代器也提供了對對象的間接訪問。就迭代器而言,其對象是容器中的元素或者string對象中的字符。使用迭代器能夠訪問某一個元素,迭代器也能從一個元素移動到另一個元素。迭代器和指針同樣,有無效和有效的區別。code

有效的迭代器指向元素或者尾元素的下一個位置,其餘狀況都屬於無效的迭代器。對象

使用迭代器

可以使用迭代器的變量類型擁有返回迭代器的方法。get

begin()方法負責返回指向第一個元素的迭代器
end()方法負責返回指向容器尾元素的下一個位置的迭代器string

// b表示v的第一個元素,e表示v尾元素的下一個位置
auto b = v.begin(), e = v.end(); // b和e的類型相同

特殊狀況下:it

若是容器爲空,則beginend返回的是同一個迭代器。table

迭代器運算符

運算符 含義
*iter 返回迭代器iter所指元素的引用
iter->mem 解引用iter並獲取該元素的名爲mem的成員,等價於*(iter).mem
++iter 令iter指向容器中的下一個元素
--iter 令iter指向元素中的上一個元素
iter1 == iter2 判斷兩個迭代器是否相等

這使得迭代器就想下標同樣的好用,好比:class

string s("come thing");
if (s.begin() != s.end()) {
    auto it = s.begin();
    *it = toupper(*it);
}

迭代器類型

就想不知道stringvectorsite_type成員究竟是什麼類型同樣,通常來講咱們也不知道迭代器的精確類型。而實際上,那些擁有迭代器的標準庫類型都會使用iteratorconst_iterator來表示迭代器的類型:容器

vector<int>::iterator it; // it能表明vector<int>的元素
string::iterator it2;       // it2能表明string對象中的元素

vector<int>::const_iterator it3; // it3只能表明讀元素,不能表明寫元素
string::const_iterator it4;     // it4只能讀字符,不能寫字符,即改變字符的值

const_iterator和常量指針差很少,能讀取但不能修改他所指元素的值。

若是vector對象或string對象是一個常量,只能使用const_iterator

結合解引用和成員訪問操做

解引用能夠得到迭代器所指的對象,若是該對象的類型剛好是個類,就有可能進一步訪問他的成員。例如:

vector<string> strs = {"string", "", "tingyugetc"};
for (auto it = strs.begin(); it != strs.end() ; ++it) {
    if (it->empty()) {
        cout << "now is in empty string" << endl;
    }
}

上述的代碼中使用了箭頭運算符, 箭頭運算符將解引用和成員訪問兩個操做結合在一塊兒,他的做用和(*it).empty()相同。

(*it).empty()的圓括號必不可少,其含義是先執行括號內的解引用,接着解引用的結果在執行點運算符。若是不加括號,那麼點運算符將由it執行,而不是it解引用的結果。

迭代器失效

某些對vector對象的操做會使迭代器失效.
謹記,但凡使用了迭代器的循環體,都不要想迭代器所屬的容器添加元素

迭代器的運算

迭代器的遞增運算令迭代器每次移動一個元素,全部的標準庫都有支持遞增運算符的迭代器。相似的,也能用==!=對任意標準庫類型的兩個有效迭代器進行比較。

一樣的,能夠令迭代器和一個整數值相加或相減,其返回值是向前或向後移動了若干個位置的迭代器,執行這樣的操做時,結果迭代器要麼指向原vector對象內的一個元素要麼指向尾元素的下一個位置。
好比,能夠這樣:

// 計算獲得最接近vi中間元素的一個迭代器
auto mid = vi.begin() + vi.size() / 2;

使用迭代器運算的一個經典算法是二分搜索。

auto beg = text.begin(), end = text.end();
auto mid = beg + (end - beg) / 2;
while (mid != end && *mid != found) {
    if (found < *mid) {
        end = mid;
    } else {
        beg = mid + 1;
    }
    mid = beg + (end - beg) / 2;
}
相關文章
相關標籤/搜索