c 學習筆記(七) 再談迭代器

2021-06-23 06:26:45 字數 4299 閱讀 9765

容器一般都會提供乙個迭代器,用於跟蹤元素操作。  但是其實,標準庫所定義的迭代器不依賴於特定的容器。 而容器所提供的迭代器也只是,標準庫提供的一下三種迭代器的一種:

1 插入迭代器:  這類迭代器與容器繫結在一起,實現在容器中插入元素的功能

2 iostream 迭代器: 這類迭代器可與輸入或輸出流繫結在一起, 用於迭代遍歷所關聯的io流

3 反向迭代器: 這類迭代器實現向後遍歷, 而不是向前遍歷。  

所有的容器都定義了自己的reverse_iterator 型別,由

rbegin 和 rend

成員函式返回。

迭代器的使用 都在iterator標頭檔案中定義。

下面介紹,如何在泛型演算法中 使用這些迭代器,  並如何利用const_iterator容器。以及總結5中迭代器。 1 

插入迭代器:

一般有三種插入迭代器:

back_inserter  建立使用push_back實現插入的迭代器

front_inserter 使用push_front實現插入

這兩個迭代器,都是接受乙個容器實參的。

inserter  使用inserter 實現插入操作。  除了所關聯的容器外,還接受第二個實參, 指向插入起始位置的迭代器。

它們的用法:

front_inserter與back_inserter的用法相同,都是在指定的地方插入元素

inserter將產生在指定位置實現插入的迭代器:

list::iterator it = find(ilst.begin(), ilst.end(), 42):

replace_copy(ivec.begin(), ivec.end(), inserter(ilst, it), 100, 0);

這段**的含義是: 在ilst中 在第乙個出現42的地方,插入ivec中begin到end之間的元素,並將這一段元素中的100替換為0。

inserter迭代器和copy及replace演算法結合的用處是 ,  將乙個容器中的元素插入到另乙個容器中,並實現是否替換功能。 2 

iostream 迭代器

雖然iostream 不是容器。  但同樣提供了迭代器:

istream_iterator 用於讀取輸入流, 而ostream_iterator 則用於寫輸出流。   這些迭代器將它們所對應的流視為特定型別的元素序列。 

使用流迭代器時,可以用泛型演算法從流物件中讀資料(或將資料寫到流物件中)。

iostream 迭代器的建構函式:

istream_iteratorin(strm);  表示從輸入流strm中讀取t型別物件的istream_iterator物件。  

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

ostream_iteratorin(strm);  解釋同istream_iterator

ostream_iteratorin(strm, delim);  建立t型別的物件寫到輸出流strm的ostream_iterator 物件, 在寫入過程中使用delim作為元素的分隔符。delim是以空字元結束的字元陣列。

流迭代器只定義了最基本的迭代器操作:自增、解引用和賦值。  此外,還提供了一些比較運算(相等或不等, 輸出流則沒有提供此類操作)。

流迭代器的定義:

流迭代器都是類模板, 任何已定義的輸入輸出操作符(如》)的型別(如cin)都可以定義 istream_iterator, 類似地可以定義ostream_iterator。

在建構函式中的空格符必須是c風格字串,因此該字串必須以空字元結束, 否則, 其行為將是未定義的。

istream_iterator物件上的操作:

舉個例子,便一目了然:

istream_iteratorin_iter(cin);

istream_iteratoreof;

while(in_iter!=eof)

vec.push_back(*in_iter++);

其中while迴圈如何結束。  在這裡,cin輸入流是通過關聯檔案或輸入來獲得的,  當到達檔案結尾或 輸入的不是int 型數值 時, while停止。

ostream_iterator物件和 ostream_iterator物件的使用:

可使用ostream_iterator物件將乙個值序列寫入流中, 其操作的過程與使用迭代器將一組值逐個賦給容器中的元素相同:

ostream_iteratorin_iter(cout, "\n");  表面以回車為間隔

istream_iteratorin_iter(cin), eof;

while(in_iter != eof)

看到這裡,想到了檔案輸入輸出操作,貌似有幾分類似:

ifstream infile;

infile.open("in");

ofstream outfile;

oufile.open("out");

即他們都要先申明是輸入還是輸出,  然後再繫結某乙個檔案/流。

在類型別上使用 istream_iterator

輸出的流迭代器的解引用會立即 輸出到指定的輸數流上 或者螢幕或者文字。

即利用類模板的性質, 流迭代器指向的元素和解引用的值都是該類型別。 然後 就可以通過流迭代器找到 該類的元素,通過該元素呼叫該類的成員。

一定要把流迭代器,想成存放很多輸入輸出的元素容器。

