迭代器(iterator)

迭代器介绍

类似于指针类型,迭代器也提供对对象的间接访问。


使用迭代器

1.有迭代器的类型同时拥有返回迭代器的成员,如名为begin和end的成员。
//由编译器决定b和e的类型
//b表示v的第一个元素,e表示v尾元素的下一个位置(one past the end)
auto b = v.begin(), e = v.end();//b和e的类型相同

end成员返回的迭代器常被称作尾后迭代器(off-the-end iterator)或者简称为尾迭代器(end iterator),这样的迭代器没有实际含义,仅是个标记而已,表示我们已经处理完了容器中的所有元素。

note : (1)若容器为空,则begin和end返回的是同一个迭代器,都是尾后迭代器;

          (2)一般来说,我们不清楚迭代器准确的类型,故用auto。

2.迭代器运算符,这里省略迭代运算符的列举。和指针类似,也能通过解引用迭代器来获取它所指示的元素,但试图解引用一个非法迭代器或尾后迭代器都是未被定义的行为。

string s("some string")
if(s.begin() != s.end())  //确保s非空
{
   auto it = s.begin();   //
   *it = toupper(*it);    //将当前字符改成大写形式
}

3.将迭代器从一个元素移动到另一个元素,即使用递增(++)运算符

//依次处理s的字符直到完全处理全部字符或遇到空白
for(auto it = s.begin(); it != s.end() && !isspace(*it); ++it)
   *it = toupper(*it);//

上循环遍历没有用下标运算符,这里用的是迭代器。

note : 不能对end返回的迭代器进行递增或解引用操作。

4.关于迭代器类型,那些拥有迭代器的标准库类型使用iterator和const_iterator来表示迭代器的类型:

vector<int>::iterator it; //it能读写vector<int>的元素
string::iterator it2;     //it2能读写string对象中的字符

vector<int>::const_iterator it3; //it3只能读元素,不能写元素
string::const_iterator it4;      //it4只能读字符,不能写字符

note : (1)如果vector对象或string对象是一个常量,只能使用const_iterator。

          (2)每个容器类定义了一个名为iterator的类型,该类型支持迭代器概念所规定的一套操作。

5.begin和end运算符。begin和end返回的具体类型由对象是否是常量决定。为了便于专门得到const_iterator类型的返回值,C++11新标准引入两个新函数,cbegin和cend,此时不管对象是否是常量,返回值都是const_iterator。

auto it3 = v.cbegin();  //it3的类型是vector<int>::const_iterator

5.结合解引用和成员访问操作。解引用迭代器可获得迭代器所指的对象,若该对象的类型是类,则有可能希望进一步访问它的成员。例如,对于一个由字符串组成的vector对象来说,想要检查其元素是否为空,令it是该vector对象的迭代器,只要检查it所指字符串是否为空:

(*it).empty()    //解引用it,再调用结果对象的empty成员

为了简化上述表达式,C++语言定义了箭头运算符(->):

it->empty()    //语义与上式相同

下面举例说明:

//依此输出text的每一行直到遇到第一个空白行为止
for(auto it = text.cbegin(); it != text.cend() && !it->empty(); ++it)
   cout << *it << endl;

6.某些对vector对象的操作会使迭代器失效。虽然vector对象可以动态增长,但也会有一些side effects。

(1)不能在范围for循环中向vector对象中添加元素

(2)任何一种可能改变vector对象容量的操作,如push_back,都会使vector对象的迭代器失效。

note : 凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素。


迭代器运算(iterator arithmetic)

1.所有标准库容器都有支持递增运算和关系运算的迭代器,另外标准库类型string也有。下面举例:

iter + n        //迭代器指示的新位置与原来相比向前移动了n个元素
iter - n
iter1 += n
iter1 -= n
iter1 - iter2  /*两个迭代器之间的距离,其类型为difference_type的带符号整型数,string和vector都定                        义了这个类型*/

>,>=,<,<=   //迭代器的关系运算符

2.使用迭代器运算的一个经典算法是二分搜索。下面给出程序:

vector<string> text;
//text必须是有序的
//
auto beg = text.begin(), end = text.end();
auto mid = text.begin() + (end - beg)/2;
//
while(mid != end && *mid != sought)
{
     if(sought < *mid)
       end = mid;
     else
       begin = mid + 1;
     mid = beg + (end - beg)/2;
}


NOTE : 迭代器这个名词有3种不同的含义:

(1)迭代器概念本身

(2)容器定义的迭代器类型

(3)某个迭代器对象






  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值