什么是迭代器
C++的迭代器是一种用于遍历容器元素的对象。迭代器提供了一种通用的访问容器元素的方式,无论容器的类型和数据结构如何。通过迭代器,我们可以依次访问容器中的每个元素,对其进行读取、修改或删除操作。
使用迭代器可以极大地简化对容器元素的访问和操作,同时提高程序的灵活性和可扩展性。迭代器的使用方式类似于指针,我们可以通过迭代器来遍历容器中的每个元素,并通过迭代器进行读写操作,而不需要关心容器内部的具体实现细节。
迭代器分类
在C++中,迭代器是一种用于访问容器中的元素的对象。C++标准库中提供了多种类型的迭代器,每种迭代器都有不同的功能和特性。以下是C++中常用的迭代器类型:
- 输入迭代器(Input Iterator):只能读取容器中的元素,而不能修改或重复读取。输入迭代器支持++、*、==、!=等操作符。适用于遍历容器中的元素,如
std::istream_iterator
。
#include <iostream> #include <iterator> int main() { int arr[] = {1, 2, 3, 4, 5}; std::istream_iterator<int> input_iter(std::cin); for (auto it = std::begin(arr); it != std::end(arr); ++it) { *it = *input_iter; ++input_iter; } for (int num : arr) { std::cout << num << " "; } return 0; }
- 输出迭代器(Output Iterator):只能写入容器中的元素,而不能读取或重复写入。输出迭代器支持++、*等操作符。适用于向容器中写入数据,如
std::ostream_iterator
。
#include <iostream> #include <iterator> #include <vector> int main() { std::vector<int> vec; std::ostream_iterator<int> output_iter(std::cout, " "); for (int i = 1; i <= 5; ++i) { *output_iter = i; ++output_iter; vec.push_back(i); } return 0; }
- 前向迭代器(Forward Iterator):支持读写操作,可以向前遍历容器中的元素。前向迭代器支持++、*、==、!=等操作符。适用于需要多次遍历容器中的元素,如
std::forward_list
。
#include <iostream> #include <forward_list> int main() { std::forward_list<int> flist = {1, 2, 3, 4, 5}; auto it = flist.begin(); while (it != flist.end()) { std::cout << *it << " "; ++it; } return 0; }
- 双向迭代器(Bidirectional Iterator):支持读写操作,可以向前和向后遍历容器中的元素。双向迭代器支持++、–、*、==、!=等操作符。适用于需要反向遍历容器中的元素,如
std::list
。
#include <iostream> #include <list> int main() { std::list<int> list = {1, 2, 3, 4, 5}; auto it = list.begin(); while (it != list.end()) { std::cout << *it << " "; ++it; } return 0; }
- 随机访问迭代器(Random Access Iterator):支持读写操作,可以在常数时间内进行随机访问。随机访问迭代器支持++、–、*、[]、+、-、<、<=、>、>=等操作符。适用于需要通过下标访问容器中的元素,如
std::vector
和std::array
。
#include <iostream> #include <vector> int main() { std::vector<int> vec = {1, 2, 3, 4, 5}; for (std::vector<int>::iterator it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << " "; } std::cout << std::endl; std::cout << "Element at index 2: " << vec[2] << std::endl; std::cout << "Element at index 4: " << *(vec.begin() + 4) << std::endl; return 0; }
以上是C++中常见的迭代器类型及其示例。通过使用适当的迭代器类型,可以方便地对容器中的元素进行访问和操作。
以上就是迭代器常见的功能,接下来我用一张表格为大家展示迭代器的功能关系:
随机访问迭代器 | 双向迭代器 | 正向迭代器 | |
支持 ++递增 | √ | √ | √ |
支持 == !=判等 | √ | √ | √ |
支持 -- 递减 | √ | √ | × |
支持算数操作符 + - | √ | × | × |
支持 > < >= <= 的比较操作 | √ | × | × |
支持+= -=的操作 | √ | × | × |
支持下标随机访问 | √ | × | × |
获取迭代器
在C++中,可以使用不同的方法来获取迭代器,具体取决于数据结构类型。以下是获取迭代器的几种常见方式:
- 使用begin()和end()方法:
这是最常用的获取迭代器的方式。通过调用容器的begin()方法,可以返回指向第一个元素的迭代器;而调用end()方法则返回指向容器末尾的迭代器。例如:
#include <iostream> #include <vector> int main() { std::vector<int> vec{1, 2, 3, 4, 5}; // 使用begin()和end()方法获取迭代器 auto it = vec.begin(); auto end = vec.end(); // 遍历容器 for (; it != end; ++it) { std::cout << *it << " "; } return 0; }
输出结果为:1 2 3 4 5
- 使用rbegin()和rend()方法:
rbegin()方法返回指向容器最后一个元素的逆向迭代器,而rend()方法则返回指向容器开始的逆向迭代器。逆向迭代器可以从容器的末尾开始向前遍历容器。例如:
#include <iostream> #include <vector> int main() { std::vector<int> vec{1, 2, 3, 4, 5}; // 使用rbegin()和rend()方法获取逆向迭代器 auto it = vec.rbegin(); auto end = vec.rend(); // 遍历容器 for (; it != end; ++it) { std::cout << *it << " "; } return 0; }
输出结果为:5 4 3 2 1
- 使用advance()方法:
advance()方法允许我们在迭代器上进行偏移,以便访问容器中的其他元素。它需要两个参数,第一个是迭代器,第二个是偏移量。使用advance()方法可以在容器中跳过指定数量的元素,然后获取新位置上的迭代器。例如:
#include <iostream> #include <list> #include <iterator> int main() { std::list<int> lst{1, 2, 3, 4, 5}; // 获取迭代器,并在容器中移动到第三个元素之后 auto it = lst.begin(); std::advance(it, 2); // 输出第三个元素之后的元素 for (; it != lst.end(); ++it) { std::cout << *it << " "; } return 0; }
输出结果为:3 4 5
- 使用next()和prev()方法:
next()方法返回当前迭代器的下一个迭代器,prev()方法返回当前迭代器的前一个迭代器。这些方法也需要两个参数,第一个是迭代器,第二个是偏移量。它们在使用时可以更加方便,无需像advance()方法一样显式指定迭代器的类型。例如:
#include <iostream> #include <array> #include <iterator> int main() { std::array<int, 5> arr{1, 2, 3, 4, 5}; // 获取第三个元素的下一个迭代器和前一个迭代器 auto nextIt = std::next(arr.begin(), 2); auto prevIt = std::prev(arr.begin(), 2); // 输出第三个元素和其周围的元素 std::cout << *prevIt << " " << *nextIt << std::endl; return 0; }
输出结果为:2 4
这些是获取C++中迭代器的几种常见方式,可以根据具体的需求选择合适的方法来获取迭代器。