C++中的迭代器(STL迭代器)iterator

技術(shù)交流QQ群:1027579432锹淌,歡迎你的加入辞色!

1.Cpp中的迭代器

  • 要訪問順序容器和關(guān)聯(lián)容器中的元素鸽嫂,需要通過迭代器(iterator)進(jìn)行。迭代器是一個(gè)變量髓窜,相當(dāng)于容器和操縱容器的算法之間的中介扇苞。迭代器可以指向容器中的某個(gè)元素,通過迭代器就可以讀寫它指向的元素,從這一點(diǎn)上看,迭代器和指針類似杨拐。
  • 迭代器按照定義方式分成以下四種:
    • 正向迭代器祈餐,定義方法如下:
          容器類名::iterator 迭代器名;
      
    • 常量正向迭代器擂啥,定義方法如下:
          容器類名::const__iterator 迭代器名;
      
    • 反向迭代器哄陶,定義方法如下:
          容器類名::reverse_iterator 迭代器名;
      
    • 常量反向迭代器,定義方法如下:
          容器類名::const_reverse_iterator 迭代器名;
      

2.迭代器用法示例

  • 通過迭代器可以讀取它指向的元素哺壶,*迭代器名就表示迭代器指向的元素,通過非常量迭代器還能修改其指向的元素**屋吨。迭代器都可以進(jìn)行++操作。反向迭代器和正向迭代器的區(qū)別在于:
    • 正向迭代器進(jìn)行++操作時(shí)山宾,迭代器會(huì)指向容器中的后一個(gè)元素至扰;
    • 反向迭代器進(jìn)行++操作時(shí),迭代器會(huì)指向容器中的前一個(gè)元素资锰。
  • 實(shí)例如下:
        #include "iostream"
        #include "vector"
    
        using namespace std;
    
    
    
        int main(){
            // 迭代器用法實(shí)例
            vector<int> v;  // v中存放int類型變量的可變長的數(shù)組敢课,開始時(shí)沒有元素
            for(int n=0; n < 5; n++)
                v.push_back(n);  // push_back()成員函數(shù)在vector容器尾部添加一個(gè)元素
            vector<int>::iterator i;  // 定義正向迭代器
            cout << "正向迭代器遍歷容器: ";
            for(i = v.begin(); i!=v.end();++i){  // 用正向迭代器從前往后遍歷容器,使用前置++,不使用后置++,因?yàn)檫@將會(huì)降低運(yùn)算時(shí)間,原因是++運(yùn)算符的重載绷杜!后置++會(huì)多生成一個(gè)局部對象temp!
                cout << *i << " ";   // *n就是迭代器n指向的元素
                *i *= 2;   // 每個(gè)元素變?yōu)樵瓉淼?倍
            }
            cout << endl;
            // 用反向迭代器遍歷容器
            cout << "反向迭代器遍歷容器: ";
            vector<int>::reverse_iterator j;
            for(j=v.rbegin(); j != v.rend();++j)   // 用反向迭代器從后往前遍歷容器
                cout << *j << " ";
            cout << "-------------------------------------\n";
    
            return 0;
        }
    

3.迭代器的功能分類

  • 不同容器的迭代器直秆,其功能強(qiáng)弱有所不同。容器的迭代器的功能強(qiáng)弱鞭盟,決定了該容器是否支持STL中的某種算法圾结。例如,排序算法需要通過隨機(jī)訪問迭代器來訪問容器中的元素齿诉,因此有的容器就不支持排序算法筝野。常用的迭代器按功能強(qiáng)弱分為輸入、輸出粤剧、正向歇竟、雙向、隨機(jī)訪問五種抵恋,這里只介紹常用的三種焕议。
    • 正向迭代器: 假設(shè)p是一個(gè)正向迭代器,則p支持以下操作:++p馋记,p++号坡,*p。此外梯醒,兩個(gè)正向迭代器可以互相賦值宽堆,還可以用==和!=運(yùn)算符進(jìn)行比較。
    • 雙向迭代器: 雙向迭代器具有正向迭代器的全部功能茸习。除此之外畜隶,若p是一個(gè)雙向迭代器,則--p和p--都是有定義的。--p使得p朝著和++p相反的方向移動(dòng)籽慢。
    • 隨機(jī)訪問迭代器: 隨機(jī)訪問迭代器具有雙向迭代器的全部功能浸遗。若p是一個(gè)隨機(jī)訪問迭代器,i是一個(gè)整型變量或常量箱亿,則p還支持以下操作:
      • p+=i:使得p往后移動(dòng)i個(gè)元素
      • p-=i:使得p往前移動(dòng)i個(gè)元素
      • p+i:返回p后面第i個(gè)元素的迭代器
      • p-i:返回p前面第i個(gè)元素的迭代器
      • p[i]:返回p后面第i個(gè)元素的引用
    • 此外跛锌,兩個(gè)隨機(jī)訪問迭代器p1、p2 還可以用 <届惋、>髓帽、<=、>= 運(yùn)算符進(jìn)行比較脑豹。p1 < p2的含義是:p1經(jīng)過若干次(至少一次)++操作后郑藏,就會(huì)等于p2,其他比較方式的含義與此類似。對于兩個(gè)隨機(jī)訪問迭代器p1瘩欺、p2必盖,表達(dá)式p2-p1也是有定義的,其返回值是p2所指向元素和p1所指向元素的序號之差(也可以說是p2和p1之間的元素個(gè)數(shù)減一)俱饿。
      不同容器的迭代器的功能.png
  • 實(shí)例如下:
        // 迭代器的功能分類
        vector<int> v1(10);   // v1初始化成有10個(gè)元素
        for(int i = 0; i < v.size(); ++i)  // size()返回元素的個(gè)數(shù)
            cout << "v1[" << i << "] = " << v1[i] << " ";
        cout << endl;
        vector<int>::iterator i1;
        for(i1 = v1.begin(); i1 != v1.end(); ++i1)  // 用 != 比較兩個(gè)迭代器
            cout << *i1;
        cout << endl;
        for(i1 = v1.begin(); i1 < v1.end(); ++i1)  // 用 < 比較兩個(gè)迭代器
            cout << *i1;
        cout << endl;
        i1 = v.begin();
        while(i1 < v.end()){  // 間隔一個(gè)輸出
            cout << *i1;
            i1 += 2;   // 隨機(jī)訪問迭代器支持 "+= 整數(shù)"  的操作
        }
        cout << endl;
    
  • list容器的迭代器是雙向迭代器歌粥。假設(shè)v和i的定義如下:
        list<int> l;
        list<int>::const_iterator i
    
  • 則以下代碼是合法的:
        for(i = l.begin(); i != l.end(); ++i)
            cout << *l << " ";
    
  • 因?yàn)殡p向迭代器不支持用“<”進(jìn)行比較,list不支持隨機(jī)訪問迭代器的容器,也不支持用下標(biāo)隨機(jī)訪問其元素稍途。以下代碼則不合法:
        for(i = l.begin(); i < l.size(); ++i)
            cout << l[i];
        for(i = l.begin(); i < l.end(); ++i)
            cout << *l << endl;
    
  • 在C++中阁吝,數(shù)組也是容器。數(shù)組的迭代器就是指針械拍,而且是隨機(jī)訪問迭代器突勇。例如,對于數(shù)組int a[10]坷虑,int * 類型的指針就是其迭代器甲馋。則a、a+1迄损、a+2都是a的迭代器定躏。