流迭代器的限制:

1 不可能從 ostream_iterator物件讀入, 也不可能寫到 istream_iterator物件中

2  一旦給ostream_iterator 物件賦乙個值, 寫入就提交了。 賦值後, 沒有辦法再改變這個值。

3 ostream_iterator沒有->操作符

與演算法一起使用流迭代器:

演算法是基於迭代器操作實現的。

流迭代器至少定義了一些迭代器操作。  由於流迭代器支援迭代器操作, 因此,至少可在一些泛型演算法上使用這類迭代器。

反向迭代器:

反向迭代器的使用與迭代器的使用完全是反過來的, 它通過定義一對反向迭代器(rbegin 和 rend)成員來完成。

這樣如果降序來排列vector, 只需向sort傳遞一對反向迭代器。

反向迭代器與其它迭代器之間的關係:

如果要取出一行中  最後乙個單詞(這些單詞以逗號分隔開)

則 用反向迭代器查詢 最後乙個冒號(即方向的第乙個冒號) 比較方便。

然後利用 line.rbegin(), rcomma之間的單詞。  但是這樣的輸出會導致 輸出的單詞字母都是顛倒的。    因此,為了糾正這個問題,我們必須把 rbegin() 和 rcomma轉換為普通迭代器 ,然後再進行輸出:

其實,沒必要轉換line.rbegin(), 因為它必定對應的是 line.end(), 而對於rcomma, 只需呼叫多有反向迭代器型別都提供的成員函式 base 來 轉換 rcomma即可。

const迭代器:

當我們不希望對迭代器的位址進行修改時, 可以使用它。  當用一些接受一對迭代器的演算法或操作時, 必須使用匹配的const迭代器。

五種迭代器:

迭代器定義了常用的操作集, 但有些迭代器具有比其他迭代器更強大的功能。 例如, ostream_iterator 只支援自增、解引用和賦值運算。 而vector除了提供這些操作外,還提供自減、關係和算術運算。 因此,可以對迭代器進行分類。

類似地,  還可根據演算法要求它的迭代器提供什麼型別的操作, 對演算法進行分類。例如,find 只要求迭代器提供讀取所指向內容和自增的功能。 另一些演算法,如sort 則要求其迭代器有讀、寫和隨機訪問元素的功能。

迭代器種類: 

輸入迭代器:  讀, 不能寫,只支援自增運算  

還支援  相等和不等操作符,  解引用操作符,  箭頭操作符

輸出迭代器: 寫,不能讀, 只支援自增運算

還支援解引用, 而且每個迭代器的值必須正好輸入一次,只能解引用一次。  一般用作演算法的第三個實參。

前向迭代器: 讀和寫, 只支援自增運算

以乙個方向遍歷序列, 可以對同乙個元素多次讀寫。 可複製前向迭代器來記錄序列中的乙個位置。 需要前向迭代器的泛型演算法包括  replace

雙向迭代器:  讀和寫, 支援自增和自減運算

從兩個方向讀寫容器。雙向迭代器包括前向迭代器的所有操作,除此之外, 還包括自減運算。

隨機訪問迭代器:  讀和寫, 支援完整的迭代器算術運算

需要低階類別迭代器的地方,可使用任意一種更高階的迭代器。  對於需要輸入迭代器的演算法, 可傳遞前向、雙向或隨機訪問迭代器呼叫該演算法。

呼叫需要隨機訪問迭代器的演算法是,必須傳遞隨機訪問迭代器。

map和 set  關聯容器的鍵是const物件,因此,關聯容器不能使用任何寫序列元素的演算法。  只能使用與關聯容器綁在一起的迭代器來提供用於讀操作的實參。

再談迭代器

一 插入迭代器 1 2解釋三種插入迭代器的區別。3區別在於插入的元素的位置不同 4back inserter,使用push back實現在容器末端插入。5front inserter,使用push front實現在容器前端插入。6inserter,使用insert實現插入,它還帶有第二個實參 指向插...

C 迭代器學習筆記

1 istream iterator和ostream iterator的學習 istream iteratorin strm 其中表示輸入型別,strm為istream iterator指向的流 提供了輸入操作符 ostream iteratorout strm 輸出操作符 2.vector rev...

C 學習筆記 迭代器

我們都知道可以用下標運算來訪問string物件和vector物件。而另外還有一種更通用的方法也可以實現這樣的方法。名曰 迭代器 iterator 類似於指標,迭代器也提供了對物件的間接訪問。就迭代器而言,其物件是容器中的元素或者string中的字元。使用迭代器可以訪問某個元素,迭代器也能從乙個元素移...