C 學習之迭代器

2021-06-21 01:42:02 字數 3777 閱讀 4028

c++標準庫中的3個重要概念就是容器,迭代器,演算法,標準庫中的常用容器有vector,list,deque,map,set,multimap,multiset(c++11中新增了array,forward_list,unordered_map,unordered_set,unordered_multimap,unordered_multiset),這些容器大家都經常用到,相對比較熟悉。但是使用c++,就必須得熟悉其提供給我們的100多個泛型演算法(參見c++學習之標準庫泛型演算法_stl演算法

),這樣我們就可以避免重複造輪子。泛型演算法不是呼叫容器已有的操作實現,而是借助於迭代器來實現,所以呼叫泛型演算法的時候,我們需要傳遞迭代器引數來指明輸入範圍和輸出範圍,所以在學習泛型演算法之前,必須先了解迭代器的概念,型別等。

下面是我在看了c++primer第11章泛型演算法後自己的理解:

一、什麼是迭代器?

我的理解是迭代器提供了一種遍歷容器內元素的方法,比如遍歷陣列可以通過指標實現,指標就可以認為是一種迭代器,可以參見c++ primer的p84 。

二、迭代器種類

1.從迭代器的型別上對迭代器分類

(1)普通迭代器:就是我們經常使用的 容器::iterator,比如std::vector::iterator,一般都支援++、--操作,其他算術操作看具體的容器型別;

(2)反向迭代器:這一種迭代器也是經常用到的,比如std::list::reverse_iterator,一般都支援++、--操作,其他算術操作看具體的容器型別;

反向迭代器的通過使用普通迭代器的自減操作實現的,所以從乙個支援--同時也支援++的迭代器就可以定義反向迭代器

*上面兩種型別的迭代器都有相應的const迭代器,const迭代器不能修改其指向的元素,比如std::list::const_iterator,std::list::const_reverse_iterator,const迭          代器類似於const int* p。

(3)流迭代器:輸入輸出流不是容器,但是標準庫將它看作了」容器「,流迭代器只支援向前遍歷(++)這是流的特點決定的,因此流迭代器不能建立反向迭代器。流迭代器分為了istream_iterator和ostream_iterator,分別用於遍歷輸入、輸出流,並且我們只能從istream_iterator讀入輸入流的內容,通過ostream_iterator寫出到輸出流。

istream_iterator提供的操作

it1==it2 比較兩個迭代器是否相同。

it1!=it2  如果兩個都指向end,那麼it1==it2;如果均不指向end,且由同乙個輸入流構造,那麼也相等。

比較運算子必須是 讀取相同型別的兩個流迭代器

*it  返回從流中讀取的值,作為右值使用

it->v  或 (*it).v 返回讀取物件的成員v

++it 

it++

ostream_iterator 只提供*it (作為左值使用),++it ,it ++,不提供比較和成員選擇操作。

流迭代器的建構函式

istream_iteratorin(stream)    建立從輸入流stream讀入t型別物件的 istream_iterator物件

istream_iteratorin                   istream_iterator物件的超出末端迭代器

ostream_iteratorout(stream)    建立將t型別物件寫出到輸出流stream的ostream_iterator物件,可以指名輸出時的分隔符,如下

ostream_iteratorout(stream,delim)  

*ostream_iterator 不提供比較函式,所以就沒必要定義其對應的超出末端的迭代器了

任何定義了輸入操作符(>>)的型別都能定義都可以定義 istream_iterator,同時任何定義了輸出操作符(<

下面是流迭代器的例子        

//將input.txt 內容拷貝到output.txt,以換行符分隔輸出

ifstream filein("input.txt");

istream_iteratoriit(filein);

istream_iteratoreof;

ofstream fileout("output.txt");

ostream_iteratoroit(fileout,"\n");

copy(iit,eof,oit);

fileout.clear();

fileout.close();

filein.clear();

filein.close();

(4)插入迭代器:插入迭代器實際是迭代器介面卡,它又分為了首插入迭代器、尾插入迭代器、指定位置插入迭代器,即front_inserter,back_inserter,inserter.

介面卡的概念可以參見這裡插入介面卡,帶有乙個容器形參,並生成乙個在此容器上的乙個迭代器,用於向容器中插入元素,首插入迭代器、尾插入迭代器、指定位置插入迭代器的位置分別是容器首部、超出末端第乙個位置、指定位置,(c++stl插入的意思是在指定位置前新增元素),並且在多次使用某個插入迭代器的時候,其位置永遠是容器首部、尾部、指定的位置。比如下面的**:

#include#include#include#includeint main(int argc,char**argv)

//vint1 0,1,2,3,4

//vint2 5,6,7,8,9

//使用inserter vint1 copy到 vint2的7的前面

//結果 5 6 0 1 2 3 4 7 8 9

std::copy(vint1.begin(),vint1.end(),std::inserter(vint2,std::find(vint2.begin(),vint2.end(),7)));

for(std::list::iterator it=vint2.begin();it!=vint2.end();++it)

std::cout<

std::cout<::iterator it="vint2.begin();it!=vint2.end();++it)

std::cout<

std::cout值得注意的是front_inserter,back_inserter,inserter分別調應其引數型別容器的push_front,push_back,insert操作,所以得要求容器具有相應的操作才行,比如不能在vector上構造front_inserter。

2.通過stl中泛型演算法對迭代器引數型別的要求對迭代器分類

(1)輸入迭代器  唯讀(一次),不寫,支援自增 ,如istream_iterator

(2)輸出迭代器  只寫(一次),不讀,支援自增,如ostream_iterator

(3)前向迭代器  支援同一元素的多次讀寫

(4)雙向迭代器  從兩個方向讀寫,如list::iterator

(5)隨機訪問迭代器   在常量時間內讀寫任意位置, vector,deque,string可以提供,常用的指標也是。

這幾種迭代器具有層次結構(具體層次結構請參見c++學習之深入理解迭代器),下層具有上層的功能,並且新增了新增一些額外的操作,如下圖。

注意:所有標準庫提供的迭代器都至少達到雙向迭代器的要求;

由於關聯容器map,set的鍵是const型別,不能寫入,所以將關聯容器的迭代器視為支援自減運算的輸入迭代器,而不是完整的雙向迭代器;

演算法中用於標記範圍的一對迭代器必須是同種型別。

c 學習筆記之迭代器

vector迭代器持續有效,除非 1.使用著在較小的索引位置插入或者刪除元素。2.由於容量的變化引起的記憶體重新分配。list迭代器失效 1.將it指向的元素刪除,那麼it則失效 2.用erase刪除元素記得接收返回值,同時最好使用while迴圈。順序容器用乙個容器去初始化另乙個容器,以及用迭代器範...

C 迭代器之 反向迭代器

反向迭代器 reverse iterator 是普通迭代器的介面卡,通過重新定義自增和自減操作,以達到按反序遍歷元素的目的。如果在標準演算法庫中用反向迭代器來代替普通的迭代器,那麼執行結果與正常情況下相反。除此之外,其用法與普通迭代器完全一樣,我們不作詳細討論。這裡主要討論的是反向迭代器的乙個很特殊...

C 之 迭代器

迭代器是一種檢查容器內元素並遍歷元素的資料型別。c 一般趨向於使用迭代器而不是下標操作。每種容器都定義了自己的迭代器型別,例如vector vector iterator iter 定義乙個名為iter的迭代器迭代器的初始化 vector ivec vector iterator iter1 ive...