• iterator迭代器的使用


    部分摘自C++ Primer:

    所有的标准库容器类都定义了相应的iterator类型,如vector:
    vector<int>::iterator iter;

    这条语句定义了一个名为iter的变量,它的数据类型是由vector<int>定义的iterator类型

    理解一下:除了使用下标来访问vector对象的元素外,标准库还提供了另一种检测元素的方法:使用迭代器(iterator)。迭代器是一种允许程序员检查容器内元素,并实现元素遍历的数据类型。

    vector <int>::iterator iter=vt.begin();//起始地址
    vector <int>::iterator iter_end=vt.end();//结束地址

    两个地址都是指针类型,end操作返回的迭代器指向vector的“末端元素的下一个”,指向了一个不存在的元素。若vector为空,begin和end返回的迭代器相同。end操作返回的迭代器并不指向vector中任何实际的元素相反它只是起一个哨兵sentinel的作用表示我们已处理完vector中所有元素。

    1.使用迭代器遍历vector元素:

    vector<int> ivec(1,2);
    for(vector<int>::iterator iter=ivec.begin();iter!=ivec.end();++iter)
    {
    *iter = 0; //使用 * 访问迭代器所指向的元素
    }

    vector<int>::const_iterator 和 const vector<int>::iterator有区别

    const vector<int>::iterator newiter=ivec.begin();
    *newiter=0; //可以修改指向容器的元素
    //newiter++; //迭代器本身不能被修改 

    2.迭代器基本操作:

    iter++, ++iter, iter- -, --iter, iter+n, iter-n, iter1-iter2

    3.注意伍是迭代器失效:

    任何改变vector长度的操作都会使已存在的迭代器失效。例如,在调用push_back后,就不能再信赖指向vector的迭代器的值了。

    修改容器的内在状态或者移动容器内的元素,这样的操作使得所有指向被移动的元素的迭代器失效,也可能同时使得其他迭代器失效。

    例如添加元素时,可能会导致容器的重新加载,这样该容器涉及的迭代器都将失效。即使不重新加载,指向新插入元素后面的那个元素的迭代器也会失效。

    任何insert、push操作都可能导致迭代器失效,因此要确保迭代器每次循环后都得到更新。

    vector<int>::iterator first = v.begin(),
    last = v.end(); // cache end iterator
    // Diaster: behavior of this loop is undefined
    while (first != last) {
      // do some processing
      // insert new value and reassign first, which otherwise would be invalid
      first = v.insert(first, 42);
      ++first; // advance first just past the element we added
    }

    上述代码的行为是未定义的。在很多实现中,该段代码将导致死循环。
    问题在于这个程序将 end 操作返回的迭代器值存储在名为 last 的局部变量中。
    循环体中实现了元素的添加运算,添加元素会使得存储在 last 中的迭代器失效。
    该迭代器既没有指向容器 v 的元素,也不再指向 v 的超出末端的下一位置。

    添加或删除 deque 或 vector 容器内的元素都会导致存储的迭代器失效。
    所以,不要存储 end 操作返回的迭代器。
    为了避免存储 end 迭代器,可以在每次做完插入运算之后重新计算 end 迭代器值:

    // Safer: recalculate end on each trip whenever the loop adds/erases elements
    while (first != v.end()) {
      // do some processing
      first = v.insert(first, 42); // insert new value
      ++first; // advance first just past the element we added
    }

    自己的备注:

    是否可以直接把iterator当成一个指针来看?
    比如说
    vector<int> v;
    vector<int>::iterator iter;
    // 其实里面的iterator 你可以这么理解typedef int* iterator;
    // 是一个指向所属容器的指针
    iter = v.begin()//指向v容器的第一个元素
    可以对iter做增与减的操作
    ++iter;
    --iter;
  • 相关阅读:
    献给所有学习控件和组件开发的读者
    ASP.NET 2.0书稿最新进展——开始一审
    愿我们共同进步——献给《Programming ASP.NET 3rd. 中文版》
    Error from MSDN——No4. Login.UserName
    安装MSDN中文版后的乱弹
    Error from MSDN——No9. Login.UserNameRequiredErrorMessage
    Error from MSDN——No1. Roles.Enabled
    Error from MSDN——No8. Login.PasswordRequiredErrorMessage
    热心的朋友请注意:ASP.NET 2.0书稿目录征求意见
    撰写《ASP.NET 2.0开发指南》的非正式小结
  • 原文地址:https://www.cnblogs.com/betteryi/p/3774541.html
Copyright © 2020-2023  润新知