找回密码
 register

QQ登录

只需一步,快速开始

查看: 12|回复: 0

[C++] 迭代器是什么,C++ STL迭代器(iterator)用法详解

[复制链接]

[C++] 迭代器是什么,C++ STL迭代器(iterator)用法详解

[复制链接]
  • 打卡等级:热心大叔
  • 打卡总天数:215
  • 打卡月天数:14
  • 打卡总奖励:213
  • 最近打卡:2025-06-14 16:42:29
Waylee

主题

0

回帖

2万

积分

仙帝

积分
22663
Waylee 2025-6-13 23:25 | 显示全部楼层 |阅读模式 | Google Chrome | Windows 10

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×

什么是迭代器(iterator)?

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

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

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

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


迭代器的类别

STL 标准库为每一种标准容器定义了一种迭代器类型,这意味着,不同容器的迭代器也不同,其功能强弱也有所不同。容器迭代器的功能强弱,决定了该容器是否支持 STL 中的某种算法。

常用迭代器按功能强弱分为:

  • 输入迭代器
  • 输出迭代器
  • 前向迭代器
  • 双向迭代器
  • 随机访问迭代器

本节主要介绍后面 3 种迭代器。输入和输出迭代器比较特殊,它们操作的对象是输入/输出流,后续章节会详细介绍。


1. 前向迭代器(forward iterator)

假设 p 是前向迭代器,则:

  • 支持 ++pp++*p 操作;
  • 可以被复制或赋值;
  • 可以用 ==!= 比较;
  • 两个前向迭代器可以互相赋值。

2. 双向迭代器(bidirectional iterator)

双向迭代器具有前向迭代器的全部功能。除此之外,假设 p 是双向迭代器:

  • 还可以进行 --p 或者 p-- 操作(即一次向后移动一个位置)。

3. 随机访问迭代器(random access iterator)

随机访问迭代器具有双向迭代器的全部功能。除此之外,假设 p 是随机访问迭代器,i 是整型变量或常量,还支持:

  • p += i:使 p 往后移动 i 个元素。
  • p -= i:使 p 往前移动 i 个元素。
  • p + i:返回 p 后面第 i 个元素的迭代器。
  • p - i:返回 p 前面第 i 个元素的迭代器。
  • p[i]:返回 p 后面第 i 个元素的引用。
  • 两个随机访问迭代器 p1p2 还可以用 <><=>= 运算符比较。
  • 表达式 p2 - p1 有定义,其返回值表示元素序号差(也可看作两迭代器间元素个数减一)。

表 1:不同容器对应的迭代器(C++11 标准)

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

注意:容器适配器 stackqueue 没有迭代器,它们通过成员函数访问元素。


表 2:迭代器的 4 种定义方式

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

值得一提的是,表 2 中的反向迭代器全称为“反向迭代器适配器”,后续章节详细讲解,这里只需了解其用法即可。

  • 常量迭代器与非常量迭代器区别在于:非常量迭代器能修改元素。
  • 反向迭代器与正向迭代器区别在于:

    • 正向迭代器 ++ 时,迭代器指向后一个元素;
    • 反向迭代器 ++ 时,迭代器指向前一个元素。

注意,不是每个容器都同时适用以上 4 种定义方式。例如:

  • array、deque、vector 支持全部定义方式;
  • forward_list 只支持正向迭代器。

具体支持情况后续章节会详细说明,也可通过 STL 手册查询。


迭代器使用示例

下面以 vector 容器为例,实际演示迭代器用法:

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> v{1,2,3,4,5,6,7,8,9,10};

    cout << "第一种遍历方法:" << endl;
    for (int i = 0; i < v.size(); ++i)
        cout << v[i] << " ";

    cout << "\n第二种遍历方法:" << endl;
    vector<int>::iterator i;
    for (i = v.begin(); i != v.end(); ++i)
        cout << *i << " ";

    cout << "\n第三种遍历方法:" << endl;
    for (i = v.begin(); i < v.end(); ++i)
        cout << *i << " ";

    cout << "\n第四种遍历方法:" << endl;
    i = v.begin();
    while (i < v.end()) {
        cout << *i << " ";
        i += 2;
    }
}

运行结果:

第一种遍历方法:
1 2 3 4 5 6 7 8 9 10
第二种遍历方法:
1 2 3 4 5 6 7 8 9 10
第三种遍历方法:
1 2 3 4 5 6 7 8 9 10
第四种遍历方法:
1 3 5 7 9

再举一例,list 容器迭代器是双向迭代器:

  • 合法:for(i = v.begin(); i != v.end(); ++i)
  • 不合法:for(i = v.begin(); i < v.end(); ++i)(不能用 < 比较)
  • 不合法:for(int i=0; i<v.size(); ++i)(不支持下标随机访问)

数组也是容器,迭代器就是指针,属于随机访问迭代器,例如数组 int a[10],其迭代器就是指针 int*

以上 vector、list 的详细用法,后续章节再详细讲解。

您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |网站地图|天天打卡

GMT+8, 2025-6-14 18:22 , Processed in 0.095254 second(s), 5 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表