STL迭代器(iterator)用法详解

C++ STL迭代器(iterator)用法详解

无论是序列容器还是关联容器,最常做的操作无疑是遍历容器中存储的元素,而实现此操作,多数情况会选用“迭代器(iterator)”来实现。那么,迭代器到底是什么呢?

我们知道,尽管不同容器的内部结构各异,但它们本质上都是用来存储大量数据的,换句话说,都是一串能存储多个数据的存储单元。因此,诸如数据的排序、查找、求和等需要对数据进行遍历的操作方法应该是类似的。

既然类似,完全可以利用泛型技术,将它们设计成适用所有容器的通用算法,从而将容器和算法分离开。但实现此目的需要有一个类似中介的装置,它除了要具有对容器进行遍历读写数据的能力之外,还要能对外隐藏容器的内部差异,从而以统一的界面向算法传送数据。

这是泛型思维发展的必然结果,于是迭代器就产生了。简单来讲,迭代器和 C++指针非常类似,它可以是需要的任意类型,通过迭代器可以指向容器中的某个元素,如果需要,还可以对该元素进行读/写操作。

迭代器类别

常用的迭代器按功能强弱分为输入迭代器输出迭代器前向迭代器双向迭代器随机访问迭代器

  1. 前向迭代器(forward iterator
    假设 p 是一个前向迭代器,则 p 支持 ++p,p++,*p 操作,还可以被复制或赋值,可以用 == 和 != 运算符进行比较。此外,两个正向迭代器可以互相赋值。

  2. 双向迭代器(bidirectional iterator
    双向迭代器具有正向迭代器的全部功能,除此之外,假设 p 是一个双向迭代器,则还可以进行 --p 或者 p-- 操作(即一次向后移动一个位置)。

  3. 随机访问迭代器(random access iterator
    随机访问迭代器具有双向迭代器的全部功能。除此之外,假设 p 是一个随机访问迭代器,i 是一个整型变量或常量,则 p 还支持以下操作:

  • p+=i:使得 p 往后移动 i 个元素。
  • p-=i:使得 p 往前移动 i 个元素。
  • p+i:返回 p 后面第 i 个元素的迭代器。
  • p-i:返回 p 前面第 i 个元素的迭代器。
  • p[i]:返回 p 后面第 i 个元素的引用。

此外,两个随机访问迭代器 p1、p2 还可以用 <、>、<=、>= 运算符进行比较。另外,表达式 p2-p1 也是有定义的,其返回值表示 p2 所指向元素和 p1 所指向元素的序号之差(也可以说是 p2 和 p1 之间的元素个数减一)。

C++ 11 标准中不同容器指定使用的迭代器类型:

容器对应的迭代器类型
array随机访问迭代器
vector随机访问迭代器
deque随机访问迭代器
list双向迭代器
set / multiset双向迭代器
map / multimap双向迭代器
forward_list前向迭代器
unordered_map / unordered_multimap前向迭代器
unordered_set / unordered_multiset前向迭代器
stack不支持迭代器
queue不支持迭代器

迭代器的定义方式

迭代器定义方式具体格式
正向迭代器容器类名::iterator 迭代器名;
常量正向迭代器容器类名::const_iterator 迭代器名;
反向迭代器容器类名::reverse_iterator 迭代器名;
常量反向迭代器容器类名::const_reverse_iterator 迭代器名;

实例1

/*******************************************************************
 *   > File Name: vector-iterator.cpp
 *   > Create Time: 2021年09月27日 15:11:00
 ******************************************************************/
#include <iostream>
#include <vector>
using namespace std;

int main(int argc, char* argv[])
{
    /* 创建一个向量容器v */
    vector<int> v{1, 2, 3, 4, 4, 6, 7, 8, 9, 10};
    cout << "1--------------" << endl;

    for(int i = 0; i< (int)v.size(); i++){
        cout << v[i] << " ";
    }

    cout << endl << "2--------------" << endl;
    vector<int>::iterator i; // 创建一个正向迭代器
    for(i = v.begin(); i != v.end(); i++){
        cout << *i << " ";
    }

    cout << endl << "3--------------" << endl;
    for(i = v.begin(); i < v.end(); i++){
        cout << *i << " ";
    }

    cout << endl << "4--------------" << endl;
    i = v.begin();
    while(i != v.end()){
        cout << *i << " ";
        i += 2;
    }

    return 0;
}

编译、运行:

PS E:\fly-prj\cplusplus\day20> .\vector-iterator.exe
1--------------
1 2 3 4 4 6 7 8 9 10
2--------------
1 2 3 4 4 6 7 8 9 10
3--------------
1 2 3 4 4 6 7 8 9 10
4--------------
1 3 4 7 9

实例2

数组也是容器。数组的迭代器就是指针,而且是随机访问迭代器。

/*******************************************************************
 *   > File Name: array-test.cpp
 *   > Create Time: 2021年09月27日 16:13:19
 ******************************************************************/
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
    int a[10] = {1,2,3,4,5,6,7,8,9,10};

    int* p = a; // p是a的迭代器
    for(int i = 0; i < 10; i++){
        printf("%d ", *p);
        p++;
    }

    return 0;
}

编译、运行:

PS E:\fly-prj\cplusplus\day20> make 
g++ -o array-test array-test.cpp -g -Wall
PS E:\fly-prj\cplusplus\day20> .\array-test.exe
1 2 3 4 5 6 7 8 9 10

实例3

/*******************************************************************
 *   > File Name: list-const_iterator.cpp
 *   > Create Time: 2021年09月27日 16:46:41
 ******************************************************************/
#include <iostream>
#include <vector>
#include <list>
using namespace std;

int main(int argc, char* argv[])
{
    list<int> v;
    list<int>::const_iterator  i; /*创建一个常量正向迭代器*/

    /* OK */
    for(i = v.begin(); i!= v.end(); ++i){
        cout << *i ;
    }

    #if 0/* 不支持<运算符 */
    // ERR:no match for ‘operator<’ (operand types are ‘std::list<int>::const_iterator’ and ‘std::list<int>::iterator’)
    for(i = v.begin(); i < v.end(); ++i){
        cout << *i;
    }
    #endif

    #if 0/* 不支持下标访问 */
    // ERR:no match for ‘operator[]’ (operand types are ‘std::list<int>’ and ‘int’)
    for(int i = 0; i < v.size(); ++i){
        cout << v[i];
    }
    #endif

    return 0;
}

C++ STL标准手册

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值