C++迭代器的使用和操作总结
迭代器是一种检查容器内元素并遍历元素的数据类型。C++更趋向于使用迭代器而不是下标操作,因为标准库为每一种标准容器(如vector)定义了一种迭代器类型,而只用少数容器(如vector)支持下标操作访问容器元素。
一.定义和初始化
每种容器都定义了自己的迭代器类型,如vector:
vector<int>::iterator iter; //定义一个名为iter的变量
每种容器都定义了一对名为begin和en的函数,用于返回迭代器。下面对迭代器进行初始化操作:
vector<int> ivec;
vector<int>::iterator iter1=ivec.bengin(); //将迭代器iter1初始化为指向ivec容器的第一个元素 vector<int>::iterator iter2=ivec.end(); //将迭代器iter2初始化为指向ivec容器的最后一个元素的下一个位置
注意end并不指向容器的任何元素,而是指向容器的最后元素的下一位置,称为超出末端迭代器。如果vector为空,则begin返回的迭代器和end返回的迭代器相同。一旦向上面这样定义和初始化,就相当于把该迭代器和容器进行了某种关联,就像把一个指针初始化为指向某一空间地址一样。
二.常用操作
下面列出了迭代器的常用运算操作:
*iter //对iter进行解引用,返回迭代器iter指向的元素的引用
iter->men //对iter进行解引用,获取指定元素中名为men的成员。等效于(*iter).men
++iter //给iter加1,使其指向容器的下一个元素
iter++
--iter //给iter减1,使其指向容器的前一个元素
iter--
iter1==iter2 //比较两个迭代器是否相等,当它们指向同一个容器的同一个元素或者都指向同同一个容器的超出末端的下一个位置时,它们相等
iter1!=iter2
假设已经声明一个vector<int>的ivec容器,下面用迭代器来遍历ivec容器,把其每个元素重置为0:
for(vector<int>::iterator iter=ivec.begin();iter!=ivec.end();++iter)
*iter=;
在C++定义的容器类型中,只有vector和queue容器提供迭代器算数运算和除!=和==之外的关系运算:
iter+n //在迭代器上加(减)整数n,将产生指向容器中钱前面(后面)第n个元素的迭代器。新计算出来的迭代器必须指向容器中的元素或超出容器末端的下一个元素
iter-n iter1+=iter2 //将iter1加上或减去iter2的运算结果赋给iter1。两个迭代器必须指向容器中的元素或超出容器末端的下一个元素
iter1-=iter2 iter1-iter2 //两个迭代器的减法,得出两个迭代器的距离。两个迭代器必须指向容器中的元素或超出容器末端的下一个元素 >,>=,<,<= //元素靠后的迭代器大于靠前的迭代器。两个迭代器必须指向容器中的元素或超出容器末端的下一个元素
注意两个迭代器相减得出两个迭代器对象的距离,该距离名为difference_type的signed类型的值,该类型类似于size_type类型,也是有vector定义的。可以迭代器算术操作来移动迭代器直接指向某个元素:
vector<int>::iterator mid=v.begin()+v.size()/; //初始化mid迭代器,使其指向v中最靠近正中间的元素
三.迭代器const_iterator
每种容器还定义了一种名为const_iterator的类型。该类型的迭代器只能读取容器中的元素,不能用于改变其值。之前的例子中,普通的迭代器可以对容器中的元素进行解引用并修改,而const_iterator类型的迭代器只能用于读不能进行重写。例如可以进行如下操作:
for(vector<int>::const_iterator iter=ivec.begin();iter!=ivec.end();++iter)
cout<<*iter<<endl; //合法,读取容器中元素值 for(vector<int>::const_iterator iter=ivec.begin();iter!=ivec.end();++iter)
*iter=; //不合法,不能进行写操作
const_iterator和const iterator是不一样的,后者对迭代器进行声明时,必须对迭代器进行初始化,并且一旦初始化后就不能修改其值。这有点像常量指针和指针常量的关系。例如:
vector<int> ivec();
const vector<int>::iterator iter=ivec.begin();
*iter=; //合法,可以改变其指向的元素的值
++iter; //不合法,无法改变其指向的位置
四.使迭代器失效的操作
由于一些对容器的操作如删除元素或移动元素等会修改容器的内在状态,这会使得原本指向被移动元素的迭代器失效,也可能同时使其他迭代器失效。使用无效的迭代器是没有定义的,可能会导致和使用悬垂指针相同的问题。所以在使用迭代器编写程序时,需要特别留意哪些操作会使迭代器失效。使用无效迭代器会导致严重的运行时错误。
参考文献
《C++ PRIMER》 中文版
C++迭代器的使用和操作总结的更多相关文章
- C++ 迭代器的使用和操作
迭代器是一种检查容器内元素并遍历元素的数据类型.C++更趋向于使用迭代器而不是下标操作,因为标准库为每一种标准容器(如vector)定义了一种迭代器类型,而只用少数容器(如vector)支持下标操作访 ...
- 迭代器模式/iterator模式/对象行为型模式
意图 又名:游标(Cursor): 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示. 动机 一个聚合对象,提供访问元素的方法,而有不暴露它的内部结构.如list,将对列表的访问 ...
- 把《c++ primer》读薄(3-2 标准库vector容器+迭代器初探)
督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. 标准库vector类型初探,同一种类型的对象的集合(类似数组),是一个类模版而不是数据类型,学名容器,负责管理 和 存储的元素 ...
- STL迭代器之二:迭代器型别
如果一个迭代器要兼容stl,必须遵循约定,自行以内嵌型别定义的方式定义出相应型别.根据书中介绍,最常用到的迭代器型别有五种:value type,difference type, pointer, r ...
- STL的迭代器和类型萃取
今天就可以把STL库中迭代器的实现,和类型萃取好好整理一下了 迭代器的设计思维是STL的关键所在,在STL的实际运用和泛型思维,迭代器都扮演着十分重要的角色,STL力求把数据容器和算法的概念分开来,于 ...
- 深入浅出设计模式——迭代器模式(Iterator Pattern)
模式动机 一个聚合对象,如一个列表(List)或者一个集合(Set),应该提供一种方法来让别人可以访问它的元素,而又不需要暴露它的内部结构.针对不同的需要,可能还要以不同的方式遍历整个聚合对象,但是我 ...
- C++中的迭代器
C++STL中的迭代器 "指针"对所有C/C++的程序员来说,一点都不陌生.在接触到C语言中的malloc函数和C++中的new函数后,我们也知道这两个函数返回的都是一个指针,该指 ...
- iOS设计模式之迭代器模式
迭代器模式 基本理解 迭代器模式(Iterrator):提供一个方法顺序访问一个聚合对象中的各个元素,而又不暴露该元素的内部表示. 当你访问一个聚合对象,而且不管这些对象是什么都需要遍历的时候,你就应 ...
- C++ 迭代器 基础介绍
C++ 迭代器 基础介绍 迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围.迭代器就如同一个指针.事实上,C++的指针也是一种迭代器.但是,迭代器不仅仅是指针,因此你不能认为他们一定 ...
随机推荐
- 讨论MMU
MMU是Memory Management Unit的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器.物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制 ...
- dojo CsvStore简介
dojox.data.CsvStore 作者:Jared Jurkiewicz 版本:V1.0 CsvStore是由dojo提供的简单的只读存储,并且是包含在dojox项目中的.CsvStore是读取 ...
- StackExchange.Redis 二次封装
在NuGet直接搜索StackExchange.Redis,下载引用包: 帮助类: public class RedisUtils { /// <summary> /// redis配置文 ...
- 关于tween.js测试介绍
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>t ...
- freemarker写select组件(二十二)
一,讲解一 1.宏定义 <#macro select id datas> <select id="${id}" name="${id}"> ...
- ajax异步的问题,(主要解决有时候前台打断点和不打断点结果不一样的问题,一般情况下是存在异步的问题)
一,代码 $(function() { $(".btn-submit").click(function() { if(!checkData()){ return; } var ur ...
- PyTorch官方中文文档:torch
torch 包 torch 包含了多维张量的数据结构以及基于其上的多种数学操作.另外,它也提供了多种工具,其中一些可以更有效地对张量和任意类型进行序列化. 它有CUDA 的对应实现,可以在NVIDIA ...
- Redis之Zset
一.Redis之Zset简介 1. 有序集合Zset是String类型的有序集合. 2. Zset中每个元素都会关联一个double类型的分数值,redis通过分数值来为集合中所有成员进行从小到大排序 ...
- PHP 秒数 转时分秒 函数
function secondsToHour($seconds){ if(intval($seconds) < 60) $tt ="00时00分".sprintf(" ...
- 如何通过Spring Boot配置动态数据源访问多个数据库
之前写过一篇博客<Spring+Mybatis+Mysql搭建分布式数据库访问框架>描述如何通过Spring+Mybatis配置动态数据源访问多个数据库.但是之前的方案有一些限制(原博客中 ...