迭代器(iterator)

xiaoxiao2021-02-28  51

迭代器介绍

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

使用迭代器

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)某个迭代器对象

转载请注明原文地址: https://www.6miu.com/read-2629839.html

最新回复(0)