0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

什么是迭代器?

汽車電子技術(shù) ? 來源:C語言Plus ? 作者:Maye426 ? 2023-02-27 15:55 ? 次閱讀

一、什么是迭代器?

簡單來說,迭代器就是用來遍歷容器的。

舉個(gè)栗子:對于int型數(shù)組除了用下標(biāo)訪問,還可以通過指針訪問,實(shí)際上迭代器就是對指針進(jìn)行了封裝。

通過代碼了解一下,自己實(shí)現(xiàn)簡單的迭代器:

#include
#include  
using namespace std;
void show(int* begin, int* end)//自己寫的輸出函數(shù)
{
  while (begin != end)
  {
    cout << *begin << " ";
    begin++;
  }
}
int main()
{
  int arr[] = { 1,2,3,4,5,68,5,2,14,5,8,4,5,8,2,5,4,5,65,9 };
  int len = sizeof(arr) / sizeof(arr[0]);//求出數(shù)組元素個(gè)數(shù)
  //指針訪問
  int* begin = arr;
  int* end = arr + len;
  show(begin, end);//在容器中,begin,和end就是迭代器,底層封裝了指針


  while (1);
  return 0;
}

當(dāng)我們把show函數(shù)編程模板函數(shù)之后,就可以輸出任意類型的數(shù)組了:

template

通過這個(gè)例子我們知道了,可以通過迭代器實(shí)現(xiàn)算法和容器的分離(show函數(shù)可以適配不同類型的數(shù)組)。所以說迭代器是一個(gè)很強(qiáng)的東西~大家好好學(xué)哈

二、迭代器類別

STL 標(biāo)準(zhǔn)庫為每一種標(biāo)準(zhǔn)容器定義了一種迭代器類型,這意味著,不同容器的迭代器也不同,其功能強(qiáng)弱也有所不同。

常用的迭代器按功能強(qiáng)弱分為輸入迭代器、輸出迭代器、前向迭代器、雙向迭代器、隨機(jī)訪問迭代器 5 種

輸入迭代器 :也有叫法稱之為“只讀迭代器”,它從容器中讀取元素,只能一次讀入一個(gè)元素向前移動(dòng),只支持一遍算法,同一個(gè)輸入迭代器不能兩遍遍歷一個(gè)序列。

輸出迭代器 :也有叫法稱之為“只寫迭代器”,它往容器中寫入元素,只能一次寫入一個(gè)元素向前移動(dòng),只支持一遍算法,同一個(gè)輸出迭代器不能兩遍遍歷一個(gè)序列。

正向迭代器 :組合輸入迭代器和輸出迭代器的功能,還可以多次解析一個(gè)迭代器指定的位置,可以對一個(gè)值進(jìn)行多次讀/寫。

雙向迭代器 :組合正向迭代器的功能,還可以通過++操作符向后移動(dòng)位置。

隨機(jī)訪問迭代器 :組合雙向迭代器的功能,還可以向前向后跳過任意個(gè)位置,可以直接訪問容器中任何位置的元素。

迭代器的操作

迭代器 操作
所有迭代器 it++、++it
輸入迭代器 *it、it1=it2、it1==it2、it1!=it2
輸出迭代器 *it、it1=it2
正向迭代器 提供輸入輸出迭代器的所有功能
雙向迭代器 it--、--it
隨機(jī)迭代器 +=、-=、+、-、[]、<、<=、>、>=

不同容器所支持的迭代器類型表

容器 對應(yīng)迭代器類型
array 隨機(jī)訪問迭代器
vector 隨機(jī)訪問迭代器
deque 隨機(jī)訪問迭代器
list 雙向迭代器
set / multiset 雙向迭代器
map / multimap 雙向迭代器
forward_list 前向迭代器
unordered_map / unordered_multimap 前向迭代器
unordered_set / unordered_multiset 前向迭代器
stack 不支持迭代器
queue 不支持迭代器

三、基本實(shí)現(xiàn)

前面我們說過迭代器實(shí)質(zhì)上就是封裝的指針,那么怎么封裝的呢?

還是看代碼吧~

#include
using namespace std;


class MyIterator
{
public:
  MyIterator(int* ptr) :_ptr(ptr) {}
  int* operator++()//模仿指針前置++操作
  {
    _ptr++;
    return _ptr;
  }
  int& operator*()//模仿對指針的取值操作
  {
    return *_ptr;
  }
  bool operator!=(MyIterator end)//模仿指針的比較
  {
    return _ptr != end._ptr;
  }
private:
  int* _ptr;
};
int main()
{
  int arr[] = { 1,2,3,4,5,68,5,2,14,5,8,4,5,8,2,5,4,5,65,9 };
  int len = sizeof(arr) / sizeof(arr[0]);
  //模擬迭代器訪問
  MyIterator begin = arr;
  MyIterator end = arr + len;
  for (begin; begin != end; ++begin)
  {
    cout << *begin << " ";
  }
  while (1);
  return 0;
}

