一、 迭代器 iterator 基本原理



1、迭代器 iterator 作用


迭代器作用 : 迭代器 iterator 对象 , 可以用于遍历 STL 容器元素 ;

迭代器 对象 类似于 指针 , 指向 STL 容器中的一个特定位置 , 可以通过 * 运算符 解引用 迭代器对象 , 以 获取 STL 容器中的元素 ;

迭代器 类 中 , 提供了一系列的 成员函数 , 用于 遍历访问 STL 容器 中的元素 ;


2、迭代器 iterator 分类


迭代器 iterator 分类 :

  • 输入迭代器 : 又称为 " 只读迭代器 " , 只能读取 STL 容器中的元素 , 不能修改 容器中的 元素内容 ; 它们只能单向移动 , 即从前往后移动 ; 如 : std::istream_iterator 就是一个 输入迭代器 , 它可以从输入流中读取元素 ;
  • 输出迭代器 : 又称为 " 只写迭代器 " , 该迭代器只能向容器中写入元素 , 单次写入一个元素, 并向前移动 , 只支持一次遍历算法 , 即 : 迭代器 创建后 只能遍历一次 STL 容器 ;
  • 正向迭代器 : 这种类型的迭代器也可以用于读取 STL 容器中的元素 , 但也可以修改它们 ; 该迭代器只能单向移动 , 即只能从前往后遍历容器中的元素 ;
  • 双向迭代器 : 这种类型的迭代器可以双向移动 , 即可以从前往后 , 也可以从后往前 ; 双向迭代器可以用于读取和修改元素 ; 如 : std::vectorstd::deque 容器提供双向迭代器 ;
  • 随机访问迭代器 : 这是最强大的迭代器类型 , 它 提供了随机访问的能力 , 可以在任何位置进行快速的插入和删除操作 ; 这种类型的迭代器可以用于读取和修改元素 ; 如 : std::vectorstd::array 容器提供随机访问迭代器 ;

3、双向迭代器


双向迭代器 : 这种类型的迭代器可以双向移动 , 即可以从前往后 , 也可以从后往前 ; 双向迭代器可以用于读取和修改元素 ; 如 : std::vectorstd::deque 容器提供双向迭代器 ;


双向迭代器 支持的操作 :

  • ++iterator : 将迭代器向前移动一个位置 ;
  • –iterator : 将迭代器向后移动一个位置 ;
  • iterator1 == iterator2 : 比较两个迭代器是否相等 ;
  • iterator1 != iterator2 : 比较两个迭代器是否不相等 ;
  • *iterator : 解引用 , 获取迭代器指向 容器 位置的元素 ;
  • iterator1 == iterator2 : 迭代器赋值 , 将 iterator2 的值赋值给 iterator1 ;

支持双向迭代器的 STL 容器 :

  • list
  • set
  • multiset
  • map
  • multimap

4、随机访问迭代器


随机访问迭代器 : 这是最强大的迭代器类型 , 它 提供了随机访问的能力 , 可以在任何位置进行快速的插入和删除操作 ; 这种类型的迭代器可以用于读取和修改元素 ; 如 : std::vectorstd::array 容器提供随机访问迭代器 ;


随机访问迭代器 支持的操作 :

  • ++iterator : 将迭代器向前移动一个位置 ;
  • –iterator : 将迭代器向后移动一个位置 ;
  • iterator1 == iterator2 : 比较两个迭代器是否相等 ;
  • iterator1 != iterator2 : 比较两个迭代器是否不相等 ;
  • *iterator : 解引用 , 获取迭代器指向 容器 位置的元素 ;
  • iterator1 == iterator2 : 迭代器赋值 , 将 iterator2 的值赋值给 iterator1 ;

上面是双向迭代器的操作 , 随机访问迭代器都支持 , 在上述基础上还支持如下操作 :

  • 迭代器算术计算 : iterator += i , iterator -= i , iterator + i ;
  • 根据下标访问迭代器 : iterator [i] ;
  • 迭代器比较 : iterator1<iterator2, iterator1<=iterator2, iterator1>iterator2, iterator1>=iterator2;

支持 随机访问迭代器的 STL 容器 :

  • vector
  • deque




