程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++學習筆記(三) 迭代器

C++學習筆記(三) 迭代器

編輯:C++入門知識

迭代器
迭代器用於存取一個序列中的元素,其用法類似於指針(實際上迭代器就可以看做是泛化的指針)。不同的是,迭代器比指針更為抽象,它可以指向容器中的一個位置,而我們不必關心這個位置對應的真正物理地址。

iterator從操作方法分可分為如下5類:


Input iterator

Read, but not write; increment only

Output iterator

Write, but not read; increment only

Forward iterator

Read and write; increment only

Bidirectional iterator

Read and write; increment and decrement

Random access iterator

Read and write; full iterator arithmetic


下面的concept繼承關系圖可以更清楚的說明這5類之間的關系,越下面的迭代器,使用越靈活,操作方法也越多。

 

對於Input Iterator和output iterator,常用的實例就是流迭代器,分別是:istream_iterator和ostream_iterator。它們的構造函數如下:


istream_iterator<T> in(strm);

Create istream_iterator that reads objects

of type T from input stream strm .

istream_iterator<T> in;

Off-the-end iterator for istream_iterator .

ostream_iterator<T> in(strm);

Create ostream_iterator that writes objects

of type T to the output stream strm .

ostream_iterator<T> in(strm, delim);

Create ostream_iterator that writes objects

of type T to the output stream strm using

delim as a separator between elements.

delim is a null-terminated character array.

對於兩個輸入流迭代器,要進行相等性比較必須具有同樣的類型。如果它們都指向流結束,那麼它們相等,如果它們都沒有指向流結束,那麼它們只要指向同一個流就相等,這個特性常常被用在判斷流結束上。下面是使用輸入流迭代器的一個例子:

[cpp]  
istream_iterator<int> in_iter(cin); // read ints from cin 
istream_iterator<int> eof; // istream "end" iterator 
vector<int> vec(in_iter, eof); // construct vec from an iterator range 

向前迭代器沒有輸入輸出迭代器的對於自增操作和寫入(或讀取)操作必須交替進行的限制,它可以自由的進行讀寫操作,不過只能自增,不能自減。
雙向迭代器比向前迭代器更靈活,它在其基礎上加入了自減的操作。向map,set,list這些容器提供的都是雙向迭代器。

隨機訪問迭代器從名字上就可以看出來,它支持對容器的隨機訪問等操作,在雙向迭代器的基礎上,它還支持p+=n,p-=n,p+n,p-n,p1-p2,p1 or p2等操作。對於像string,vector,deque這些容器提供的都是隨機訪問迭代器,可以看出這些容器都是采用連續數據結構的。

以上對迭代器的劃分是按照他們的concept分類進行劃分的,實際上,我們還可以從它的使用角度上進行劃分,例如逆向迭代器。通過container.rbegin(),container.rend()這兩個容器函數可以得到容器的逆向迭代器,它的操作方式和普通的迭代器正好相反,我們可以用它們對容器進行逆向迭代。

使用逆向迭代器一定要注意它真正指向的元素,請看下面這個例子,假設有這麼一個字符串line:

FIRST,MIDDLE,LAST

現在要打印出最後一個單詞,我們可能會如此寫C++代碼:

[cpp] 
string::reverse_iterator rcomma = find(line.rbegin(), line.rend(), ','); 
cout << string(line.rbegin(), rcomma) << endl; 

但打印結果卻是:TSAL
仔細想想,這個結果是很正常的,因為逆向迭代器本來就是對容器的逆向迭代。但這可不是我們想要的,要想得到last這個打印結果,我們需要如下修改代碼:

[cpp]
cout << string(rcomma.base(), line.end()) << endl; 

調用逆向迭代器的base函數可以得到對應的正向迭代器,有些童鞋看到這裡可能會對其迭代范圍感到疑惑,因為它並沒有打印出逗號,實際上rcoma和rcoma.base()並沒有指向同一個元素,STL這樣設計的原因主要是考慮到序列的左閉右開原則,使得rcomma.base(), line.end()和line.rbegin(), rcomma指向的是同一段序列,或許下面的圖說明的更加清晰一些:

 

\
作者:justaipanda

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved