C++ while/do-while循环块内条件变化时的执行逻辑问题
循环执行规则说明
不管是C++的普通while循环还是do-while循环,条件判断只会发生在每一轮循环的收尾节点,也就是整段循环体代码执行完毕、准备开启下一轮循环的时候。
- 普通
while:进入第一轮循环前会额外做一次条件判断,不满足直接不进循环 do-while:先执行完第一轮循环体,再做第一次条件判断
循环体运行过程中就算修改条件变量让循环终止条件成立,也不会中途打断当前轮次的执行,当前轮循环块里剩下的代码会照常跑完,除非代码里显式写了break、return、goto这类直接跳出当前代码块的语句。
第一段测试代码的执行逻辑
你运行第一段测试代码正常输出hello world是完全符合语法规则的,执行流程对应代码如下:
while (conditionalStatement == false) { std::cout << "hello "; conditionalStatement = true; std::cout << "world\n"; }
- 首次判断
conditionalStatement == false成立,进入循环体 - 执行输出语句打印
hello - 将
conditionalStatement赋值为true,此时循环终止条件已经满足,但当前轮循环没有结束,不会立刻退出 - 继续执行后续输出语句打印
world\n - 本轮循环体全部执行完毕,回到循环头部重新判断条件,发现条件不成立,正式退出循环
第二段项目代码的问题原因
你项目里输入2后看不到we broke the loop!输出,和循环逻辑无关,是标准输出缓冲区未刷新导致的。
这段代码的循环执行逻辑本身是完全正常的:
bool something = false; while (something == false) { std::cout << "choose 2 to break loop.\n"; int loopbreak; std::cin >> loopbreak; if (loopbreak == 1) { std::cout << "were looping!\n"; } else if (loopbreak == 2) { something = true; std::cout << "we broke the loop!\n"; } } //continue code
当你输入2时的执行流程:
- 进入
loopbreak == 2的分支,先将something赋值为true - 执行语句向输出缓冲区写入
we broke the loop!\n - 本轮循环体执行完毕,回到循环头部判断条件,发现
something == false不成立,退出循环
你看不到这行内容,是因为C++的std::cout是带缓冲设计的:写入的内容会先存在内存缓冲区里,只有遇到缓冲区满、主动调用刷新接口、程序正常退出、(终端行缓冲模式下)遇到换行符这几种情况,才会把缓冲区内容真正推到终端显示。
大部分场景下终端默认是行缓冲模式,输出里带
\n就会触发刷新,但如果你在部分IDE的调试输出窗口运行程序、或者把程序输出重定向到文件/管道,输出模式会切换为全缓冲,这时候\n不会触发刷新,就会出现“代码执行了但看不到输出”的错觉。
修复方法
两种改法都可以解决这个显示问题:
- 在输出语句后主动调用刷新接口:在
std::cout << "we broke the loop!\n";后加一句std::cout.flush(); - 把换行换成
std::endl,该操纵符会在输出换行后自动刷新缓冲区:写成std::cout << "we broke the loop!" << std::endl;
内容的提问来源于stack exchange,提问作者Alkurion
相关产品推荐
相关产品推荐

