菜单
×
   ❮     
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

C++ 教程

C++ 主页 C++ 简介 C++ 入门 C++ 语法 C++ 输出 C++ 注释 C++ 变量 C++ 用户输入 C++ 数据类型 C++ 运算符 C++ 字符串 C++ 数学 C++ 布尔值 C++ If...Else C++ Switch C++ While 循环 C++ For 循环 C++ Break/Continue C++ 数组 C++ 结构体 C++ 枚举 C++ 引用 C++ 指针

C++ 函数

C++ 函数 C++ 函数参数 C++ 函数重载 C++ 作用域 C++ 递归

C++ 类

C++ OOP C++ 类/对象 C++ 类方法 C++ 构造函数 C++ 访问修饰符 C++ 封装 C++ 继承 C++ 多态 C++ 文件 C++ 异常 C++ 日期

C++ 数据结构

C++ 数据结构与 STL C++ Vectors C++ List C++ Stacks C++ Queues C++ Deque C++ Sets C++ Maps C++ 迭代器 C++ 算法

C++ How To

C++ 两数相加 C++ 随机数

C++ 参考

C++ 参考 C++ 关键字 C++ <iostream> C++ <fstream> C++ <cmath> C++ <string> C++ <cstring> C++ <ctime> C++ <vector> C++ <algorithm>

C++ 示例

C++ 示例 C++ 现实生活中的例子 C++ 编译器 C++ 练习 C++ 测验 C++ 证书


C++ 迭代器


C++ 迭代器

迭代器用于访问和遍历数据结构(vectorset 等)中的元素,通过“指向”它们。

之所以称为“迭代器”,是因为“迭代”(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";
}
自己动手试一试 »

示例说明

  1. 首先,我们创建一个字符串 vector 来存储不同汽车制造商的名称。
  2. 然后,我们创建一个名为 it 的“vector 迭代器”,我们将用它来遍历 vector。
  3. 接下来,我们使用 for 循环通过迭代器遍历 vector。迭代器(it)指向 vector 中的第一个元素(cars.begin()),并且循环将一直持续到 it 等于 cars.end() 为止。
  4. 递增运算符(++it)会将迭代器移动到 vector 中的下一个元素。
  5. 解引用运算符(*it)会访问迭代器指向的元素。

注意:迭代器的类型必须与它要遍历的数据结构类型匹配(在本例中为 string


什么是 begin()end()

begin()end() 是**属于数据结构**(如 vectorlist)的**函数**。它们**不属于迭代器**本身。相反,它们与迭代器一起使用,以访问和遍历这些数据结构中的元素。

  • begin() 返回一个指向数据结构第一个元素的迭代器。
  • end() 返回一个指向最后一个元素之后一个位置的迭代器。

为了理解它们的工作原理,让我们继续以 vector 为例

vector<string> cars = {"Volvo", "BMW", "Ford", "Mazda"};

vector<string>::iterator it;

Begin 示例

begin() 指向 vector 中的第一个元素(索引 0,“Volvo”)

示例

// 指向 vector 中的第一个元素
it = cars.begin();
自己动手试一试 »

要指向第二个元素(BMW),您可以编写 cars.begin() + 1

示例

// 指向第二个元素
it = cars.begin() + 1;
自己动手试一试 »

当然,这也意味着您可以使用 cars.begin() + 2 指向第三个元素

示例

// 指向第三个元素
it = cars.begin() + 2;
自己动手试一试 »

End 示例

end() 指向 vector 中最后一个元素**之后**的一个位置(这意味着它不指向实际元素,而是指示这是 vector 的末尾)。

因此,要使用 end() 来指向 cars vector 中的最后一个元素(Mazda),您可以使用 cars.end() - 1

示例

// 指向最后一个元素
it = cars.end() - 1;
自己动手试一试 »

为什么说“指向”?

迭代器就像“指针”,因为它们“指向”数据结构中的元素,而不是从中返回值。它们引用一个特定位置,提供了一种在需要时访问和修改值的方式,而无需复制它。例如:

示例

// 指向 vector 中的第一个元素
it = cars.begin();

// 修改第一个元素的值
*it = "Tesla";

// Volvo 现在是 Tesla
自己动手试一试 »

auto 关键字

在 C++11 及更高版本中,您可以使用 auto 关键字,而不是显式声明和指定迭代器的类型。

auto 关键字允许编译器自动确定正确的数据类型,这简化了代码并使其更具可读性。

而不是这样

vector<string>::iterator it = cars.begin();

您只需写:

auto 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()

示例

// 反向迭代
for (auto it = cars.rbegin(); it != cars.rend(); ++it) {
  cout << *it << "\n";
}
自己动手试一试 »

遍历其他数据结构

迭代器非常适合代码重用,因为您可以对遍历 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";
}
自己动手试一试 »

迭代器支持

上面的示例展示了如何遍历不同的数据结构,这些结构支持迭代器(vectorlistdequemapset 支持迭代器,而**stackqueue 则不支持**)。


算法

迭代器的另一个重要特性是它们与不同的算法函数一起使用,例如 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;
}
自己动手试一试 »


×

联系销售

如果您想将 W3Schools 服务用于教育机构、团队或企业,请发送电子邮件给我们
sales@w3schools.com

报告错误

如果您想报告错误,或想提出建议,请发送电子邮件给我们
help@w3schools.com

W3Schools 经过优化,旨在方便学习和培训。示例可能经过简化,以提高阅读和学习体验。教程、参考资料和示例会不断审查,以避免错误,但我们无法保证所有内容的完全正确性。使用 W3Schools 即表示您已阅读并接受我们的使用条款Cookie 和隐私政策

版权所有 1999-2024 Refsnes Data。保留所有权利。W3Schools 由 W3.CSS 提供支持