使用迭代器

begin成员负责返回指向第一个元素的迭代器:

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

end成员则负责返回指向容器“尾元素的下一位置”的迭代器,这样的迭代器仅是个标记,表示已经处理完了容器中的所有元素,end返回的迭代器成为尾后迭代器

Note:容器为空,则begin和end返回的是同一个迭代器,都是尾后迭代器。

迭代运算符

标准容器迭代器的运算符
*iter 返回迭代器iter所指元素的引用
iter->mem 解引用iter并获取该元素的名为mem的成员,等价于(*iter).mem
++iter 令iter指示容器的下一个元素
--iter 令iter指示容器的上一个元素
iter1==iter2 判断两个迭代器是否相等(不相等),如果两个迭代器指示的是同一个元素或者它们是同一个容器的尾后迭代器,则相等;反之,不相等
iter1!=iter2

执行解引用的迭代器必须合法并确实指示着某个元素,试图解引用一个非法迭代器或者尾后迭代器都是未被定义的行为。

利用迭代器把string对象的第一个字母改写了大写形式:

    string s("some string");
    if (s.begin() != s.end())//确保s非空
    {
        auto it = s.begin();//it表示s的第一个字符
        *it = toupper(*it);//将当前字符改成大写形式
    }

将迭代器从一个元素移动到另一个元素

迭代器使用递增(++)运算符来从一个元素移动到下一个元素。

Note:end返回的迭代器并不实际指示某个元素,所以不能对其进行递增或解引用的操作。

利用迭代器及其递增运算符将string对象中第一个单词改写为大写形式:

    //依次处理s的字符直至我们处理完全部字符或者遇到空白
    for(auto it=s.begin();it!=s.end()&&!isspace(*it);++it)
        * it = toupper(*it);//将当前字符改成大写形式

迭代器类型

拥有迭代器的标准库类型使用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只能读字符,不能写元素

begin和end运算符

如果对象是常量,begin和end返回const_iterator,如果对象不是常量,返回iterator:

    vector<int> v;
    const vector<int> cv;
    auto it1 = v.begin();//it1的类型是vector<int>::iterator
    auto it2 = cv.begin();//it2的类型是vector<int>::const_iterator

为了得到const_iterator类型的返回值,C++11新标准引入了两个函数,分别是cbegin和cend:

    auto it3 = v.cbegin();//it3的类型是vector<int>::const_iterator

返回指示容器第一个元素或最后元素下一位置的迭代器,不论vector对象(或string对象)本身是否是常量,返回值都是const_iterator。

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

检查一个由字符串组成的vector对象的元素是否为空,令it是该vector对象的迭代器,检查it所指字符串是否为空:

    (*it).empty()

圆括号必不可少,含义是先对it解引用,然后解引用的结果再执行点运算符:

    (*it).empty()//解引用it,然后调用结果对象的empty成员
    *it.empty()//错误:试图访问it的名为empty的成员,但it是个迭代器,没有empty成员

箭头运算符:把解引用和成员访问两个操作结合在一起:it->mem和(*it).mem表达的意思相同。

名为text的字符串向量存放文本文件中的数据,其中的元素是一句话或者是一个用于表示段落分隔的空字符串,输出text中第一段的内容:

    //依次输出text的每一行直至遇到第一个空白为止
    for (auto it = text.cbegin(); it != text.cend() && !it->empty(); ++it)
        cout << *it << endl;

某些对vector对象的操作会使迭代器失效

  • 不能在范围for循环中向vector对象添加元素
  • 任何一种可能改变vector对象容量的操作,如果push_back,会使该vector对象的迭代器失效

 

posted @ 2019-05-06 16:28  CodeWithMe  阅读(337)  评论(0)    收藏  举报