首页 > 代码库 > C++学习笔记(十):迭代器

C++学习笔记(十):迭代器

我们都知道可以用下标运算来访问string对象和vector对象。而另外还有一种更通用的方法也可以实现这样的方法。名曰:迭代器(iterator)。

类似于指针,迭代器也提供了对对象的间接访问。就迭代器而言,其对象是容器中的元素或者string中的字符。使用迭代器可以访问某个元素,迭代器也能从一个元素移动到另外一个元素。迭代器有有效和无效之分,有效的迭代器指向某个元素或者容器中尾元素的下一个位置。其他情况均为无效。

和指针不一样的是,迭代器不是使用取址符,而是使用beginend成员。

如下:

auto  a = v.begin(),  b = v.end();

这里的a表示v的第一个元素,b表示v的最后一个元素的下一位置的元素。

注:end成员返回指向容器“尾元素的下一个位置”的迭代器,也就是说这个迭代器指示的内容是一个根本不存在的元素,有时候也称为尾后迭代器。这个迭代器没有什么实际含义,仅仅是个标记而已,表示我们已经处理完容器中的所有元素。如果容器为空,那么beginend返回的是同一个迭代器。

一般来说,我们可能不清楚迭代器的类型是什么,那么使用auto关键字定义变量即可,如上面的例子就是使用这种方法。

 

迭代器的运算符:

*iter       返回迭代器所指向的元素的引用

iter->mem  获取元素的成员。等价于(*iter.mem

++iter     指向容器的下一个元素

--iter      指向容器的上一个元素 

==和!=   如果两个迭代器指向的元素相同后者都指向同一个容器的尾后迭代器,则相等

        

和指针相类似,迭代器也能够通过接引用迭代器来获取它所指示的元素,执行解引用的迭代器必须合法并确实指示着某个元素。试图解引用一个非法的迭代器或者尾后迭代器都是非法的行为。

下面给个例子如下:

string  s(“good job”)
if(s.begin() != s.end()){  //确保S为非空的字符串

auto it = s.begin();   //it表示s的第一个字符

*it = toupper( *it )   //将字符串的第一个字符改成大写,这里必须要用引用,否则操作失败

}   

 

结合解引用和成员访问操作

解引用迭代器可以获得迭代器所指的对象,如果该对象的类型恰好是类,那么就可以访问这个类的成员。例如:

(*it).enpty();

这里要注意*it一定要加圆括号,否则会出错。如果不加,那么这句话的意思就变成了访问itempty成员,但是it是个迭代器,没有empty成员。C++11中提供了箭头运算符->,箭头运算符把解引用和成员访问两个操作结合在了一起。故iter->mem 等价于(*iter.mem

强烈注意:一旦使用了迭代器的循环体,那就不要向迭代器所属的容器添加元素。

 

迭代器的算术运算:

iter + n    迭代器加上一个整数后仍是一个迭代器,在这里迭代器和指针很像,可以理解成地址上的加减。

iter1 - iter2 两个迭代器相减的结果是它们之间的距离。即所指向位置的距离。

<,<=,>,>=  迭代器关系运算符,如果某迭代器指向的容器位置在另一个迭代器所指位置之前,则说前者小于后者。

 

C++学习笔记(十):迭代器