二、 迭代器 iterator 正向遍历与逆向遍历



1、迭代器正向遍历与逆向遍历


使用 begin() 函数 , 可以获取 正向迭代器 的首元素迭代器 ,

使用 end() 函数 , 可以获取 正向迭代器 的 指向尾部元素的后一个位置的迭代器 ;

在这里插入图片描述

使用 rbegin() 函数 , 可以获取 正向迭代器 的 尾部元素迭代器 ,

使用 rend() 函数 , 可以获取 正向迭代器 的 指向 首元素的前一个位置的迭代器 ;


2、使用迭代器正向遍历 vector 容器


使用 迭代器 遍历 vector 容器 ,

首先 , 获取 起始范围 迭代器 , std::vector<int> 类型的容器 , 其迭代器类型是 vector<int>::iterator , 调用 vector 类的 begin() 函数 , 可获取 指向容器中 第一个元素的迭代器 ;

vector<int>::iterator it = vec.begin();

然后 , 获取 迭代器 指向元素的内容 , 使用 * 操作符 , 实际上调用的是 重载 * 运算符函数 ;

*it

再后 , 对 迭代器 进行自增操作 , 自增 ++ 操作实际上调用的是 重载 ++ 运算符函数 , 用于递增迭代器 , 执行完毕后 , 迭代器指向下一个元素 ;

it++

最后 , 判定迭代器 是否迭代到了 容器末尾 , 调用 vector 类的 end() 函数 , 可获取 指向容器中 最后一个元素的迭代器 , 判断当前的迭代器值 是否等于 最后一个元素 后面一个位置 的迭代器值 , 如果 不等于 继续迭代 , 如果等于 停止迭代 ;

it != vec.end();

代码示例 :

#include "iostream"
using namespace std;
#include "vector"

int main() {

    // 创建空的 vector 容器
    std::vector<int> vec{1, 2, 3};

    // 遍历打印 vector 容器的内容 
    for (int i = 0; i < vec.size(); i++) {
        std::cout << vec[i] << ' ';
    }
    std::cout << std::endl;

    // 通过迭代器遍历数组
    for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
        std::cout << *it << ' ';
    }
    std::cout << std::endl;

	
	// 控制台暂停 , 按任意键继续向后执行
	system("pause");

	return 0;
};

执行结果 :

1 2 3
1 2 3
Press any key to continue . . .

在这里插入图片描述


3、使用迭代器反向遍历 vector 容器


使用 迭代器 遍历 vector 容器 ,

首先 , 获取 起始范围 迭代器 , std::vector<int> 类型的容器 , 其迭代器类型是 vector<int>::iterator , 调用 vector 类的 rbegin() 函数 , 可获取 指向容器中 最后一个元素的迭代器 ;

vector<int>::reverse_iterator rit = vec.rbegin();

然后 , 获取 迭代器 指向元素的内容 , 使用 * 操作符 , 实际上调用的是 重载 * 运算符函数 ;

*rit

再后 , 对 迭代器 进行自增操作 , 自增 ++ 操作实际上调用的是 重载 ++ 运算符函数 , 用于递增迭代器 , 执行完毕后 , 迭代器指向下一个元素 ;

rit++

最后 , 判定迭代器 是否迭代到了 容器末尾 , 调用 vector 类的 rend() 函数 , 可获取 指向容器中 第一个元素 前方一个位置 的迭代器 , 判断当前的迭代器值 是否等于 该迭代器值 , 如果 不等于 继续迭代 , 如果等于 停止迭代 ;

rit != vec.rend();

代码示例 :

#include "iostream"
using namespace std;
#include "vector"

int main() {

    // 创建空的 vector 容器
    std::vector<int> vec{ 1, 2, 3 };

    // 通过迭代器逆向遍历数组
    for (vector<int>::reverse_iterator rit = vec.rbegin(); rit != vec.rend(); rit++) {
        std::cout << *rit << ' ';
    }
    std::cout << std::endl;


    // 控制台暂停 , 按任意键继续向后执行
    system("pause");

    return 0;
};

执行结果 :

3 2 1
Press any key to continue . . .

在这里插入图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