C++迭代器 iterator详解

server/2024/9/23 5:29:34/

目录

什么是迭代器

迭代器的类型

迭代器的用法

 三种迭代器

范围for


什么是迭代器

它提供了一种访问容器(如列表、集合等)中元素的方法,而无需暴露容器的内部表示。迭代器使得程序员能够以统一的方式遍历不同的数据结构,而无需关心这些数据结构的具体实现细节。类似于指针指向对应的元素并且能对这个元素进行修改和使用。

迭代器的类型

有4种迭代器形式:

正向迭代器:

语法:容器名::iterator 迭代器名字;

正向常量迭代器:

语法:容器名::const_iterator 迭代器名字;

反向迭代器:

语法:容器名::reverse_iterator 迭代器名字;

反向常量迭代器:

语法:容器名::const_reverse_iterator 迭代器名字;

迭代器的用法

前面说迭代器类似于一个指针,所以用法和指针也是类似的 

vector<int> v = {1,2,3,4};
vector<int>::iterator i;//定义一个vector的迭代器
i = v.begin();//让i 等于 v 的第一个元素int *p = &v[i];//定义一个指针int j = *i;
int k = *p;

此时 j == k 。说明了迭代器和指针是类似的,因为迭代器就是封装了对应类型的指针。

迭代器都可以进行++:

正向迭代器的++ 是向后移动。

反向迭代器的++ 是向前移动。

下面我们使用vector进行遍历和修改:

//vector是c++的容器,类似于一个数组,但是支持变长vector<int> v;vector<int>::iterator it;//这里给v 中插入了5个数字 0 1 2 3 4 5for (int i = 0; i < 5; i++){v.push_back(i);}//打印v的内容for (it = v.begin(); it != v.end(); ++it){cout << *it << ' ';}cout << endl;//改变v的内容for (it = v.begin(); it != v.end(); ++it){*it *= 2;}cout << endl;//打印改变后的内容for (it = v.begin(); it != v.end(); ++it){cout << *it << ' ';}cout << endl;//用反向迭代器遍历vfor (vector<int>::reverse_iterator j = v.rbegin(); j != v.rend(); ++j)cout << *j << " ";

结果如下:

注意:

1.it 用的是 != v.end(),这是为什么?而不是 < end() 在部分容器里用 < end(),是可以的,比如现在使用的vector,但是对于部分不是连续空间的容器类似 list 等等无法通过 < end()比较当前位置。

2.可以看出反向迭代器的++是逆向的。

3.为什么用的是前置++而不是后置++?

因为前置++的效率更高

// 前置++
Date& Date::operator++()
{// 复用operator+=*this += 1;return *this;
}
// 后置++
Date Date::operator++(int)
{Date tmp(*this);// 拷贝构造tmp,用于返回// 复用operator+=*this += 1;return tmp;
}

如上代码:

1.operator区分前置++和后置++是看有没有参数(语法规定)

2.为什么前置++效率高,因为前置++直接对 *this操作然后返回,后置++则是先拷贝构造了一份tmp。

 三种迭代器

第一只:正向迭代器

只可以进行++ ,和*i,还支持== != 等操作。

第二只:双向迭代器

可以进行++ 或者 -- 。比正向迭代器多一种--手段。

第三只:随机迭代器

拥有上面两种迭代器的全部功能。并且支持随机访问,i + 10,代表了往后10个元素。同时支持下标访问数组 

vector<int>::iterator i;
i += 10;//向后移动10个元素
i[10];//第10个元素的位置

对于随机迭代器通常只出现在物理空间连续的容器上,例如vector。

而物理空间不连续的例如list,上是没有随机访问这种功能的。

和 数组 和 链表的定义是类似的。

所以不同容器的迭代器不同,有些容器没有迭代器。

范围for

范围for就是利用迭代器实现的遍历容器的方法

具体使用如下:

    vector<int> v;//这里给v 中插入了5个数字 0 1 2 3 4 5for (int i = 0; i < 5; i++){v.push_back(i);}//范围forfor (int num : v){cout << num<<' ';}

范围for其实就是迭代器遍历,其中 int num 就是 *it .

结果如下:


http://www.ppmy.cn/server/120651.html

相关文章

数据结构与算法——Java实现 10.习题——删除有序链表重复节点

所有无能为力的事情&#xff0c;我都在慢慢接受 —— 24.9.22 83. 删除排序链表中的重复元素 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,1,2] 输出…

SOCKS5、HTTP 代理IP协议有何区别?

在网络通信领域&#xff0c;代理服务器的选择对于数据安全和传输效率至关重要。SOCKS5代理和HTTP代理作为两种常用的代理类型&#xff0c;各自具有独特的特点和适用场景。本文将深入探讨SOCKS5代理与HTTP代理的区别、特性及应用场景&#xff0c;为用户提供选择指南。 一、SOCK…

矩阵分析第二章内积空间手稿笔记

概念 CS定理 内积长度 向量正交 正交基 构造正交基 内积的坐标表示 正交矩阵 两组正交基的过渡矩阵是正交的 特征值的模为1 正交子空间 正交补 内积空间的同构 正交变换内积不变 证明 点到点的距离 点到子空间的距离 最小二乘法 复内积空间 复内积空间cs定理和证明 三角不等式 …

增强现实系列—Map-Relative Pose Regression for Visual Re-Localization

&#x1f31f;&#x1f31f; 欢迎来到我的技术小筑&#xff0c;一个专为技术探索者打造的交流空间。在这里&#xff0c;我们不仅分享代码的智慧&#xff0c;还探讨技术的深度与广度。无论您是资深开发者还是技术新手&#xff0c;这里都有一片属于您的天空。让我们在知识的海洋中…

MyBatis 源码解析:TypeHandler 设计与自定义实现

引言 在 MyBatis 中&#xff0c;TypeHandler 是一个非常重要的接口&#xff0c;它的作用是将 Java 类型和数据库类型进行互相转换。当我们执行 SQL 查询或插入操作时&#xff0c;TypeHandler 决定了如何将 Java 对象转换为数据库字段类型&#xff0c;或将数据库字段转换为 Jav…

【C/C++】initializer_list

initializer_list 1 构造函数场景 class P { public:P(int a, int b) {std::cout << "int, int" << std::endl;}P(std::initializer_list<int> initList) {std::cout << "initializer_list" << std::endl;} };调用&#x…

上位机图像处理和嵌入式模块部署(linux小系统开发)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 和若干年前相比较&#xff0c;现在嵌入式linux开发要简单得多。稍微贵一点的有树莓派&#xff0c;国产的有各种水果派&#xff0c;基本上都可以按照…

镜像导入、标签设置与应用、探针测试

一、镜像导入 1、master主机下载镜像并打包 [rootk8s-master ~]# docker pull nginx:1.20.0[rootk8s-master ~]# docker pull nginx:1.21.0[rootk8s-master ~]# docker pull nginx:1.25.0[rootk8s-master ~]# docker pull busybox:latest[rootk8s-master ~]# docker save -o n…