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;
}
自己動手試一試 »