【C/C++】范围for循环

📘 C++ 范围 for 循环详解(Range-based for loop)


一、什么是范围 for 循环?

范围 for 循环(Range-based for loop) 是 C++11 引入的一种简化容器/数组遍历的方式。它通过自动调用容器的 begin()end() 方法,实现对每个元素的遍历,无需手动管理索引或迭代器


二、语法格式

cpp 复制代码
for (declaration : expression) {
    // 循环体
}
  • declaration :用于声明当前遍历的元素(可使用 auto 自动推导类型)
  • expression:表示要遍历的容器或数组

三、基本原理

✅ 自动调用 begin()end()

范围 for 循环会自动调用容器的 begin()end() 方法,获取起始和结束迭代器,然后依次遍历每个元素。

示例说明:
cpp 复制代码
std::vector<int> numbers = {1, 2, 3, 4, 5};

for (int num : numbers) {
    std::cout << num << " ";
}
✅ 等价于传统写法:
cpp 复制代码
std::vector<int> numbers = {1, 2, 3, 4, 5};

for (auto it = numbers.begin(); it != numbers.end(); ++it) {
    int num = *it;
    std::cout << num << " ";
}

四、适用对象

范围 for 循环适用于以下对象:

类型 是否支持 示例
数组 ✅ 支持 int arr[] = {1, 2, 3};
标准库容器 ✅ 支持 std::vector, std::list, std::map
自定义容器类 ✅ 支持 需要实现 begin()end() 方法
字符串(std::string ✅ 支持 逐字符遍历
原始指针容器 ❌ 不支持 没有 begin()/end() 方法

五、优点

优点 说明
代码简洁 避免手动写 begin()/end()
安全性高 不易越界,适合只读遍历
可读性强 更贴近自然语言,易于理解
自动类型推导 可使用 auto 自动识别元素类型

六、局限性

局限 说明
不能直接访问索引 无法通过循环变量获取当前索引
不能反向遍历 只能从前往后遍历
不能跳过元素 无法控制步长(如 i += 2
不能修改容器结构 不能在循环中添加/删除元素

七、代码示例

1. 遍历数组

cpp 复制代码
int arr[] = {1, 2, 3, 4, 5};

for (int num : arr) {
    std::cout << num << " ";
}
// 输出: 1 2 3 4 5

2. 遍历 std::vector

cpp 复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> nums = {10, 20, 30, 40, 50};

    for (auto num : nums) {
        std::cout << num << " ";
    }
    // 输出: 10 20 30 40 50
    return 0;
}

3. 遍历 std::map

cpp 复制代码
#include <iostream>
#include <map>

int main() {
    std::map<std::string, int> scores = {
        {"Alice", 95},
        {"Bob", 80},
        {"Charlie", 88}
    };

    for (const auto &pair : scores) {
        std::cout << pair.first << ": " << pair.second << std::endl;
    }
    return 0;
}

输出:

复制代码
Alice: 95
Bob: 80
Charlie: 88

4. 遍历 std::string

cpp 复制代码
#include <iostream>
#include <string>

int main() {
    std::string str = "Hello";

    for (char c : str) {
        std::cout << c << " ";
    }
    // 输出: H e l l o
    return 0;
}

5. 使用引用修改元素

cpp 复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<int> nums = {1, 2, 3, 4, 5};

    for (auto &num : nums) {
        num *= 2;  // 修改原容器中的值
    }

    for (auto num : nums) {
        std::cout << num << " ";
    }
    // 输出: 2 4 6 8 10
    return 0;
}

6. 使用 auto 自动推导类型

cpp 复制代码
#include <iostream>
#include <vector>

int main() {
    std::vector<std::string> names = {"Tom", "Jerry", "Spike"};

    for (const auto &name : names) {
        std::cout << name << std::endl;
    }
    return 0;
}

八、常见错误与修正

错误写法 正确写法 说明
for (int x : 10) for (int x : vector) 范围 for 必须作用于容器
for (int x : {}); std::vector<int> v = {1, 2}; for (int x : v) 空列表不能单独使用
for (int &x : const std::vector<int> v) for (int x : v) 不能通过引用修改常量容器
for (int x : arr, arr + 5) for (int x : arr) 不需要手动指定范围,自动识别容器边界

九、性能与安全建议

建议 说明
使用 const auto & 遍历只读容器 避免拷贝,提高性能
使用 auto & 修改容器元素 通过引用直接操作原数据
避免在循环中修改容器结构 push_back()erase(),可能导致迭代器失效
优先使用 const 如果不打算修改元素,使用 const auto & 提高代码清晰度

十、通俗类比

你可以把范围 for 循环理解为:

cpp 复制代码
for (auto &item : shopping_list) {
    std::cout << "Buy: " << item << std::endl;
}
  • shopping_list 是你要遍历的容器
  • item 是当前遍历到的元素
  • 循环自动帮你"取出"每一个物品,不需要你手动操作索引或指针

十一、术语对照表

英文术语 中文解释
Range-based for loop 范围 for 循环
Container 容器(如 vector, map
Iterator 迭代器(传统 for 循环中使用)
Reference 引用(& 表示)
auto 自动类型推导
const auto & 常量引用,防止拷贝和修改原始数据

十二、设计建议

场景 推荐写法
只读遍历容器 for (const auto &item : container)
修改容器元素 for (auto &item : container)
遍历字符串 for (char c : str)
遍历 map 的键值对 for (const auto &pair : my_map)
避免拷贝 使用引用 &
避免修改容器结构 不在循环中调用 push_back()erase() 等方法

十三、总结

特性 说明
语法简洁 for (auto &item : container)
自动调用 begin() / end() 无需手动写迭代器
适用于容器和数组 vector, map, array, string
不能控制索引 无法获取当前索引值
不适合动态修改容器 如增删元素会导致迭代器失效

相关推荐
小汉堡编程33 分钟前
数据结构——vector数组c++(超详细)
数据结构·c++
tan180°6 小时前
MySQL表的操作(3)
linux·数据库·c++·vscode·后端·mysql
学不动CV了6 小时前
ARM单片机启动流程(二)(详细解析)
c语言·arm开发·stm32·单片机·51单片机
彭祥.7 小时前
Jetson边缘计算主板:Ubuntu 环境配置 CUDA 与 cudNN 推理环境 + OpenCV 与 C++ 进行目标分类
c++·opencv·分类
lzb_kkk7 小时前
【C++】C++四种类型转换操作符详解
开发语言·c++·windows·1024程序员节
猫猫的小茶馆8 小时前
【STM32】通用定时器基本原理
c语言·stm32·单片机·嵌入式硬件·mcu·51单片机
胖大和尚9 小时前
clang 编译器怎么查看在编译过程中做了哪些优化
c++·clang
pumpkin845149 小时前
Rust 调用 C 函数的 FFI
c语言·算法·rust
2401_8582861110 小时前
125.【C语言】数据结构之归并排序递归解法
c语言·开发语言·数据结构·算法·排序算法·归并排序
钱彬 (Qian Bin)10 小时前
一文掌握Qt Quick数字图像处理项目开发(基于Qt 6.9 C++和QML,代码开源)
c++·开源·qml·qt quick·qt6.9·数字图像处理项目·美观界面