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

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

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

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

迭代器类别

STL 标准库为每一种标准容器定义了一种迭代器类型,这意味着,不同容器的迭代器也不同,其功能强弱也有所不同。

容器的迭代器的功能强弱,决定了该容器是否支持 STL 中的某种算法。

常用的迭代器按功能强弱分为输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器 5 种。本节主要介绍后面的这 3 种迭代器。

输入迭代器和输出迭代器比较特殊,它们不是把数组或容器当做操作对象,而是把输入流/输出流作为操作对象。有关这 2 个迭代器,我们会在后续章节做详细介绍。

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 之间的元素个数减一)。

表 1 所示,是 C++ 11 标准中不同容器指定使用的迭代器类型。

表 1 不同容器的迭代器

容器

对应的迭代器类型

array

随机访问迭代器

vector

随机访问迭代器

deque

随机访问迭代器

list

双向迭代器

set / multiset

双向迭代器

map / multimap

双向迭代器

forward_list

前向迭代器

unordered_map / unordered_multimap

前向迭代器

unordered_set / unordered_multiset

前向迭代器

stack

不支持迭代器

queue

不支持迭代器

注意,容器适配器 stack 和 queue 没有迭代器,它们包含有一些成员函数,可以用来对元素进行访问。

迭代器的定义方式

尽管不同容器对应着不同类别的迭代器,但这些迭代器有着较为统一的定义方式,具体分为 4 种,如表 1 所示。

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

迭代器定义方式

具体格式

正向迭代器

容器类名::iterator  迭代器名;

常量正向迭代器

容器类名::const_iterator  迭代器名;

反向迭代器

容器类名::reverse_iterator  迭代器名;

常量反向迭代器

容器类名::const_reverse_iterator  迭代器名;

值得一提的是,表 2 中的反向迭代器全称为 "反向迭代器适配器",后续章节会做详细讲解,这里读者只需要知道其用法即可。

通过定义以上几种迭代器,就可以读取它指向的元素,*迭代器名就表示迭代器指向的元素。其中,常量迭代器和非常量迭代器的分别在于,通过非常量迭代器还能修改其指向的元素。另外,反向迭代器和正向迭代器的区别在于:

对正向迭代器进行 ++ 操作时,迭代器会指向容器中的后一个元素;

而对反向迭代器进行 ++ 操作时,迭代器会指向容器中的前一个元素。

注意,以上 4 种定义迭代器的方式,并不是每个容器都适用。有一部分容器同时支持以上 4 种方式,比如 array、deque、vector;而有些容器只支持其中部分的定义方式,例如 forward_list 容器只支持定义正向迭代器,不支持定义反向迭代器。

具体容器支持定义迭代器的方式,讲具体容器时会详细说明。另外,读者也可以通过 C++ STL标准手册,查询具体容器迭代器支持的定义方式。

以上对迭代器做了很详细的介绍,下面就以 vector 容器为例,带领大家实际感受迭代器的用法和功能。通过前面的学习,vector 支持随机访问迭代器,因此遍历 vector 容器有以下几种做法。下面的程序中,每个循环演示了一种做法:

//遍历 vector 容器。

#include

//需要引入 vector 头文件

#include

using namespace std;

int main()

