迭代器

来源:互联网 发布:hash 源码 编辑:程序博客网 时间:2024/06/17 17:34

3.4 迭代器

我们可以通过下标运算符[]访问string对象的字符或vector对象的元素,但还有一种更通用的机制也可以实现:那就是 迭代器(iterator) 所有标准容器都可以使用迭代器,但是其中只有少数几种同时支持下标运算符。
类似于指针类型,迭代器也提供对对象的间接访问。但是迭代器也分为有效迭代器和无效迭代器。有效迭代器:指向某个元素或者指向容器中尾元素的下一个位置。无效迭代器:反之,都是无效迭代器。

3.4.1使用迭代器

和指针不一样:获取迭代器不是使用取值运算符&,有迭代器的类型同时返回迭代器的成员。
auto b = v.begin();     //返回指向v中第一个元素(或第一个字符)的迭代器auto e =v.end();        //返回指向v中“尾部元素的下一个位置”的迭代器 

注: end()函数返回的迭代器指向容器中的一个根本不存在的“尾后”元素,这样的迭代器其实没什么实际含义,只不过为了做标记而已。 end()函数返回的的迭代器常称作:“尾后迭代器”
特殊情况下:如果容器为空,则begin和end返回的是同一个迭代器,都是尾后迭代器。


迭代器运算符


运算符 解释 iter->mem 解引用iter并获取该元素的名为mem的成员,等价于
(*item).men *iter 返回迭代器iter所指元素的引用 ++iter 令iter指示容器中下一个元素 –iter 令iter指示容器中上一个元素 iter1 ==iter2
iter1 != iter2 判断两个迭代器是否相等(不等),如果两个迭代器指向
同一个元素或者他们是同一个容器的尾后迭代器,则相等,
反之,不等。
//依次处理s的字符,直到处理完全部字符或者遇到空白for(auto it = s.begin(); it != s.end() && !isspace(*it); ++it){        *it = toupper(*it);   //将当前字符改写成大写}//因为end返回的迭代器并不实际指示某个元素,所以不能对其进行递增或解引用的操作//注意for循环中使用的是 != 而不是 </*因为之前说过,只有string和vector等一些标准库类型有下标运算符,而非全都如此。与之类似,所有标准库容器的迭代器都定义了 == 和 !=,但是他们中的大多数都没定义 < 运算符。因此只要我们养成使用迭代器和 !=的习惯,就不用太在意到底用哪种容器类型*/

迭代器类型

  • iterator
  • const_iterator

vector<int>::iterator it;           //it能读写vector<int>的元素string::iterator it2;               //it2能读写string对象中的字符vector<int>::const_iterator it3;    //it3只能读元素,不能写元素string::const_iterator it;          //it4只能读字符,不能写字符

注:
- 如果vector对象或者string对象是一个常量,只能使用 const_iterator
- 如果vectror对象或者string对象不是一个常量,那么即可以使用iterator 也可以使用const_iterator


begin和end运算符

begin 和 end 返回的具体类型由对象是不是常量决定
- 对象是常量,返回const_iterator
- 对象是变量,返回iterator

vector<int> v;const vector<int>cv;auto it1 = v.begin();   //it1的类型是vector<int>::iteratorauto it2 = cv.begin();  //it2的类型是vector<int>::const_iterator

然而有时候,如果对象只需要都操作,不需要写操作,那我们会好使用常量类型。
C++11引入:cbegin 和 cend

vector<int> v;          //对象不是常量。让它返回常量类型auto it1 = v.cbegin();  //it1的类型是vector<int>::const_iterator

某些对vector对象的操作会使迭代器失效

  1. 不能在范围for循环中向vector对象添加元素
  2. 任何一种可能改变vector对象容量的操作,比如push_back 都会使vector对象的迭代器失效。
    但凡使用了迭代器的循环体,都不要向迭代器所属的容器中添加元素

3.4.2 迭代器运算

所有的标准库容器都有支持递增运算的迭代器,类似的,也能用 ==和 !=对任意标准库类型的两个有效迭代器进行比较

vector和string
迭代器支持的运算 解释 iter + n 迭代器加上一个整数仍得一个迭代器,向前移动了若干个元素。结果
迭代器或者指向容器中的一个元素,或者指向容器尾元素的下一个位置 iter - n 迭代器减去一个整数仍得一个迭代器,向前移动了若干个元素。结果
迭代器或者指向容器中的一个元素,或者指向容器尾元素的下一个位置 iter1 += n iter1 = iter1 + n iter1 -= n iter1 = iter1 - n iter1 - iter2 两个迭代器相减的结果是它们之间的距离 < ,>= ,<,<=
auto mid = vi.begin() + vi.size()/2;//计算得到会接近vi中间元素的一个迭代器

两个迭代器的距离:指的是 右侧的迭代器向前移动多少个位置就能追上左侧的迭代器。
类型: difference_type 的带符号整数,因为这个距离可正可负。
string 和 vector都定义了 difference_type

原创粉丝点击