4.迭代器的輔助函數(shù)

  • STL中有用于操作迭代器的三個(gè)函數(shù)模板,它們是:
    • advance(p, n):使迭代器p向前或向后移動(dòng)n個(gè)元素
    • distance(p, q):計(jì)算兩個(gè)迭代器之間的距離芹敌,即迭代器p經(jīng)過多少次++操作后和迭代器q相等痊远。如果調(diào)用時(shí)p已經(jīng)指向q的后面,則這個(gè)函數(shù)會(huì)陷入死循環(huán)氏捞。
    • iter_swap(p, q):用于交換兩個(gè)迭代器p碧聪、q指向的值
  • 要使用上述模板,需要包含頭文件algorithm液茎。下面的程序演示了這三個(gè)函數(shù)模板的用法:
        #include "iostream"
        #include "vector"
        #include "list"
        #include "algorithm"  // 要使用操作迭代器的函數(shù)模板逞姿,需要包含此文件!!
    
        using namespace std;
        int main(){
            // 迭代器的輔助函數(shù)
            int a[5] = {6, 66, 666, 6666, 0};
            list<int> lst(a, a+5);
            list<int>::iterator p = lst.begin();  // 迭代器p辞嗡,類似于一個(gè)指針
            advance(p, 2);    // p向后移動(dòng)兩個(gè)元素,指向666
            cout << *p << endl;  // 輸出666
            advance(p, -1);  // p向前移動(dòng)一個(gè)元素滞造,指向66
            cout << *p << endl;  // 輸出66
            list<int>::iterator q = lst.end();
            q--;  // q指向5
            cout << distance(p, q) << endl;  // 輸出3
            iter_swap(p, q);  // 序號從1開始续室,交換2號和5號元素
            for(p = lst.begin(); p != lst.end(); ++p)
                cout << *p << " ";
            return 0;
        } 
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市谒养,隨后出現(xiàn)的幾起案子挺狰,更是在濱河造成了極大的恐慌,老刑警劉巖蝴光,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件她渴,死亡現(xiàn)場離奇詭異达址,居然都是意外死亡蔑祟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門沉唠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疆虚,“玉大人,你說我怎么就攤上這事满葛【恫荆” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵嘀韧,是天一觀的道長篇亭。 經(jīng)常有香客問我,道長锄贷,這世上最難降的妖魔是什么译蒂? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮谊却,結(jié)果婚禮上柔昼,老公的妹妹穿的比我還像新娘。我一直安慰自己炎辨,他們只是感情好捕透,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著碴萧,像睡著了一般乙嘀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上破喻,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天虎谢,我揣著相機(jī)與錄音,去河邊找鬼低缩。 笑死嘉冒,一個(gè)胖子當(dāng)著我的面吹牛曹货,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播讳推,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼顶籽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了银觅?” 一聲冷哼從身側(cè)響起礼饱,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎究驴,沒想到半個(gè)月后镊绪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡洒忧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年蝴韭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片熙侍。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡榄鉴,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蛉抓,到底是詐尸還是另有隱情庆尘,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布巷送,位于F島的核電站驶忌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏笑跛。R本人自食惡果不足惜付魔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望堡牡。 院中可真熱鬧抒抬,春花似錦、人聲如沸晤柄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芥颈。三九已至惠勒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間爬坑,已是汗流浹背纠屋。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留盾计,地道東北人售担。 一個(gè)月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓赁遗,卻偏偏與公主長得像,于是被迫代替她去往敵國和親族铆。 傳聞我的和親對象是個(gè)殘疾皇子岩四,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355