0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

简单介绍C++中迭代器

jf_78858299 来源:QStack 作者: 月下西楼 2023-03-17 14:03 次阅读

前言

之前的两篇文章我们主要了解了vector和string的相关知识,从中我们知道可以通过下标来访问vector的元素或者string的字符,但是除了这种方式还有一种更为通用的方式获取元素,那就是迭代器,这篇文章就会简单介绍迭代器的相关内容。

迭代器简介

在我们使用容器去存储元素的时候有时候会需要获取存储的元素,而迭代器就是用于从容器中获取元素的,基本上所有容器的库都支持迭代器,但是只有其中一小部分支持下标获取元素的。虽然string不是容器但是其支持很多容器的操作,其中就包括下标和迭代器。

与指针类似,迭代器提供了一种间接获取对象的方式,对于迭代器而言,这个对象就是容器中的元素或者string中的字符,我们可以通过迭代器获取一个元素,与此同时也可以将指向的对象从一个对象移到下一个对象。迭代器还和指针一样有有效和无效之分,所有代表容器中元素或最后一个元素的下一个位置都是有效的,其他所有的迭代器都是无效的。

迭代器的使用

不像指针,我们不使用地址操作符去获取一个迭代器,每一个支持迭代器的类型都有函数可以返回迭代器,这些类型都有名为begin和end的函数,begin返回的是代表第一个元素的迭代器,end的返回的迭代器是容器或者字符串的最后一个元素的下一个位置,这个迭代器代表着最后一个元素的下一个位置,是一个不存在的元素。如果容器为空,则begin和end返回的是同一个迭代器。

auto b = v.begin(), e = v.end()

迭代器的操作

迭代器只支持下表列出来的操作,我们可以通过==或!=比较两个有效的迭代器,如果迭代器代表着同一个元素或者都是最后一个元素的下一个位置则相等,否则它们不等。 |操作|解释| |*iter|返回迭代器代表的指针指向的值| |iter->mem|等价于(*iter).mem| |++iter|指向容器中的下一个元素| |--iter|指向容器中的前一个元素| |iter1 == iter2|判断两个迭代器是否相等| |iter1 != iter2|判断两个迭代器是否不等|

对于指针,我们可以使用解引用符获取一个迭代器的元素,和指针相同,我们只能通过解引用符获取一个有效的迭代器的元素,如果解引用一个最后一个元素之后的迭代器结果是未知的。

# include
# include
using namespace std;


