----------------迭代器介绍---------------
通过下标可以访问vector或者string类型对象的元素,还可以通过另外一种方式实现同样的目的------迭代器
获取迭代器不是使用取地址符&,因为有迭代器的类型同时拥有返回迭代器的成员函数,begin和end
例如:auto a = v.begin(),b = v.end(); //a和b的类型由begin和end的返回值决定
a指代第一个元素的位置,b指代尾元素的下一个位置,end返回的迭代器叫做尾后迭代器
如果容器为空,begin和end返回的是同一个迭代器,都是尾后迭代器
迭代器类型:
vector <int> :: iterator it; //可读写
string::iterator it; //可读写
vector <int> :: const_iterator it; //可读不可写
string::iterator const_it; //可读不可写
begin和end返回的具体类型由对象是否是常量决定,如果对象是常量,begin和end返回const_itreator;如果对象不是常量,返回iterator。如果对象只需要读操作而不需要写操作的话最好使用常量类型(const_iterator)。函数cbegin和cend返回值是const_iterator,与对象本身是否是常量无关。
解引用和成员访问:
(*a).empty(); //a是类型为string的vector的迭代器,通过这个语句可以查看a对应位置的元素是否为空
*a.empty(); //错误,必须加括号,点运算优先级大于解引用
a->empty(); //正确,与(*a).empty();意义相同
使得vector对象的迭代器失效的语句:
比如push_back,虽然能够让vector无限增长,但会使得end()返回的迭代器失效。
同时不能在范围for循环中向vector对象添加元素。
迭代器的运算:
两个迭代器指向的是同一个容器中的元素或者尾元素的下一个位置,就能够进行减法运算,运算的类型是difference_type,带符号整型数。
使用迭代器运算的一个常见算法是二分(有序序列)搜索:
auto beg = a.begin(),end = a.end();
auto mid = a.begin() + (end - begin)/2;
while (mid != end && *mid != aim)
{
if(sought < *mid)
end = mid;
else
beg = mid + 1;
mid = beg + (end - beg)/2;
}