把指針封裝到類里面,這樣就可以輕松使用了,不用擔(dān)心出現(xiàn)亂七八糟的問題。

但是,細(xì)心的同學(xué)會發(fā)現(xiàn),操作的時(shí)候是不用指針了,直接操作迭代器就行,但是賦值的時(shí)候還是指針呀~這可咋解決呢?

不要著急,請聽我娓娓道來~我們可以把賦值的指針再封裝一層,直接返回一個(gè)迭代器。不過這里的任務(wù)就比較龐大了,

首先 ,需要把數(shù)組用類封裝(自己實(shí)現(xiàn)簡單的vector);

然后 ,把我們剛剛寫好的迭代器類稍加修改,放到類中(迭代器是一個(gè)類中類);

最后 ,直接把數(shù)組的首地址,和最后一個(gè)元素的下一個(gè)位置分別封裝成返回迭代器的begin()和end()函數(shù)

直接上代碼:

template<typename Data>
class Vector
{
public:
    Vector() :_Array(nullptr), _curSize(0), _capacity(0) {}
    Vector(int size) :_curSize(0), _capacity(size)
    {
        _Array = new Data[size];
    }
    void push_back(Data elem)//插入元素
{
        if (_curSize < _capacity)
        {
            _Array[_curSize] = elem;
            _curSize++;
            return;
        }
    }
    Data& operator[](int index)//提供下標(biāo)法訪問元素
    {
        if (index >= 0 && index < _capacity)
        {
            return _Array[index];
        }
        cout << "數(shù)組訪問越界" << endl;
    }
    ~Vector()
    {
        delete[] _Array;
    }
public://實(shí)現(xiàn)迭代器
    class iterator
    {
    public:
        iterator() :_ptr(nullptr) {}
        iterator(Data* ptr) :_ptr(ptr) {}
        iterator(const iterator& it)
        {
            this->_ptr = it._ptr;
        }
        ~iterator() {}
        iterator operator=(iterator it)
        {
            this->_ptr = it._ptr;
            return *this;
        }
        bool operator!=(iterator it)
        {
            return _ptr != it._ptr;
        }
        iterator operator++(int)
        {
            iterator temp = *this;
            _ptr++;
            return temp;
        }
        Data& operator*()
        {
            return *_ptr;
        }
        Data* operator->()
        {
            return _ptr;
        }
    private:
        Data* _ptr;
    };
    //提供用于迭代的begin和end函數(shù),這兩個(gè)函數(shù)一定要放在迭代器類的后面
    iterator begin()   //返回?cái)?shù)組首地址
{
        iterator t(_Array);
        return t;
    }
    iterator end()//返回?cái)?shù)組,最后一個(gè)元素的一下一個(gè)位置的地址
{
        iterator t(&_Array[_curSize]);
        return t;
    }
private:
    Data* _Array;//數(shù)組指針
    int _curSize;//數(shù)組當(dāng)前元素大小
    int _capacity;//數(shù)組最大容量
};

代碼測試:

void Test()
{
  Vector<int> vec(10);
  for (int i = 0; i < 10; i++)
  {
    vec.push_back(i);
  }
  //能通過迭代器訪問嘛?不能,要自己實(shí)現(xiàn)迭代器之后才能使用
  for (Vector<int>::iterator it = vec.begin(); it != vec.end(); it++)
  {
    cout << *it << " ";
  }
  cout << endl;
}

ok,完美~

圖片

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • Int
    Int
    +關(guān)注

    關(guān)注

    0

    文章

    23

    瀏覽量

    16076
  • 數(shù)組
    +關(guān)注

    關(guān)注

    1

    文章

    417

    瀏覽量

    25960
  • 迭代器
    +關(guān)注

    關(guān)注

    0

    文章

    43

    瀏覽量

    4316
