百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

C++ 迭代器

ztj100 2025-01-03 20:48 10 浏览 0 评论

C++ 迭代器是一种使程序能够遍历访问容器(如 vector、list、set、map 等)中元素的方法。它允许我们使用相同的语法来遍历不同的容器,使得代码具有更高的可复用性和可维护性。在 C++ STL 中,迭代器是一种通用的工具,可以用来访问所有容器类型的元素,因此也成为了 STL 算法的基石。

迭代器本质上是一种指针,它指向容器中的元素。通过迭代器,我们可以访问容器中的元素,读取或修改它们的值。迭代器可以看作是容器和算法之间的桥梁,将容器和算法解耦,让它们可以相互独立地演化。迭代器使得容器的实现细节对外部透明,用户只需要关心迭代器提供的操作接口即可。

迭代器的常见用法

  1. 遍历容器元素
std::vector<int> vec = {1, 2, 3, 4, 5};
for (auto it = vec.begin(); it != vec.end(); ++it) {
    std::cout << *it << " ";
}
  1. 在容器中查找元素
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;
}
  1. 插入或删除元素
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,并返回指向下一个元素的迭代器

迭代器的操作

迭代器作为访问容器元素的一种方式,支持多种操作来方便地访问和修改容器中的元素。

下面列出了迭代器的常见操作:

  1. 解引用操作(*、->):可以通过迭代器对元素进行读写操作。例如,对于一个指向 vector<int> 中第一个元素的迭代器 iter,可以通过 *iter 来访问该元素的值,通过 iter-> 运算符来访问该元素的成员。
  2. 前缀/后缀自增/自减运算符(++、--):通过这些运算符可以将迭代器向前或向后移动。例如,iter++ 表示将迭代器 iter 向后移动一个位置,而 ++iter 表示将迭代器向前移动一个位置。
  3. 算术运算符(+、-、+=、-=):通过这些运算符可以实现迭代器的加减操作。例如,iter+n 表示将迭代器 iter 向后移动 n 个位置,而 iter-n 表示将迭代器向前移动 n 个位置。
  4. 比较运算符(==、!=、<、>、<=、>=):通过这些运算符可以比较两个迭代器的相对位置。例如,iter1 == iter2 表示两个迭代器指向同一个元素,而 iter1 < iter2 表示 iter1 在 iter2 之前。
  5. distance 函数:可以通过该函数计算两个迭代器之间的距离,即它们相差的元素个数。例如,distance(iter1, iter2) 返回迭代器 iter1 到 iter2 之间元素的个数。
  6. advance 函数:可以通过该函数将迭代器向前或向后移动指定的距离。例如,advance(iter, n) 表示将迭代器 iter 向后移动 n 个位置,而 advance(iter, -n) 表示将迭代器向前移动 n 个位置。
  7. 迭代器交换(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;
}

相关推荐

从IDEA开始,迈进GO语言之门(idea got)

前言笔者在学习GO语言编程的时候,GO语言在国内还没有像JAVA/Php/Python那样普及,绕了不少的弯路,要开始入门学习一门编程语言,最好就先从选择一个好的编程语言的开发环境开始,有了这个开发环...

基于SpringBoot+MyBatis的私人影院java网上购票jsp源代码Mysql

本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍基于SpringBoot...

基于springboot的个人服装管理系统java网上商城jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍基于springboot...

基于springboot的美食网站Java食品销售jsp源代码Mysql

本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍基于springboot...

贸易管理进销存springboot云管货管账分析java jsp源代码mysql

本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目描述贸易管理进销存spring...

SpringBoot+VUE员工信息管理系统Java人员管理jsp源代码Mysql

本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目介绍SpringBoot+V...

目前见过最牛的一个SpringBoot商城项目(附源码)还有人没用过吗

帮粉丝找了一个基于SpringBoot的天猫商城项目,快速部署运行,所用技术:MySQL,Druid,Log4j2,Maven,Echarts,Bootstrap...免费给大家分享出来前台演示...

SpringBoot+Mysql实现的手机商城附带源码演示导入视频

今天为大家带来的是基于SpringBoot+JPA+Thymeleaf框架的手机商城管理系统,商城系统分为前台和后台、前台用的是Bootstrap框架后台用的是SpringBoot+JPA都是现在主...

全网首发!马士兵内部共享—1658页《Java面试突击核心讲》

又是一年一度的“金九银十”秋招大热门,为助力广大程序员朋友“面试造火箭”,小编今天给大家分享的便是这份马士兵内部的面试神技——1658页《Java面试突击核心讲》!...

SpringBoot数据库操作的应用(springboot与数据库交互)

1.JDBC+HikariDataSource...

SpringBoot 整合 Flink 实时同步 MySQL

1、需求在Flink发布SpringBoot打包的jar包能够实时同步MySQL表,做到原表进行新增、修改、删除的时候目标表都能对应同步。...

SpringBoot + Mybatis + Shiro + mysql + redis智能平台源码分享

后端技术栈基于SpringBoot+Mybatis+Shiro+mysql+redis构建的智慧云智能教育平台基于数据驱动视图的理念封装element-ui,即使没有vue的使...

Springboot+Mysql舞蹈课程在线预约系统源码附带视频运行教程

今天发布的是由【猿来入此】的优秀学员独立做的一个基于springboot脚手架的Springboot+Mysql舞蹈课程在线预约系统,系统项目源代码在【猿来入此】获取!https://www.yuan...

SpringBoot+Mysql在线众筹系统源码+讲解视频+开发文档(参考论文

今天发布的是由【猿来入此】的优秀学员独立做的一个基于springboot脚手架的在线众筹管理系统,主要实现了普通用户在线参与众筹基本操作流程的全部功能,系统分普通用户、超级管理员等角色,除基础脚手架外...

Docker一键部署 SpringBoot 应用的方法,贼快贼好用

这两天发现个Gradle插件,支持一键打包、推送Docker镜像。今天我们来讲讲这个插件,希望对大家有所帮助!GradleDockerPlugin简介...

取消回复欢迎 发表评论: