传统for循环控制力强、结构清晰,由初始化、条件判断、迭代三部分用分号分隔;支持反向、步长非1遍历及多变量操作;现代C++推荐auto推导迭代器类型,且erase后需用其返回值更新迭代器。

传统for循环:控制力强,适合索引操作
传统for循环结构清晰,由初始化、条件判断、迭代三部分组成,用分号分隔:for (int i = 0; i 。它最适用于需要下标参与逻辑的场景,比如:
- 按位置访问或修改数组/容器元素(如 arr[i] = i * 2)
- 反向遍历(for (int i = n - 1; i >= 0; --i))
- 步长非1的遍历(for (int i = 0; i )
- 嵌套循环处理二维结构(如矩阵行列索引)
注意:循环变量作用域限于for语句内;若需在循环后继续使用,应在外部声明。
范围for循环:简洁安全,专注元素本身
C++11起支持的range-based for语法为 for (auto& x : container),自动调用 begin() 和 end(),省去索引管理。核心技巧包括:
- 只读访问用 const auto&(避免拷贝大对象或临时字符串)
- 需修改原值时用 auto&(如
for (int& x : vec) x *= -1;) - 类型不确定时优先写 auto,而非硬编码类型(提升泛型性)
- 支持数组、
std::vector、std::array、std::string等标准容器
不支持纯指针数组(如 int* p = new int[5]),也不适用于运行时才确定范围的表达式(如函数返回临时容器时,C++23前需先赋值给变量再遍历)。
立即学习“C++免费学习笔记(深入)”;
迭代器for循环:通用性强,适配所有STL容器
对 std::list、std::map 等不支持随机访问的容器,必须用迭代器方式:
- for (auto it = c.begin(); it != c.end(); ++it) —— 显式控制,兼容旧标准
- 配合解引用
*it访问元素,可安全修改(it->second = ...用于 map) - 现代写法推荐 auto 推导迭代器类型,避免冗长声明(如
std::map<int, std::string>::iterator)
注意:避免在循环中 erase 迭代器后仍 ++it,应使用 erase 返回的新迭代器。
实用细节与避坑提醒
几种常见但易错的写法需留意:
- 省略某一部分:如 for (; condition; ) 或 for (int i = 0; ; ++i),后者是无限循环,必须内部有 break
- 逗号表达式可用于多变量初始化或更新:for (int i = 0, j = n-1; i
- 范围for中不要直接写函数调用作为容器源(如
for (auto x : getVec())),C++23前可能引发临时对象生命周期问题,应先存为局部变量 - 容器为空时,范围for自动跳过,无需额外判空;而传统for若依赖
size(),注意size()返回无符号类型,减1可能溢出
选哪种,关键看需求:要下标就用传统for,要干净遍历优先范围for,要最大兼容性就用迭代器for。











