zoukankan      html  css  js  c++  java
  • STL六大组件之——迭代器这个东西

    迭代器:除了在其它语言中司空见惯的下标法访问容器元素之外,C++语言提供了一种全新的方法——迭代器(iterator)来访问容器的元素。迭代器其实类似于引用,指向容器中某一元素。换个方式来说,容器就是数据结构的泛指,迭代器就是指针的泛指,可以指向元素。容器相当于一个储藏柜,里面装的许多不同的物品就像是储存的元素,比如面包、啤酒、苹果、现金。要取得各个物体就得用与各个物体向匹配的工具,如取出面包要用盘子、取出啤酒要用杯子、取出苹果要用篮子、取出现金要用钱包。迭代器的作用就相当于取出物品的工具的抽象,通过迭代器泛指现实生活中从贮藏室中取出物体的工具。C++迭代器是一种检查容器内元素并遍历元素的数据类型。

    迭代器的类型

    对于STL数据结构和算法,你可以使用五种迭代器。下面简要说明了这五种类型:

    Input iterators 提供对数据的只读访问。

    Output iterators 提供对数据的只写访问。

    Forward iterators 提供读写操作,并能向前推进迭代器。

    Bidirectional iterators提供读写操作,并能向前和向后操作。

    Random access iterators提供读写操作,并能在数据中随机移动。

    尽管各种不同的STL实现细节方面有所不同,还是可以将上面的迭代器想象为一种类继承关系。从这个意义上说,下面的迭代器继承自上面的迭代器。由于这种继承关系,你可以将一个Forward迭代器作为一个output或input迭代器使用。同样,如果一个算法要求是一个bidirectional 迭代器,那么只能使用该种类型和随机访问迭代器。

    指针迭代器

    一个指针也是一种迭代器。该程序同样显示了STL的一个主要特性——它不只是能够用于它自己的类类型,而且也能用于任何C或C++类型。下面的程序显示了如何把指针作为迭代器用于STL的find()算法来搜索普通的数组。

     1 #include <iostream.h>
     2 #include <algorithm>
     3 
     4 using namespace std;
     5 #define SIZE 100
     6 int iarray[SIZE];
     7 
     8 int main()
     9 {
    10   iarray[20] = 50;
    11   int* ip = find(iarray, iarray + SIZE, 50);
    12   if (ip == iarray + SIZE)
    13      cout << "50 not found in array" << endl;
    14   else
    15      cout << *ip << " found in array" << endl;
    16   return 0;
    17 }

    程序中定义了尺寸为SIZE的全局数组。由于是全局变量,所以运行时数组自动初始化为零。下面的语句将在索引20位置处地元素设置为50,并使用find()算法来搜索值50:

    iarray[20] = 50;

    int* ip = find(iarray, iarray + SIZE, 50);

    find()函数接受三个参数。头两个定义了搜索的范围。由于C和C++数组等同于指针,表达式iarray指向数组的第一个元素。而第二个参数iarray + SIZE等同于past-the-end 值,也就是数组中最后一个元素的后面位置。第三个参数是待定位的值,也就是50。find()函数返回和前两个参数相同类型的迭代器,这儿是一个指向整数的指针ip。

    if (ip == iarray + SIZE) ...

    如果表达式为真,则表示在搜索的范围内没有指定的值。否则就是指向一个合法对象的指针,这时可以用下面的语句显示::

    cout << *ip << " found in array" << endl;

    测试函数返回值和NULL是否相等是不正确的。不要象下面这样使用:

    int* ip = find(iarray, iarray + SIZE, 50);

    if (ip != NULL) ...  // ??? incorrect

    当使用STL函数时,只能测试ip是否和past-the-end 值是否相等。尽管在本例中ip是一个C++指针,其用法也必须符合STL迭代器的规则。

    容器迭代器

    尽管C++指针也是迭代器,但用的更多的是容器迭代器。和将迭代器申明为指针变量不同的是,你可以使用容器类方法来获取迭代器对象。两个典型的容器类方法是begin()和end()。它们在大多数容器中表示整个容器范围。其他一些容器还使用rbegin()和rend()方法提供反向迭代器,以按反向顺序指定对象范围。

    下面的程序创建了一个矢量容器(STL的和数组等价的对象),并使用迭代器在其中搜索。该程序和前一章中的程序相同。

     1 #include <iostream.h>
     2 #include <algorithm>
     3 #include <vector>
     4 
     5 using namespace std;
     6 vector<int> intVector(100);
     7 
     8 void main()
     9 {
    10   intVector[20] = 50;
    11   vector<int>::iterator intIter =
    12   find(intVector.begin(), intVector.end(), 50);
    13   if (intIter != intVector.end())
    14      cout << "Vector contains value " << *intIter << endl;
    15   else
    16      cout << "Vector does not contain 50" << endl;
    17 }

    常量迭代器

    和指针一样,你可以给一个迭代器赋值。例如,首先申明一个迭代器:

    vector<int>::iterator first;

    该语句创建了一个vector<int>类的迭代器。下面的语句将该迭代器设置到intVector的第一个对象,并将它指向的对象值设置为123::

    first = intVector.begin();

    *first = 123;

    这种赋值对于大多数容器类都是允许的,除了只读变量。为了防止错误赋值,可以申明迭代器为:

    const vector<int>::iterator result;

    result = find(intVector.begin(), intVector.end(), value);

    if (result != intVector.end())

    *result = 123;  // ???

    //警告:另一种防止数据被改变得方法是将容器申明为const类型。

    具体迭代器的实现源码,https://www.sgi.com/tech/stl/download.html上有,可以自己下来看看。

  • 相关阅读:
    导出表结构语句
    closeChannel: close the connection to remote address[] result: true
    spingboot使用rabbitmq
    服务器很卡问题排查
    docker-compose安装nginx
    Docker方式安装ShowDoc
    "docker build" requires exactly 1 argument
    Intellij IDEA常用快捷键介绍 Intellij IDEA快捷键大全汇总
    IDEA 2018 3.4 激活破解方法
    jpress:v3.2.5的docker-compose安装
  • 原文地址:https://www.cnblogs.com/geekpaul/p/4166925.html
Copyright © 2011-2022 走看看