C++ 迭代器
ztj100 2025-01-03 20:48 21 浏览 0 评论
C++ 迭代器是一种使程序能够遍历访问容器(如 vector、list、set、map 等)中元素的方法。它允许我们使用相同的语法来遍历不同的容器,使得代码具有更高的可复用性和可维护性。在 C++ STL 中,迭代器是一种通用的工具,可以用来访问所有容器类型的元素,因此也成为了 STL 算法的基石。
迭代器本质上是一种指针,它指向容器中的元素。通过迭代器,我们可以访问容器中的元素,读取或修改它们的值。迭代器可以看作是容器和算法之间的桥梁,将容器和算法解耦,让它们可以相互独立地演化。迭代器使得容器的实现细节对外部透明,用户只需要关心迭代器提供的操作接口即可。
迭代器的常见用法
- 遍历容器元素
std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
- 在容器中查找元素
std::vector<int> vec = {1, 2, 3, 4, 5};
auto it = std::find(vec.begin(), vec.end(), 3);
if (it != vec.end()) {
std::cout << "Found element 3 at index " << std::distance(vec.begin(), it) << std::endl;
}
- 插入或删除元素
std::vector<int> vec = {1, 2, 3, 4, 5};
auto it = vec.begin() + 2; // 指向元素3的迭代器
it = vec.insert(it, 6); // 在元素3之前插入元素6,并返回指向新插入元素的迭代器
it = vec.erase(it); // 删除元素6,并返回指向下一个元素的迭代器
迭代器的操作
迭代器作为访问容器元素的一种方式,支持多种操作来方便地访问和修改容器中的元素。
下面列出了迭代器的常见操作:
- 解引用操作(*、->):可以通过迭代器对元素进行读写操作。例如,对于一个指向 vector<int> 中第一个元素的迭代器 iter,可以通过 *iter 来访问该元素的值,通过 iter-> 运算符来访问该元素的成员。
- 前缀/后缀自增/自减运算符(++、--):通过这些运算符可以将迭代器向前或向后移动。例如,iter++ 表示将迭代器 iter 向后移动一个位置,而 ++iter 表示将迭代器向前移动一个位置。
- 算术运算符(+、-、+=、-=):通过这些运算符可以实现迭代器的加减操作。例如,iter+n 表示将迭代器 iter 向后移动 n 个位置,而 iter-n 表示将迭代器向前移动 n 个位置。
- 比较运算符(==、!=、<、>、<=、>=):通过这些运算符可以比较两个迭代器的相对位置。例如,iter1 == iter2 表示两个迭代器指向同一个元素,而 iter1 < iter2 表示 iter1 在 iter2 之前。
- distance 函数:可以通过该函数计算两个迭代器之间的距离,即它们相差的元素个数。例如,distance(iter1, iter2) 返回迭代器 iter1 到 iter2 之间元素的个数。
- advance 函数:可以通过该函数将迭代器向前或向后移动指定的距离。例如,advance(iter, n) 表示将迭代器 iter 向后移动 n 个位置,而 advance(iter, -n) 表示将迭代器向前移动 n 个位置。
- 迭代器交换(swap):可以通过该函数交换两个迭代器的值。例如,swap(iter1, iter2) 表示交换迭代器 iter1 和 iter2 的值。
int main() {
std::vector<int> v{1, 2, 3, 4, 5};
// 使用迭代器遍历vector,并输出所有元素
std::cout << "遍历vector并输出所有元素:";
for (std::vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 修改迭代器所指向的元素
std::cout << "修改迭代器所指向的元素:";
std::vector<int>::iterator it = v.begin();
*it = 10;
std::cout << *it << " ";
std::cout << std::endl;
// 插入元素并返回插入元素的迭代器
std::cout << "在vector的开头插入一个元素:";
std::vector<int>::iterator it_insert = v.insert(v.begin(), 0);
std::cout << *it_insert << " ";
std::cout << std::endl;
// 删除迭代器所指向的元素
std::cout << "删除迭代器所指向的元素:";
std::vector<int>::iterator it_erase = v.erase(v.begin() + 2);
std::cout << *it_erase << " ";
std::cout << std::endl;
// 查找元素并返回指向该元素的迭代器
std::cout << "查找元素并返回指向该元素的迭代器:";
std::vector<int>::iterator it_find = std::find(v.begin(), v.end(), 4);
std::cout << *it_find << " ";
std::cout << std::endl;
return 0;
}
迭代器的失效
在使用迭代器时,需要注意迭代器的失效问题。当容器在插入、删除元素时,会导致迭代器失效,即该迭代器所指向的元素不再存在或者已经发生变化。如果继续使用失效的迭代器,可能会引发程序崩溃或者产生不可预期的错误结果。
以下 vector 容器的迭代器失效规则:
- 对于 vector,如果在中间插入或删除元素,则该位置后的迭代器全部失效;如果在尾部插入或删除元素,则尾部迭代器失效。
下面是Vector 插入删除的迭代器解决方法:
添加或者删除时,需要更新迭代器
int main() {
std::vector<int> vec{ 1, 2, 3, 4, 5, 6 };
// 遍历 vector,同时添加元素
for (auto it = vec.begin(); it != vec.end();) {
std::cout << *it << " ";
if (*it == 3) {
// 更新迭代器
it = vec.insert(it, 6); // 在 3 的前面插入 6
it+=2; // 移动迭代器,跳过插入的元素
} else {
it++;
}
}
std::cout << std::endl;
for (auto i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
auto iter = vec.begin();
while (iter != vec.end()) {
if (*iter % 2 == 0) {
// 更新迭代器
iter = vec.erase(iter); // 删除偶数元素
}
else {
++iter;
}
}
for (auto i : vec) {
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
相关推荐
- Jquery 详细用法
-
1、jQuery介绍(1)jQuery是什么?是一个js框架,其主要思想是利用jQuery提供的选择器查找要操作的节点,然后将找到的节点封装成一个jQuery对象。封装成jQuery对象的目的有...
- 前端开发79条知识点汇总
-
1.css禁用鼠标事件2.get/post的理解和他们之间的区别http超文本传输协议(HTTP)的设计目的是保证客户机与服务器之间的通信。HTTP的工作方式是客户机与服务器之间的请求-应答协议。...
- js基础面试题92-130道题目
-
92.说说你对作用域链的理解参考答案:作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到window对象即被终止,作用域链向下访问变量是不被允许的。...
- Web前端必备基础知识点,百万网友:牛逼
-
1、Web中的常见攻击方式1.SQL注入------常见的安全性问题。解决方案:前端页面需要校验用户的输入数据(限制用户输入的类型、范围、格式、长度),不能只靠后端去校验用户数据。一来可以提高后端处理...
- 事件——《JS高级程序设计》
-
一、事件流1.事件流描述的是从页面中接收事件的顺序2.事件冒泡(eventbubble):事件从开始时由最具体的元素(就是嵌套最深的那个节点)开始,逐级向上传播到较为不具体的节点(就是Docu...
- 前端开发中79条不可忽视的知识点汇总
-
过往一些不足的地方,通过博客,好好总结一下。1.css禁用鼠标事件...
- Chrome 开发工具之Network
-
经常会听到比如"为什么我的js代码没执行啊?","我明明发送了请求,为什么反应?","我这个网站怎么加载的这么慢?"这类的问题,那么问题既然存在,就需要去解决它,需要解决它,首先我们得找对导致问题的原...
- 轻量级 React.js 虚拟美化滚动条组件RScroll
-
前几天有给大家分享一个Vue自定义滚动条组件VScroll。今天再分享一个最新开发的ReactPC端模拟滚动条组件RScroll。...
- 一文解读JavaScript事件对象和表单对象
-
前言相信做网站对JavaScript再熟悉不过了,它是一门脚本语言,不同于Python的是,它是一门浏览器脚本语言,而Python则是服务器脚本语言,我们不光要会Python,还要会JavaScrip...
- Python函数参数黑科技:*args与**kwargs深度解析
-
90%的Python程序员不知道,可变参数设计竟能决定函数的灵活性和扩展性!掌握这些技巧,让你的函数适应任何场景!一、函数参数设计的三大进阶技巧...
- 深入理解Python3密码学:详解PyCrypto库加密、解密与数字签名
-
在现代计算领域,信息安全逐渐成为焦点话题。密码学,作为信息保护的关键技术之一,允许我们加密(保密)和解密(解密)数据。...
- 阿里Nacos惊爆安全漏洞,火速升级!(附修复建议)
-
前言好,我是threedr3am,我发现nacos最新版本1.4.1对于User-Agent绕过安全漏洞的serverIdentitykey-value修复机制,依然存在绕过问题,在nacos开启了...
- Python模块:zoneinfo时区支持详解
-
一、知识导图二、知识讲解(一)zoneinfo模块概述...
- Golang开发的一些注意事项(一)
-
1.channel关闭后读的问题当channel关闭之后再去读取它,虽然不会引发panic,但会直接得到零值,而且ok的值为false。packagemainimport"...
- Python鼠标与键盘自动化指南:从入门到进阶——键盘篇
-
`pynput`是一个用于控制和监控鼠标和键盘的Python库...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)