選單
×
   ❮     
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 提供支援