范圍 for 循環是 C++11 引入的語法特性,用于簡化遍歷容器或數組元素的過程。它比傳統 for 循環更簡潔安全,特別適合初學者。以下是詳細講解:
基本語法
for (元素類型 變量名 : 容器/數組) {// 循環體(使用變量名訪問當前元素)
}
或使用 auto
自動推斷類型:
for (auto 變量名 : 容器/數組) {// 循環體
}
與普通 for 循環對比
傳統遍歷向量的方式:
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
{// 使用 *it 訪問元素
}
范圍 for 循環更簡潔,可讀性更強,且不易出錯(如避免了迭代器越界等問題)。
關鍵特點
- 自動遍歷:無需手動控制索引或迭代器
- 邊界安全:自動處理開始和結束位置,避免越界
- 簡潔性:代碼更易讀,減少錯誤
底層原理
范圍 for 循環會遍歷給定容器(或數組)中的每一個元素。在每次迭代中,它會將當前元素復制到循環變量中(注意:這里是復制)。如果你希望避免復制,特別是當容器元素較大時,可以使用引用(如 auto&
或 const auto&
)。
編譯器將范圍 for 轉換為迭代器操作:
// 原始代碼
for (auto x : container) { ... }// 等效的傳統代碼
for (auto it = begin(container); it != end(container); ++it) {auto x = *it; // 注意:這里是值拷貝!...
}
使用示例
示例 1:遍歷數組
int numbers[] = {10, 20, 30, 40};// 傳統 for 循環
for (int i = 0; i < 4; ++i) {cout << numbers[i] << " ";
}// 范圍 for 循環(更簡潔!)
for (int num : numbers) {cout << num << " ";
}
// 輸出:10 20 30 40
示例 2:遍歷 vector
#include <vector>
#include <iostream>
using namespace std;int main() {vector<string> fruits = {"Apple", "Banana", "Cherry"};// 使用 auto 自動推斷類型for (auto fruit : fruits) {cout << fruit << " ";}// 輸出:Apple Banana Cherry
}
修改元素(使用引用)
若需修改容器中的元素,需使用引用 &
:
vector<int> scores = {80, 90, 70};// 給每個成績加10分
for (auto& score : scores) { // 注意 & 符號score += 10;
}// 驗證結果
for (auto s : scores) {cout << s << " "; // 輸出:90 100 80
}
只讀場景(使用 const 引用)
當不需要修改元素時,使用 const auto&
避免復制開銷:
vector<string> names = {"Alice", "Bob", "Charlie"};// 高效只讀訪問(尤其對大型對象)
for (const auto& name : names) {cout << name.length() << " "; // 輸出:5 3 7
}
支持的數據類型
范圍 for 循環可用于:
- 原生數組(如
int arr[5]
) - STL 容器(
vector
,list
,map
,set
等) - 自定義類型(需實現
begin()
和end()
成員函數) - 初始化列表(如
{1,2,3}
)
注意事項
-
容器必須支持迭代器:范圍 for 循環內部使用迭代器,因此容器必須具有
begin()
和end()
成員函數,或者是數組。 -
不能修改容器結構:在范圍 for 循環中,不能添加或刪除容器中的元素,否則可能導致迭代器失效,引發未定義行為。
-
元素訪問方式:
-
使用
auto
:創建元素的副本(適用于基本類型或需要修改但不影響原容器的情況)。 -
使用
auto&
:引用元素,可以修改元素(修改會影響原容器)。 -
使用
const auto&
:常量引用,只讀且避免復制(適用于大對象或只讀遍歷)。
經典應用場景
- 遍歷數組/容器處理數據
- 配合 STL 算法快速操作
- 處理字符串字符:
string msg = "Hello"; for (char c : msg) {cout << c << "-"; // 輸出:H-e-l-l-o- }
建議:在 C++11 及以上版本中,優先使用范圍 for 替代傳統 for 循環,代碼更簡潔安全。掌握后你會愛上它!