C++基础之迭代器iterator

C++基础之迭代器iterator

咱们已经知道可使用下标运算符来访问string对象的字符或vector对象的元素,还有另外一种更通用的机制也能够实现一样的目的,这就是迭代器(iterator)算法

标准库容器均可以使用迭代器,可是只有少数几种才同时支持下标运算符。指针

相似于指针类型,迭代器也提供了对对象的间接访问。就迭代器而言,其对象是容器中的元素或者string对象中的字符。使用迭代器能够访问某一个元素,迭代器也能从一个元素移动到另一个元素。迭代器和指针同样,有无效和有效的区别。code

有效的迭代器指向元素或者尾元素的下一个位置,其余状况都属于无效的迭代器。对象

使用迭代器

可以使用迭代器的变量类型拥有返回迭代器的方法。get

begin()方法负责返回指向第一个元素的迭代器
end()方法负责返回指向容器尾元素的下一个位置的迭代器string

// b表示v的第一个元素,e表示v尾元素的下一个位置
auto b = v.begin(), e = v.end(); // b和e的类型相同

特殊状况下:it

若是容器为空,则beginend返回的是同一个迭代器。table

迭代器运算符

运算符 含义
*iter 返回迭代器iter所指元素的引用
iter->mem 解引用iter并获取该元素的名为mem的成员,等价于*(iter).mem
++iter 令iter指向容器中的下一个元素
--iter 令iter指向元素中的上一个元素
iter1 == iter2 判断两个迭代器是否相等

这使得迭代器就想下标同样的好用,好比:class

string s("come thing");
if (s.begin() != s.end()) {
    auto it = s.begin();
    *it = toupper(*it);
}

迭代器类型

就想不知道stringvectorsite_type成员究竟是什么类型同样,通常来讲咱们也不知道迭代器的精确类型。而实际上,那些拥有迭代器的标准库类型都会使用iteratorconst_iterator来表示迭代器的类型:容器

vector<int>::iterator it; // it能表明vector<int>的元素
string::iterator it2;       // it2能表明string对象中的元素

vector<int>::const_iterator it3; // it3只能表明读元素,不能表明写元素
string::const_iterator it4;     // it4只能读字符,不能写字符,即改变字符的值

const_iterator和常量指针差很少,能读取但不能修改他所指元素的值。

若是vector对象或string对象是一个常量,只能使用const_iterator

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

解引用能够得到迭代器所指的对象,若是该对象的类型刚好是个类,就有可能进一步访问他的成员。例如:

vector<string> strs = {"string", "", "tingyugetc"};
for (auto it = strs.begin(); it != strs.end() ; ++it) {
    if (it->empty()) {
        cout << "now is in empty string" << endl;
    }
}

上述的代码中使用了箭头运算符, 箭头运算符将解引用和成员访问两个操做结合在一块儿,他的做用和(*it).empty()相同。

(*it).empty()的圆括号必不可少,其含义是先执行括号内的解引用,接着解引用的结果在执行点运算符。若是不加括号,那么点运算符将由it执行,而不是it解引用的结果。

迭代器失效

某些对vector对象的操做会使迭代器失效.
谨记,但凡使用了迭代器的循环体,都不要想迭代器所属的容器添加元素

迭代器的运算

迭代器的递增运算令迭代器每次移动一个元素,全部的标准库都有支持递增运算符的迭代器。相似的,也能用==!=对任意标准库类型的两个有效迭代器进行比较。

一样的,能够令迭代器和一个整数值相加或相减,其返回值是向前或向后移动了若干个位置的迭代器,执行这样的操做时,结果迭代器要么指向原vector对象内的一个元素要么指向尾元素的下一个位置。
好比,能够这样:

// 计算获得最接近vi中间元素的一个迭代器
auto mid = vi.begin() + vi.size() / 2;

使用迭代器运算的一个经典算法是二分搜索。

auto beg = text.begin(), end = text.end();
auto mid = beg + (end - beg) / 2;
while (mid != end && *mid != found) {
    if (found < *mid) {
        end = mid;
    } else {
        beg = mid + 1;
    }
    mid = beg + (end - beg) / 2;
}
相关文章
相关标签/搜索