{

vector v{1,2,3,4,5,6,7,8,9,10}; //v被初始化成有10个元素

cout << "第一种遍历方法:" << endl;

//size返回元素个数

for (int i = 0; i < v.size(); ++i)

cout << v[i] <

//创建一个正向迭代器,当然,vector也支持其他 3 种定义迭代器的方式

cout << endl << "第二种遍历方法:" << endl;

vector::iterator i;

//用 != 比较两个迭代器

for (i = v.begin(); i != v.end(); ++i)

cout << *i << " ";

cout << endl << "第三种遍历方法:" << endl;

for (i = v.begin(); i < v.end(); ++i) //用 < 比较两个迭代器

cout << *i << " ";

cout << endl << "第四种遍历方法:" << 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 容器的迭代器是双向迭代器。假设 v 和 i 的定义如下:

//创建一个 v list容器

list v;

//创建一个常量正向迭代器,同样,list也支持其他三种定义迭代器的方式。

list::const_iterator i;

则以下代码是合法的:

for(i = v.begin(); i != v.end(); ++i)

cout << *i;

以下代码则不合法,因为双向迭代器不支持用“

for(i = v.begin(); i < v.end(); ++i)

cout << *i;

以下代码也不合法,因为双向迭代器不支持用下标随机访问元素:

for(int i=0; i

cout << v[i];

其实在 C++ 中,数组也是容器。数组的迭代器就是指针,而且是随机访问迭代器。例如,对于数组 int a[10],int * 类型的指针就是其迭代器。则 a、a+1、a+2 都是 a 的迭代器。另外,以上有关 vector、list 容器的具体用法,后续章节会做详细讲解。

mysql迭代器_迭代器是什么,C++ STL迭代器(iterator)用法详解相关推荐

  1. C++ STL容器 —— array 用法详解

    C++ STL容器 -- array 用法详解 写在前面:近期正在学习C++的STL容器,因此在这里做一下日志记录,主要介绍一些容器基本成员函数的用法, 配上实际用例,并不涉及原理.但别人的博客终究是 ...

  2. mysql isnull()_MySql中的IFNULL、NULLIF和ISNULL用法详解

    今天用到了MySql里的isnull才发现他和MSSQL里的还是有点区别,现在简单总结一下: mysql中isnull,ifnull,nullif的用法如下: isnull(expr) 的用法: 如e ...

  3. STL中map用法详解

    Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候 ...

  4. [转] STL中map用法详解

    一.Map概述          Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完 ...

  5. STL —— multimap的用法详解

    文章目录 multimap的基本性质 STL--multimap容器的用法 multimap容器的创建与初始化 multimap容器包含的成员方法 multimap容器大小 multimap容器中键值 ...

  6. STL中list用法详解

    本文转载自百度文库.作者如下.其中下面的count, count_if等函数的使用有些陈旧,如在编译时遇到问题,请百度. 标准模板库(STL)介绍 作者:Scott Field 本文以List容器为例 ...

  7. STL之string用法详解

    2.1 string容器介绍 string也属于STL常用容器之一,因此vector(参考博客)中的大部分方法与迭代器都适用于string容器.string容器用于保存字符串,使用一组连续的内存单元来 ...

  8. STL:list用法详解

    list容器介绍 相对于vector容器的连续线性空间,list是一个双向链表,它有一个重要性质:插入操作和删除操作都不会造成原有的list迭代器失效,每次插入或删除一个元素就配置或释放一个元素空间. ...

  9. mysql 存储引擎作用_MySQL常用存储引擎功能与用法详解

    MySQL存储引擎主要有两大类: 1. 事务安全表:InnoDB.BDB. 2. 非事务安全表:MyISAM.MEMORY.MERGE.EXAMPLE.NDB Cluster.ARCHIVE.CSV. ...

  10. python3 isinstance用法_对python中assert、isinstance的用法详解

    1. assert 函数说明: Assert statements are a convenient way to insert debugging assertions into a program ...

最新文章

  1. tensorflow tuner 调参,示例代码(jupyter notebook 版)
  2. 网络工程师的经典爱情观
  3. Win64 驱动内核编程-4.内核里操作字符串
  4. 【Google Play】从 Android 应用中跳转到 Google Play 中 ( 跳转代码示例 | Google Play 页面的链接格式 | Google Play 免安装体验 )
  5. XML 序列化与反序列化
  6. C的function call與stack frame心得
  7. MySQL a库备份恢复为B库_MySQL数据库备份的基础知识_MySQL
  8. LeetCode 378. 有序矩阵中第K小的元素(二分查找)
  9. apache安装_kali Linux下的Apache的配置和安装:
  10. win10搭建hadoop环境
  11. 【转】请不要做浮躁的人。
  12. idea导入java文件_怎么在idea中导入Java文件并运行文件
  13. 黑龙江大学自考,助学专业软件工程(本科)招生简章
  14. python读取csv最后一行_用Python读取CSV文件行的最后一个非空单元格
  15. html 复选框事件,HTML复选框选中与未选中触发事件的方法
  16. php nofollow,php如何实现统一给外部链接添加nofollow值?
  17. 【软考系统架构设计师】复盘架构设计师真题知识点第二十五章---企业信息化战略
  18. Win10卸载office出现安装包语言不受系统支持
  19. 因设计或者设施缺陷导致道路交通事故赔偿问题的法律依据
  20. 1024 发福利,送你一份珍藏依旧的 Java,大数据礼包,确定不收藏 ?拒绝白嫖 !

热门文章

  1. 没考计算机水平怎么填6,“计算机水平”怎么填,没曾考级,只参加过大 – 手机爱问...
  2. java.lang.UnsatisfiedLinkError: C:\Users\Administrator\AppData\Local\Temp\2\librocksdbjni91
  3. 电脑使用android手机摄像头,电脑怎么使用安卓手机摄像头 电脑使用手机摄像头的方法-电脑教程...
  4. c语言幼儿园自动分班,【资源学习】c语言程序代码,登录幼儿园200个小朋友的数据...
  5. 计算机网络浅谈,浅谈计算机网络的重要性
  6. 开源软件总体拥有成本指南
  7. 大型机汇编HLASM - HOOK ISPF命令START(一)
  8. REDO文件损坏修复
  9. python俄罗斯方块编程思路_少儿编程分享:手把手教你用Python编写俄罗斯方块(十)...
  10. 好看的桑基图是如何炼成的!