int main() {
  string s("some string");
  if (s.begin() != s.end()) {
    auto it = s.begin();
    *it = toupper(*it);
  }
  cout<

上述的例子就是通过迭代器获取字符串s的首个字符并将其大写。

迭代器从一个元素移动到另一个元素

迭代器私用自增操作符从一个元素移动到该元素的下一个元素,自增一个迭代器与自增一个整型十分类似,对于整型而言,自增的是其本身的值,对于迭代器而言,其影响是往前进一个位置。

❝由于end返回的不是一个元素,所以其不能自增或者解引用

使用自增操作我们可以重写之前的程序:

# include
# include
using namespace std;


int main() {
  string s("some string");
  for (auto it = s.begin(); it != s.end() && !isspace(*it); ++it) {
    *it = toupper(*it);
  }
  cout<

如上例所示,我们通过迭代器可以实现循环遍历。

迭代器的类型

正如我们并不准确知道vector的准确类型或者string的size,同样的,我们也不知道同时也不需要知道迭代器的准确类型,但是根据迭代器的读写权限定义了以下几种迭代器的类型:

vector<int>::iterator it; //it可以读也可以写vector
  string::iterator it2; //it2可以读写字符串里的字符
  vector<int>::const_iterator it3; //it3可以读但是不可以写元素
  string::const_iterator it4; //it4可以读但是不可以写字符串里面的字符

const_iterator表现就像是常量指针,可以读取元素但是不能写元素

begin和end操作

begin和end返回的结果取决于它们操作的对象是不是常量,如果操作对象是常量,那么begin和end返回的就是const_iterator,如果对象不是常量,那么返回的就是iterator。

# include
# include
# include
using namespace std;


int main() {
vector<int> v;
const vector<int> cv;
auto it1 = v.begin(); //it返回的是vector
auto it2 = v.begin(); //it返回的是vector
}

这种默认的返回策略有时候并不满足需求,在一些情况下一些非常量的vector我们只想读取元素,避免元素被更改,在C++11中提供了以下新的方法cbegin和cend,无论vetor是不是常量都返回const_iterator。

auto it3 = v.cbegin();

迭代器的数学运算

处理之前提到自增和自减外,迭代器还支持以下数学运算,虽然迭代器是没有下标的概念的,但是一下运算都可以理解为是对于下标的操作,如加减就是自增和自减的普通形式,就是向前移动或者向后移动,大小比较就是前后位置的比较。

操作 解释
iter + n 同一个容器向前移动n
iter - n 同一个容器向后移动
iter1 += n 将移动结果赋值给iter1
iter1 -= n 将移动结果赋值给iter1
>, >=, <, <= 相对位置的比较

这么说起来可能又带你抽象,下面用一个二分法来说明:

# include
# include
# include
using namespace std;


int main() {
  vector<int> v = {1, 2, 3, 4, 5};
  auto beg = v.begin(), end = v.end();
  auto mid = v.begin() + (end - beg) / 2;
  int target = 2;
  while (mid != end && *mid != target)
  {
    if (target < *mid) {
      end = mid;
    } else{
      beg = mid;
    }
    mid = beg + (end - beg) / 2;
  }
  cout<<to_string(*mid)<

以上例子会打印2,也就是元素2的位置。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C++
    C++
    +关注

    关注

    21

    文章

    2094

    浏览量

    73446
  • Vector
    +关注

    关注

    3

    文章

    53

    浏览量

    8541
  • 迭代器
    +关注

    关注

    0

    文章

    43

    浏览量

    4296
收藏 人收藏

    评论

    相关推荐

    C语言和C++那些不同的地方

    ++11标准。根据不同的标准,它们的功能也会有所不同,但是越新的版本支持的编译越少,所以本文在讨论的时候使用的C语言标准是C89,C++标准是C
    的头像 发表于 12-07 14:29 882次阅读
    <b class='flag-5'>C</b>语言和<b class='flag-5'>C++</b><b class='flag-5'>中</b>那些不同的地方

    js迭代异步介绍

    js 迭代 异步 介绍 (Introduction)It’s been a long while coming and I feel it’s high time I made a post
    发表于 09-06 09:26

    CodeWarrior C and C++ and Assembly 语言参考设计

    本文是英文版的,介绍了CodeWarrior C and C++ and Assembly 语言参考设计,在您的设计或许有用:
    发表于 06-22 15:33 74次下载

    C++C/C++程序设计教程_C/C++概述

    C++基础知识,简要介绍C++的一些简单知识,概念,函数
    发表于 12-25 10:15 0次下载

    C++入门教程之C++程序设计的课件资料免费下载

    本文档的主要内容详细介绍的是C++入门教程之C++程序设计的课件资料免费下载主要内容包括了:1. 认识C++2. C++的现状和发展3.
    发表于 12-07 08:00 33次下载
    <b class='flag-5'>C++</b>入门教程之<b class='flag-5'>C++</b>程序设计的课件资料免费下载

    Visual C++教程之C++的基础知识介绍

    本文档的主要内容详细介绍的是Visual C++教程之C++的基础知识介绍主要内容包括了:1 类和对象,2 类的成员及特性,3 继承和派生类
    发表于 02-15 15:59 9次下载
    Visual <b class='flag-5'>C++</b>教程之<b class='flag-5'>C++</b>的基础知识<b class='flag-5'>介绍</b>

    C++程序设计的基础知识初步了解C++的资料免费下载

    本文档的主要内容详细介绍的是C++程序设计的基础知识初步了解C++的资料免费下载包括了:1 认识C++,2 C++的现状和发展,3
    发表于 06-10 08:00 25次下载
    <b class='flag-5'>C++</b>程序设计的基础知识初步了解<b class='flag-5'>C++</b>的资料免费下载

    EE-128:C++的DSP:从C++调用汇编类成员函数

    EE-128:C++的DSP:从C++调用汇编类成员函数
    发表于 04-16 17:04 2次下载
    EE-128:<b class='flag-5'>C++</b><b class='flag-5'>中</b>的DSP:从<b class='flag-5'>C++</b>调用汇编类成员函数

    IAR中使用C++做开发语言,更加简单高效

    本文简要介绍了如何在IAR配置C++开发环境,由于C++的封装支持,引入面向对象的开发思路可以使得用C++进行单片机获得更高的开发效率
    发表于 12-03 11:36 4次下载
    IAR中使用<b class='flag-5'>C++</b>做开发语言,更加<b class='flag-5'>简单</b>高效

    C++的引用和指针

    之前的文章我们已经介绍C++的基本类型如int,bool和double等,除了基本类型C++还有一些更复杂的数据类型复合类型,所谓的复合类型就是通过其他类型定义的类型,本篇文章我们
    的头像 发表于 03-17 14:00 596次阅读

    C++的const关键字介绍

    前一篇文章我们主要介绍C++的复合类型引用和指针,这篇文章我们将会主要介绍C++const
    的头像 发表于 03-17 14:01 614次阅读

    C++的输入流和输出流介绍

    C++的输入流和输出流是C++标准库的两个重要的流类,分别用于输入和输出数据。在本篇博客,我们将详细介绍
    的头像 发表于 04-30 17:58 1991次阅读

    C++入门之通用算法

    C++ 是一种强大的编程语言,它提供了许多通用算法,可以用于各种容器类型。这些算法是通过迭代来操作容器的元素,因此它们是通用的,可以用于不同类型的容器。在本篇博客
    的头像 发表于 05-17 09:40 612次阅读

    C++简史:C++是如何开始的

    MISRA C++:2023,MISRA® C++ 标准的下一个版本,来了!为了帮助您做好准备,我们介绍了 Perforce 首席技术支持工程师 Frank van den Beuken 博士撰写
    的头像 发表于 01-11 09:00 508次阅读
    <b class='flag-5'>C++</b>简史:<b class='flag-5'>C++</b>是如何开始的

    C++实现类似instanceof的方法

    函数,可实际上C++没有。但是别着急,其实C++中有两种简单的方法可以实现类似Java的instanceof的功能。 在
    的头像 发表于 07-18 10:16 480次阅读
    <b class='flag-5'>C++</b><b class='flag-5'>中</b>实现类似instanceof的方法