循环条件变量必须在循环体内显式更新,c++不会自动递增、递减或重置;for中increment在本轮循环体执行后立即运行;do-while末尾分号不可省略;条件变量更新与检查间的间隙需用锁或原子操作防护。

循环条件变量必须在循环体内显式更新
如果 while 或 for 的控制变量(比如 i、flag、ptr)没在循环体中被修改,就会卡死或跳过——C++ 不会自动帮你递增、递减或重置它。
- 常见错误:
while (x > 0) { std::cout —— 缺少 <code>x--或类似更新,直接死循环 - 初始值和终止条件要逻辑自洽:比如
int i = 10; while (i ,条件一开始就是 false,循环体一次都不执行 - 用自增/自减运算符写在条件里(如
while (x-- > 0))语义模糊,容易误判执行次数;建议把更新逻辑单独放在循环末尾,意图更清晰
for 循环的更新表达式不是“下轮开始前”才运行
for(init; condition; increment) 中的 increment 是在本轮循环体执行完后立即执行,而不是等下一轮 condition 检查前才跑。这个顺序直接影响状态判断时机。
- 例如:
for (int i = 0; i → <code>i在i == 2这轮结束后仍会执行i++,但因break跳出,后续不进入循环体 - 若在循环体中提前
return或throw,increment就完全不会执行 - 不要依赖
increment做关键状态变更(比如释放资源),它可能被跳过;清理逻辑应放在 RAII 对象或显式finally-风格代码块中(C++ 无 finally,需靠作用域或std::unique_ptr等)
条件表达式含副作用时行为难预测
如果循环条件本身调用函数、读取 volatile 变量、或带自增(如 while (func()) 或 while (ptr && *ptr++)),每次检查都会重新求值并触发副作用——这可能导致多读、漏读、或状态错位。
- 文件读取典型陷阱:
do { std::cin >> x; } while (std::cin >> x);—— 第二次读可能失败,但已进循环体,x值未定义 - 正确写法:
while (std::cin >> x) { /* 处理 x */ },利用流对象隐式转换为 bool,且只读一次 - 硬件轮询场景:
while (!ready()) delay(1);安全;而do { delay(1); } while (!ready());会多等一轮,哪怕就绪了也白耗一次延迟
do-while 的分号是语法硬要求
do { ... } while (cond); 结尾的分号是语法规则的一部分,不是可选的。漏掉它,编译器报错类似 expected ';' before '}' token,且错误位置往往指向右大括号之后,容易误判。
- 错误写法:
do { x--; } while (x > 0)→ 编译失败 - 正确写法:
do { x--; } while (x > 0); - 这个分号和
if后不加分号、for后不加分号的直觉冲突,是初学者高频翻车点
真正容易被忽略的是:条件变量的更新时机与条件检查时机是两个独立事件,而它们之间的间隙(比如从检查完条件到执行更新之间)可能被其他线程或异步操作插入干扰——尤其在共享变量或指针场景下,必须配合锁或原子操作,不能只靠“看起来更新了”。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