收藏 人收藏

    評論

    相關(guān)推薦

    使用迭代如何實(shí)現(xiàn)指針前移或后移

    顯然,迭代是一種更靈活的遍歷行為,它可以按任意順序訪問容器中的元素,而且不會暴露容器的內(nèi)部結(jié)構(gòu)。
    的頭像 發(fā)表于 09-27 14:06 ?6288次閱讀
    使用<b class='flag-5'>迭代</b><b class='flag-5'>器</b>如何實(shí)現(xiàn)指針前移或后移

    談?wù)凱ython 中的迭代模式

    年,Design Patterns - Elements of Reusable Object-Oriented Software)中,它提出了23種設(shè)計(jì)模式。迭代模式就是其中的一種,在各種編程語言
    發(fā)表于 11-23 13:10 ?800次閱讀
    談?wù)凱ython 中的<b class='flag-5'>迭代</b><b class='flag-5'>器</b>模式

    Python高級特性:迭代切片的應(yīng)用

    在前兩篇關(guān)于 Python 切片的文章中,我們學(xué)習(xí)了切片的基礎(chǔ)用法、高級用法、使用誤區(qū),以及自定義對象如何實(shí)現(xiàn)切片用法(相關(guān)鏈接見文末)。本文是切片系列的第三篇,主要內(nèi)容是迭代切片。 迭代
    發(fā)表于 11-29 10:11 ?665次閱讀

    淺談python中的迭代

      說道python的迭代之前,不得不提到的就是在遠(yuǎn)古時(shí)期的C語言的時(shí)代,如果想要對一個(gè)數(shù)組進(jìn)行遍歷,只能使用for循環(huán)。
    發(fā)表于 11-24 17:01 ?317次閱讀
    淺談python中的<b class='flag-5'>迭代</b><b class='flag-5'>器</b>

    請問迭代的實(shí)現(xiàn)原理是什么?

    什么是集合框架?LIST接口的實(shí)際應(yīng)用?迭代的實(shí)現(xiàn)原理是什么?
    發(fā)表于 11-04 09:45

    js迭代異步介紹

    js 迭代 異步 介紹 (Introduction)It’s been a long while coming and I feel it’s high time I made a post
    發(fā)表于 09-06 09:26

    python迭代

    python迭代1. 可迭代對象可以利用 for 循環(huán)的對象,都叫可迭代對象。列表、元組、字典、字符串等都是可迭代對象。# 以列表為例>>
    發(fā)表于 02-24 15:42

    OpenHarmony中的HDF單鏈表及其迭代

    成員的值設(shè)置成第1個(gè)節(jié)點(diǎn)的地址。因?yàn)閱捂湵碇恢С滞粋€(gè)方向查找,不支持往回查找,如上面的錯(cuò)誤范例。如果root記錄的是第二個(gè)節(jié)點(diǎn)地址,則第一個(gè)節(jié)點(diǎn)變得不可訪問。迭代簡介迭代是伴隨集
    發(fā)表于 08-30 10:31

    OpenHarmony中的HDF單鏈表及其迭代

    節(jié)點(diǎn)的地址。因?yàn)閱捂湵碇恢С滞粋€(gè)方向查找,不支持往回查找,如上面的錯(cuò)誤范例。如果root記錄的是第二個(gè)節(jié)點(diǎn)地址,則第一個(gè)節(jié)點(diǎn)變得不可訪問。迭代簡介迭代是伴隨集合概念產(chǎn)生的,意思是
    發(fā)表于 09-05 11:38

    算法與數(shù)據(jù)結(jié)構(gòu)——迭代模式

    第三章為算法與數(shù)據(jù)結(jié)構(gòu),本文為3.4 迭代模式。
    的頭像 發(fā)表于 09-20 17:09 ?4959次閱讀
    算法與數(shù)據(jù)結(jié)構(gòu)——<b class='flag-5'>迭代</b><b class='flag-5'>器</b>模式

    什么是迭代?我們?yōu)槭裁匆褂?b class='flag-5'>迭代

    事實(shí)上,迭代是一個(gè)伴隨著迭代模式(Iterator Pattern)而生的抽象概念,其目的是分離并統(tǒng)一不同的數(shù)據(jù)結(jié)構(gòu)訪問其中數(shù)據(jù)的方式,從而使得各種需要訪問數(shù)據(jù)結(jié)構(gòu)的函數(shù),對于不同
    的頭像 發(fā)表于 07-21 07:45 ?1.4w次閱讀

    Python學(xué)習(xí)點(diǎn):為什么 range() 不生成迭代

    迭代是 23 種設(shè)計(jì)模式中最常用的一種(之一),在 Python 中隨處可見它的身影,我們經(jīng)常用到它,但是卻不一定意識到它的存在。在關(guān)于迭代的系列文章中(鏈接見文末),我至少提到了
    發(fā)表于 11-23 13:50 ?776次閱讀
    Python學(xué)習(xí)點(diǎn):為什么 range() 不生成<b class='flag-5'>迭代</b><b class='flag-5'>器</b>

    python迭代詳解

    python迭代 1. 可迭代對象 可以利用 for 循環(huán)的對象,都叫可迭代對象。 列表、元組、字典、字符串等都是可迭代對象。 # 以列表
    的頭像 發(fā)表于 02-24 15:42 ?1344次閱讀

    簡單介紹C++中迭代

    之前的兩篇文章我們主要了解了vector和string的相關(guān)知識,從中我們知道可以通過下標(biāo)來訪問vector的元素或者string的字符,但是除了這種方式還有一種更為通用的方式獲取元素,那就是迭代,這篇文章就會簡單介紹迭代
    的頭像 發(fā)表于 03-17 14:03 ?516次閱讀

    Python中的迭代介紹 迭代在scoreboard中的應(yīng)用有哪些?

    Iterator Design Pattern: 對容器 (聚合類,集合數(shù)據(jù)等) 的遍歷操作從容器中拆分出來,放到迭代中,實(shí)現(xiàn)迭代操作的解耦。
    的頭像 發(fā)表于 08-08 09:41 ?620次閱讀
    Python中的<b class='flag-5'>迭代</b><b class='flag-5'>器</b>介紹 <b class='flag-5'>迭代</b><b class='flag-5'>器</b>在scoreboard中的應(yīng)用有哪些?