基于范围的 for 循环(C++11)

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() 全局函数的对象。

简单来说,就是一个容器的快速一遍式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;
}