1. 程式人生 > >C++標準模板庫---迭代器介紹(iterator、const_iterator)

C++標準模板庫---迭代器介紹(iterator、const_iterator)

迭代器

概念:C++的一種機制,用來遍歷標準模板庫容器中的元素,是一種"智慧"指標

一、迭代器的特點

  • 迭代器是一種智慧指標,具有遍歷複雜資料結構的能力
  • 不同的容器有不一樣的內部結構,因此會有一樣的迭代器型別
  • 迭代器定義後,並不屬於某一例項容器物件,只要是屬於該迭代器型別的容器型別都可用

二、迭代器的使用

1.原理:迭代器定義之後,可指向指定型別容器內的元素,從而達到訪問容器內元素的能力

2.用法

  • 關鍵字interator代表宣告一個迭代器,前面需要指明型別
  • 迭代器指向容器的某一位置
  • 通過*解引用獲取元素的引用(注:*得到的是元素的引用)。也可用->得到該元素的成員(下面程式碼會介紹)
string s= "HelloWorld";
string::iterator i; //一個string型別的迭代器
for (i = s.begin(); i != s.end(); i)
{
    cout << *i;
}

3.解引用和成員訪問

注意:訪問成員時,要對迭代器加上(),否則產生的意義不同

(*item).empty(); //正確用法
*item.empty; //錯誤用法

 上面程式碼中:第一行是解引用迭代器。而第二種是試圖訪問item中的empty成員,但是item是個迭代器,顯示是錯誤的

三、begin()、end()

1.概念:

begin()、end()代表容器的特殊位置,分別為元素的第一個位置與最後一個元素的下一個位置

  • 下面比如是vector的一個模型,則begin()、end()分別代表一下位置

2.為什麼要這樣設計?

  • begin():我們在遍歷容器的元素的時候,一般要獲取該元素的首元素,因此設計bengin()
  • end():當我們用迭代器遍歷容器的時候,一般需要結束條件(如遍歷到最後一個元素),但是遍歷到最後一個元素時又不能捨棄它,因此將最後一個元素的下一位置作為結束標誌

3.提醒

C++11新標準中cbegin()、cend()會在下面介紹

四、interator、const_iterator關鍵字

1.迭代器的核心關鍵字

2.分類

  • interator:當我們需要對容器元素進行修改、刪除等操作時或者物件是非常量時使用
  • const_iterator:當我們只是遍歷容器元素,而不更改容器元素時或者物件是常量時使用

注意:上面所說的常量是指常量容器,而不是容器內的元素為常量

3.兩者的選擇

  • 建議:如果我們只是簡單的遍歷容器元素或者物件是常量時,一般使用const_iterator比較合適

4.C++11新標準:cbegin()、cend()

C++11引進了兩個新函式,分別為cbegin()、cend(),其兩者的功能類似於begin()、end()

  • C++11新標準之前,iterator與const_iterator都使用begin()、end()兩個輔助函式遍歷容器。
  • C++新標準之後,const_iterator既可以使用可以使用begin()、end(),也可以使用cbegin()、cend()。但是iterator還是隻能使用begin()、end()
vector<int> v;
const vector<int> v2;
auto it1=v.begin(); //v1是vector<int>::iterator型別
auto it2=v2.brgin();//v2是vector<int>::const_iterator型別

五、迭代器的運算

說明:迭代器的運算子一般都是對迭代器所指元素的位置進行比較,返回的是比較結果或者改變迭代器的位置

迭代器沒有+運算

例如有迭代器iter,iter1,iter2

*iter  返回迭代器所指元素的引用
iter->data  代表當前所指位置處元素的的指標,可以訪問其函式或成員,等價於(*iter).data
++iter  令迭代器指向容器的下一個元素
--iter  令迭代器指向容器的前一個元素
iter1==iter2  判斷兩個迭代器的位置是否相同
iter1!=iter2  同上
>、>=、<、<=    同上

iter + n  改變迭代器的位置
iter - n  同上
iter +=n  同上
iter -=n  同上
iter1 - iter2  兩個迭代器相減,返回它們之間的距離
  • 例項:遍歷vector中的元素,如果遇到空白,停止遍歷 
vector<string> v = {"Hello","fwe",""};
vector<string>::iterator iter;
for (iter = v.begin(); iter != v.end() && !iter->empty(); ++iter)
{
    cout << *iter<<"\t";
}

六、一些程式碼事例

  • 將string中的第一個字元改為大寫
string s = "helloWorld";
string::iterator it;
if (s.begin() != s.end())//先判斷s不為空
{
    it = s.begin();
    *it = toupper(*it);
}
  • 使用容器元素的函式
(*item).empty(); //判斷是否為空
(*item).size(); //得到大小
  • 得到中間元素的迭代器
auto mid=v.begin()+vi.size()/2;
  • 折半查詢string中的一個元素
string s = "abcdefghj";
char foundChar = 'e';
string::const_iterator l_iter=s.begin();
string::const_iterator r_iter=s.end();
string::const_iterator mid_iter = s.begin() + (r_iter - l_iter) / 2;
while (mid_iter != r_iter && *mid_iter != foundChar)
{
    if (*mid_iter > foundChar)
    {
        r_iter = mid_iter;
    }
    else
    {
        l_iter = mid_iter + 1;
    }
    mid_iter = l_iter + (r_iter - l_iter) / 2;
}
cout << *mid_iter << endl;