C++ 迭代器
C++ 迭代器
迭代器用于访问和遍历数据结构(vector、set 等)中的元素,通过“指向”它们。
之所以称为“迭代器”,是因为“迭代”(iterating)是**循环**(looping)的技术术语。
要遍历 vector,请看以下示例
示例
// 创建一个名为 cars 的 vector,用于存储字符串
vector<string> cars = {"Volvo", "BMW", "Ford", "Mazda"};
// 创建一个名为 it 的 vector 迭代器
vector<string>::iterator it;
// 使用迭代器循环遍历 vector
for (it = cars.begin(); it != cars.end(); ++it) {
cout << *it << "\n";
}
自己动手试一试 »
示例说明
- 首先,我们创建一个字符串 vector 来存储不同汽车制造商的名称。
- 然后,我们创建一个名为
it
的“vector 迭代器”,我们将用它来遍历 vector。 - 接下来,我们使用
for
循环通过迭代器遍历 vector。迭代器(it
)指向 vector 中的第一个元素(cars.begin()
),并且循环将一直持续到it
等于cars.end()
为止。 - 递增运算符(
++it
)会将迭代器移动到 vector 中的下一个元素。 - 解引用运算符(
*it
)会访问迭代器指向的元素。
注意:迭代器的类型必须与它要遍历的数据结构类型匹配(在本例中为 string
)
什么是 begin()
和 end()
?
begin()
和 end()
是**属于数据结构**(如 vector 和 list)的**函数**。它们**不属于迭代器**本身。相反,它们与迭代器一起使用,以访问和遍历这些数据结构中的元素。
begin()
返回一个指向数据结构第一个元素的迭代器。end()
返回一个指向最后一个元素之后一个位置的迭代器。
为了理解它们的工作原理,让我们继续以 vector 为例
vector<string> cars = {"Volvo", "BMW", "Ford", "Mazda"};
vector<string>::iterator it;
Begin 示例
begin()
指向 vector 中的第一个元素(索引 0,“Volvo”)
要指向第二个元素(BMW),您可以编写 cars.begin() + 1
当然,这也意味着您可以使用 cars.begin() + 2
指向第三个元素
End 示例
end()
指向 vector 中最后一个元素**之后**的一个位置(这意味着它不指向实际元素,而是指示这是 vector 的末尾)。
因此,要使用 end()
来指向 cars vector 中的最后一个元素(Mazda),您可以使用 cars.end() - 1
为什么说“指向”?
迭代器就像“指针”,因为它们“指向”数据结构中的元素,而不是从中返回值。它们引用一个特定位置,提供了一种在需要时访问和修改值的方式,而无需复制它。例如:
auto
关键字
在 C++11 及更高版本中,您可以使用 auto
关键字,而不是显式声明和指定迭代器的类型。
auto
关键字允许编译器自动确定正确的数据类型,这简化了代码并使其更具可读性。
而不是这样
vector<string>::iterator it = cars.begin();
在上面的示例中,编译器根据 cars.begin()
的返回值类型(即 vector<string>::iterator
)确定 it
的类型。
auto
关键字在 for
循环中也同样适用。
for (auto it = cars.begin(); it != cars.end(); ++it) {
cout << *it << "\n";
}
自己动手试一试 »
For-Each 循环 vs. 迭代器
您可以使用**for-each** 循环来仅循环遍历数据结构中的元素,如下所示:
示例
// 创建一个名为 cars 的 vector,用于存储字符串
vector<string> cars = {"Volvo", "BMW", "Ford", "Mazda"};
// 打印 vector 元素
for (string car : cars) {
cout << car << "\n";
}
自己动手试一试 »
当您只是读取元素而不需要修改它们时,for-each 循环比迭代器更简单、更清晰。
但是,当您需要在**迭代过程中**添加、修改或删除元素,反向迭代,或跳过元素时,应该使用迭代器。
示例
// 创建一个名为 cars 的 vector,用于存储字符串
vector<string> cars = {"Volvo", "BMW", "Ford", "Mazda"};
// 循环遍历 vector 元素
for (auto it = cars.begin(); it != cars.end(); ) {
if (*it == "BMW") {
it = cars.erase(it); // 删除 BMW 元素
} else {
++it;
}
}
// 打印 vector 元素
for (const string& car : cars) {
cout << car << "\n";
}
自己动手试一试 »
反向迭代
要反向迭代,您可以使用 rbegin()
和 rend()
代替 begin()
和 end()
。
遍历其他数据结构
迭代器非常适合代码重用,因为您可以对遍历 vector、list、deque、set 和 map 使用相同的语法。
List 示例
// 创建一个名为 cars 的 list,用于存储字符串
list<string> cars = {"Volvo", "BMW", "Ford", "Mazda"};
// 使用迭代器循环遍历 list
for (auto it = cars.begin(); it != cars.end(); ++it) {
cout << *it << "\n";
}
自己动手试一试 »
Deque 示例
// 创建一个名为 cars 的 deque,用于存储字符串
deque<string> cars = {"Volvo", "BMW", "Ford", "Mazda"};
// 使用迭代器循环遍历 deque
for (auto it = cars.begin(); it != cars.end(); ++it) {
cout << *it << "\n";
}
自己动手试一试 »
Set 示例
// 创建一个名为 cars 的 set,用于存储字符串
set<string> cars = {"Volvo", "BMW", "Ford", "Mazda"};
// 使用迭代器循环遍历 set
for (auto it = cars.begin(); it != cars.end(); ++it) {
cout << *it << "\n";
}
自己动手试一试 »
Map 示例
// 创建一个 map,用于存储字符串和整数
map<string, int> people = { {"John", 32}, {"Adele", 45}, {"Bo", 29} };
// 使用迭代器循环遍历 map
for (auto it = people.begin(); it != people.end(); ++it) {
cout << it->first << " is: " << it->second << "\n";
}
自己动手试一试 »
算法
迭代器的另一个重要特性是它们与不同的算法函数一起使用,例如 sort()
和 find()
(在 <algorithm>
库中找到),用于对数据结构中的元素进行排序和搜索。
例如,sort()
函数以迭代器(通常由 begin()
和 end()
返回)作为参数,对数据结构中的元素从开始到结束进行排序。
在此示例中,由于元素是字符串,因此它们按字母顺序排序:
示例
#include <iostream>
#include <vector>
#include <algorithm> // 包含 <algorithm> 库
using namespace std;
int main() {
// 创建一个名为 cars 的 vector,用于存储字符串
vector<string> cars = {"Volvo", "BMW", "Ford", "Mazda"};
// 按字母顺序对 cars 进行排序
sort(cars.begin(), cars.end());
// 按字母顺序打印 cars
for (string car : cars) {
cout << car << "\n";
}
return 0;
}
自己动手试一试 »
在此示例中,由于元素是整数,因此它们按数字顺序排序:
示例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
// 创建一个名为 numbers 的 vector,用于存储整数
vector<int> numbers = {1, 7, 3, 5, 9, 2};
// 按数字顺序对 numbers 进行排序
sort(numbers.begin(), numbers.end());
for (int num : numbers) {
cout << num << "\n";
}
return 0;
}
自己动手试一试 »
要反转顺序,您可以使用 rbegin()
和 rend()
代替 begin()
和 end()
。
示例
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
// 创建一个名为 numbers 的 vector,用于存储整数
vector<int> numbers = {1, 7, 3, 5, 9, 2};
// 按数字反向顺序对 numbers 进行排序
sort(numbers.rbegin(), numbers.rend());
for (int num : numbers) {
cout << num << "\n";
}
return 0;
}
自己动手试一试 »