C++基礎之迭代器iterator


C++基礎之迭代器iterator

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

標准庫容器都可以使用迭代器,但是只有少數幾種才同時支持下標運算符。

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

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

使用迭代器

能夠使用迭代器的變量類型擁有返回迭代器的方法。

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

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

特殊情況下:

如果容器為空,則beginend返回的是同一個迭代器。

迭代器運算符

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

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

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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM