for (declaration : range_expression) {
// 循环体 (loop body)
// 在这里可以使用 declaration 来访问 range_expression 中的当前元素
}
declaration
: 声明一个变量,用于在每次迭代中存储range_expression
中的一个元素。- 这个变量的类型通常可以由编译器通过
range_expression
中元素的类型自动推断(使用auto
),或者你可以显式指定类型。 - 你可以声明为值 (
type var
)、引用 (type& var
) 或常量引用 (const type& var
),具体取决于你是否需要修改元素以及是否希望避免不必要的拷贝。
- 这个变量的类型通常可以由编译器通过
range_expression
: 一个可以被迭代的对象,例如:- STL 容器(如
std::vector
,std::string
,std::list
,std::map
等)。 - C 风格数组。
- 初始化列表 (
{1, 2, 3}
)。 - 任何定义了
begin()
和end()
成员函数,或者可以通过 ADL 找到begin()
和end()
全局函数的对象。
- STL 容器(如
简单来说,就是一个容器的快速一遍式for循环?像数组,字符串这种也是可以的。下面是一个对于Vector的此循环示例:
#include <vector>
#include <iostream>
#include <string> // 包含 string 头文件
// 使用 using namespace std; 使得代码更简洁 (在学习和小型项目中常用)
using namespace std;
int main() {
vector<int> numbers = {1, 2, 3, 4, 5};
cout << "Numbers: ";
for (int num : numbers) { // num 是每个元素的副本
cout << num << " ";
// num = num * 2; // 修改 num 不会影响 vector 中的原始元素
}
cout << endl;
// 修改 vector 中的元素 (使用引用)
cout << "Numbers doubled: ";
for (int& num_ref : numbers) { // num_ref 是每个元素的引用
num_ref *= 2;
cout << num_ref << " ";
}
cout << endl;
// 再次打印,确认修改
cout << "Numbers after doubling: ";
for (const int& num_const_ref : numbers) { // num_const_ref 是每个元素的常量引用 (只读,避免拷贝)
cout << num_const_ref << " ";
}
cout << endl;
vector<string> words = {"hello", "world", "C++"};
cout << "Words: ";
for (const string& word : words) { // 对于复杂对象,使用 const& 避免拷贝开销
cout << word << " ";
}
cout << endl;
return 0;
}
需要注意的是,对于此类的循环在不使用引用时实际上是在原件的复制上进行修改,因此何时调用引用也很重要。
使用auto
关键字可以再次简化代码:
#include <vector>
#include <iostream>
#include <map>
using namespace std;
int main() {
vector<double> doubles = {1.1, 2.2, 3.3};
cout << "Doubles: ";
for (auto d : doubles) { // d 的类型被推断为 double
cout << d << " ";
}
cout << endl;
map<string, int> scores = {{"Alice", 90}, {"Bob", 85}};
cout << "Scores: " << endl;
for (auto const& pair : scores) { // pair 的类型被推断为 const std::pair<const std::string, int>&
// 使用 const& 避免拷贝,且 map 的键是 const
cout << pair.first << ": " << pair.second << endl;
}
return 0;
}