迭代器(iterator)
严格来说,string对象不属于容器类型,但是string支持许多与容器类型相似的操作
所有容器类都支持迭代器,但只有vector等几种才支持下标运算符
(string,vector都支持下标运算符、迭代器)
获取迭代器不是使用取地址符,有迭代器的类型同时拥有返回迭代器的成员
例程:
string s(“some string”)
if (s.bigen() != s.end())
{
auto it = s.begin();
*it=toupper(*it);
}
标准容器迭代器的运算符:
*iter | 返回迭代器iter所指元素的引用 |
---|---|
iter->mem | 解引用iter并获取该元素的名为mem的成员,等价于(*iter).mem |
++iter | 令iter指示容器中的下一个元素 |
–iter | 令iter指示容器中的上一个元素 |
iter_1==iter_2 | 判断两个迭代器是否相等,如果指示同一个元素或者是同一个容器的尾后迭代器,则True |
iter_1!=iter_2 | 反之,不相等 |
将迭代器从一个元素移动到另外一个元素
迭代器使用++运算符从一个元素移动到下一个元素,迭代器的递增运算符是将迭代器“向前移动一个位置”
(把一个字符串中的第一个单词全变成大写)
for (auto it=s.begin;it!=s.end() && !isspace(*it);++it)
{
*it=toupper(*it);
}
(所有标准库容器的迭代器都定义了==和!=,但是它们大都没有定义<运算符)
因此,在使用迭代器时要养成使用!的习惯
迭代器类型(不是很重要)
vector::iterator it;//it 能读写元素
string::iterator it;//it 能读写字符
vector::const_iterator it;//it只能读元素
string::const_iteractor it;//it 只能读字符
常量迭代器与迭代器“变量”
begin end;cbegin cend
结合解引用和成员访问操作
(*it).empty()
it->empty()
//依次输出text的每一行直至遇到第一个空白行为止
for
(auto it=text.cbegin();it!=text.cend() && !it->empty();++it)
{
cout << *it <<endl;
}
某些对vector对象的操作会使迭代器失效
任何一种可能改变vector对象容量的操作,比如push_back,都会使该vector对象的迭代器失效
谨记,但凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素
迭代器运算
使迭代器跨越更多的元素
两个迭代器相减,返回这两个迭代器之间的距离
迭代器大小比较——前后顺序比较
//计算得到最接近容器a的中间元素的一个迭代器
auto mid=a.begin()+a.size()/2;
if(it<mid)//处理前半段的元素
使用迭代器运算——二分搜索
auto beg=text.begin();
auto end = text.end();
auto mid=text.begin()+(end-beg)/2;
while(mid!=end && *mid!=sought)
{
if (sought<*mid)
end=mid;
else
beg=mid+1;
mid=beg+(end-beg)/2;
}