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的中心思想在于:将数 ...
随机推荐
- C#中通过反射获取类中非公有成员
public class NGlbGlobeXComm { public static T GetPrivateField<T>(object instance, string field ...
- Scala 基础新手教程
1.前言 近期在參加Hadoop和Spark培训.须要使用Scala,自学了一下作为入门.这里作一个记录. 2.下载 1) 在scala官网下载.地址: http://www.scala-lang.o ...
- 音频单元组件服务参考(Audio Unit Component Services Reference)
目录 了解Audio Unit体系结构 文档结构预览 结构单元介绍 本文主要介绍AudioUnit的组成 本文由自己理解而成,如有错误,请欢迎网友们指出校正. 了解Audio Unit体系结构 开始前 ...
- 【Access2007】Access2007的打开方式
Access2007提供了多种打开方式 仅仅读与非仅仅读就不用说了,就是能编辑与不可以编辑的差别 是否以独占的方式打开是Access2007的打开方式的核心 这里什么都没有写的打开是指以"共 ...
- mysqldump导入导出详解
mysqldump可以指定路径的,如果没指定路径,而只写了文件名的话,那么就在当前进入mysql命令行所在的目录,也就是mysql安装目录下 mysqldump --default-characte ...
- upstart man
man upstart nit(8) init(8) NAME init - Upstart process management daemon SYNOPSIS init [OPTION]... D ...
- 每天一个linux命令(23):Linux 目录结构(转)
对于每一个Linux学习者来说,了解Linux文件系统的目录结构,是学好Linux的至关重要的一步.,深入了解linux文件目录结构的标准和每个目录的详细功能,对于我们用好linux系统只管重要,下面 ...
- [网页游戏开发]Morn简介及使用教程
网页游戏开发利器,morn系列教程之Morn简介及使用教程 网页游戏开发的一大部分工作是在和UI制作上,一个好的工具及框架能使开发事半功倍,Adobe自带flash IDE和Flex各有不足. Mor ...
- pygame 安装教程
步骤: 1.去官网下载PyGame 注意:要下载对应版本的包 官网地址:http://www.pygame.org/download.shtml 其中,如果python为以下版本: python 3. ...
- r testifying that your code will behave as you intend.
https://github.com/stretchr/testify Testify - Thou Shalt Write Tests Go code (golang) set of pack ...