C++之STL迭代器
迭代器是一种检查容器内元素并遍历元素的数据类型。可以替代下标访问vector对象的元素。
每种容器类型都定义了自己的迭代器类型,如 vector:
- vector<int>::iterator iter;
这符语句定义了一个名为 iter 的变量,它的数据类型是 vector<int> 定义的 iterator 类型。每个标准库容器类型都定义了一个名为 iterator 的成员,这里的 iterator 与迭代器实际类型的含义相同。
begin 和 end 操作
- vector<int>::iterator iter = ivec.begin();
上述语句把 iter 初始化为由名为 vector 操作返回的值。假设 vector 不空,初始化后,iter 即指该元素为 ivec[0]。由 end 操作返回的迭代器指向 vector 的“末端元素的下一个”。表明它指向了一个不存在的元素。如果 vector 为空,begin 返回的迭代器与 end 返回的迭代器相同。由 end 操作返回的迭代器并不指向 vector 中任何实际的元素,相反,它只是起一个哨兵(sentinel)的作用,表示我们已处理完 vector 中所有元素。
vector 迭代器的自增和解引用运算
- *iter = 0;
解引用操作符返回迭代器当前所指向的元素。假设 iter 指向 vector 对象 ivec 的第一元素,那么 *iter 和 ivec[0] 就是指向同一个元素。上面这个语句的效果就是把这个元素的值赋为 0。
迭代器使用自增操作符向前移动迭代器指向容器中下一个元素。从逻辑上说,迭代器的自增操作和 int 型对象的自增操作类似。对 int 对象来说,操作结果就是把 int 型值“加 1”,而对迭代器对象则是把容器中的迭代器“向前移动一个位置”。因此,如果 iter 指向第一个元素,则 ++iter 指向第二个元素。
迭代器的其他操作
迭代器应用的程序示例
1、使用迭代器和下标改变vector的内容
- #include <iostream>
- #include <string>
- #include <vector>
- int print_int_vector(std::vector<int> ivec)
- {
- for(std::vector<int>::size_type ix =0, j = 0; ix != ivec.size(); ++ix, ++j)
- {
- std::cout<<ivec[ix]<<" "; //加空格!
- }
- std::cout<<std::endl;
- return 0;
- }
- int main()
- {
- std::vector<int> ivec(10, 68); // empty vector
- print_int_vector(ivec);
- // reset all the elements in ivec to 0
- /*
- // 使用下标
- for (std::vector<int>::size_type ix = 0; ix != ivec.size(); ++ix)
- {
- ivec[ix] = 0;
- }
- */
- // equivalent loop using iterators to reset all the elements in ivec to 0
- for (std::vector<int>::iterator iter = ivec.begin(); iter != ivec.end(); ++iter)
- *iter = 0; // set element to which iter refers to 0
- print_int_vector(ivec);
- return 0;
- }
2、tuple功能的实现【不可变性】
当我们对普通 iterator 类型解引用时,得到对某个元素的非 const。而如果我们对 const_iterator 类型解引用时,则可以得到一个指向 const 对象的引用),如同任何常量一样,该对象不能进行重写。
- vector<int> nums(10); // nums is nonconst
- const vector<int>::iterator cit = nums.begin();
- *cit = 1; // ok: cit can change its underlying element
- ++cit; // error: can't change the value of cit
【注意:const_iterator 对象可以用于 const vector 或非 const vector,因为不能改写元素值。const 迭代器这种类型几乎没什么用处:一旦它被初始化后,只能用它来改写其指向的元素,但不能使它指向任何其他元素。】
总结
迭代器的算术操作
- int main()
- {
- std::vector<int> ivec(10, 68);
- print_int_vector(ivec);
- int i = 0;
- for (std::vector<int>::iterator iter = ivec.begin(); iter != ivec.end(); ++iter, i++)
- *iter = i; // set element to which iter refers to i
- print_int_vector(ivec);
- std::vector<int>::iterator iter = ivec.begin();
- iter += 100;
- std::cout<<*iter;
- return 0;
- }
本例子中ivec有10个元素,iter+=j,j在10以内都不会有错(0~9),大于等于10则会出现溢出问题,编译器,运行中间都不会报错!可以加当然可以减。
- vector<int>::iterator mid = vi.begin() + vi.size() / 2;
上述代码用来初始化 mid 使其指向 vi 中最靠近正中间的元素。这种直接计算迭代器的方法,与用迭代器逐个元素自增操作到达中间元素的方法是等价的,但前者的效率要高得多。
- *iter = i; // set element to which iter refers to i
- ivec.push_back(i*2);
加上这句代码没问题,正确运行,但是,我们试图在for循环里面执行,即:
- {
- *iter = i; // set element to which iter refers to i
- ivec.push_back(i*2);
- }
则会莫名其妙退出!
C++之STL迭代器的更多相关文章
- STL迭代器笔记
STL迭代器简介 标准模板库(The Standard Template Library, STL)定义了五种迭代器.下面的图表画出了这几种: input output \ ...
- 一步一步的理解C++STL迭代器
一步一步的理解C++STL迭代器 "指针"对全部C/C++的程序猿来说,一点都不陌生. 在接触到C语言中的malloc函数和C++中的new函数后.我们也知道这两个函数返回的都是一 ...
- STL 迭代器 iterator const
STL迭代器很多时候可以当成指针来使用. 但是指针一般可以用const来控制访问. 那迭代器呢. #include <iostream> #include <vector> u ...
- STL迭代器的使用、正向、逆向输出双向链表中的所有元素
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...
- 【STL 源码剖析】浅谈 STL 迭代器与 traits 编程技法
大家好,我是小贺. 点赞再看,养成习惯 文章每周持续更新,可以微信搜索「herongwei」第一时间阅读和催更,本文 GitHub : https://github.com/rongweihe/Mor ...
- STL迭代器之一:偏特化
在stl的算法中运用容器的迭代器时,很可能经常会用到迭代器相应型别(例如迭代器所指物的型别),假设算法中有必要声明一个变量,以"迭代器所指对象的型别"为类型,如何是好,例如我们写一 ...
- C++ STL 迭代器失效问题
之前看<C++ Primier>的时候,也解到在顺序型窗口里insert/erase会涉及到迭代器失效的问题,并没有深究.今天写程序的时候遇到了这个问题. 1 莫名其妙的Erase 最初我 ...
- stl 迭代器(了解)
STL 主要是由 containers(容器),iterators(迭代器)和 algorithms(算法)的 templates(模板)构成的. 对应于它们所支持的操作,共有五种 iterators ...
- stl迭代器原理
具体实现肯定不如书上讲的清楚了,这里只是根据侯捷书上的讲解,自己建立一条思路以及形成一些相关的概念 迭代器也可被称作智能指针,用于遍历容器内的元素,stl每个容器都实现了自己的iterator,ite ...
- STL——迭代器的概念
迭代器是一种抽象的设计概念,现实程序语言中并没有直接对应于这个概念的实物. 1 迭代器设计思维——STL关键所在 不论是泛型思维或STL的实际运用,迭代器都扮演这重要的角色.STL的中心思想在于:将数 ...
随机推荐
- 关于position的小总结
position:relative/absolute/fixed/static ...... relative:相对定位. 脱离标准流,相对自己原来(标准流)的位置定位.absolute:绝对定位. ...
- crtmp Server 开启rtsp服务功能
Crtmp Server 包含了rtsp 服务功能,如果需要一个简单轻量的rtsp服务,Crtmp Server会是不错的选择. 默认情况下,rtsp功能是关闭的,需要在配置文件中打开.window环 ...
- orcad元件属性批量修改(通过excel表格)
本文适合于没有使用CIS的情况下,提高元件属性修改的效率和BOM生成. 第一步:编号 首先给元件编好号: 如果是沿用旧工程,用这个编号.如果是创建的新工程,使用第二项,强制从头开始编号.因为编号与PC ...
- Android中Environment与StatFs获取系统/SDCard存储空间大小
近期想起Android开发的知识.好久没有使用了,都忘得几乎相同了,今天查看了一会资料往回捡捡,顺便写下来帮助一下须要的同学. 首先讲述一下Environment与StatFs这两个类,然后介绍它们的 ...
- Django-form组件补充
首先来看一个用户登录的实例 from django.forms import Form from django.forms import fields from django.forms import ...
- Jquery 插件 实例
先说明下应用场景,通过可配项的配置和默认项覆盖,获取指定的需求数据,填充到指定的位置(两个指定其实都是可配的) (function($) { $.fn.extend({ getOneNews: fun ...
- iOS UILabel文字缩进
使用NSMutableParagraphStyle实现label文字首尾的缩进 NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphSty ...
- ffmpeg编码常见问题排查方法
播放问题排查: 一旦我们遇到视频播放不了,第一件事,就是要找几个别的播放器也播放看看,做一下对比测试,或者对码流做一些基础分析,以便更好的定位问题的源头,而各个平台比较常见的播放/分析工具有如下几个: ...
- vs2005 未能完成操作。未指定的错误
具体解决过程是这样的: 1.先把.vcproj 文件剪切到其他地方 2.打开.sln,报错->点“确定”->再点“确定” 3.把 .vcproj 文件 放回来,在vs2008右边的“解决方 ...
- EasyHLS实现将IPCamera摄像机的RTSP转HLS直播输出
EasyHLS EasyHLS是EasyDarwin开源流媒体团队开发的一款HLS打包库,接口非常简单,只需要传入打包的文件名.切片存放的目录.单个切片时长以及切片数等参数,EasyHLS库就能轻松将 ...