C/C++迭代器使用详解
迭代器是一种检查容器内元素并遍历元素的数据类型。可以替代下标访问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); }则会莫名其妙退出!
本文由@The_Third_Wave(Blog地址:http://blog.csdn.net/zhanh1218)原创。由于还有部分内容没有接触,只讲了大概没有原因,会不定期更新,有错误请指正。
如果你看到这篇博文时发现没有不完整,那是我为防止爬虫先发布一半的原因,请看原作者Blog。
如果这篇博文对您有帮助,为了好的网络环境,不建议转载,建议收藏!如果您一定要转载,请带上后缀和本文地址
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。