do-while
循环
1. 概念与用途
do-while
循环是 C++ 中提供的另一种循环结构,它与 while
循环非常相似,主要区别在于 do-while
是一种后测试循环 (post-tested loop)。这意味着循环体内的代码至少会执行一次,然后才在每次迭代结束时检查循环条件 (condition
) 是否为真 (true
)。如果条件为真,循环继续执行;如果条件为假 (false
),循环终止。
这种循环结构特别适用于那些无论条件如何,都需要至少执行一次循环体的场景,例如,显示菜单至少一次、获取用户输入并进行验证等。
2. 语法结构
// 可能的初始化语句
initialization_statement(s);
do {
// 循环体 (Loop Body)
// 这部分代码至少会无条件执行一次
statement(s);
// 更新语句,可能影响 condition 的值
update_statement(s);
} while (condition); // 注意:条件检查在循环体之后,并且必须以分号结尾!
// 当 while(condition) 计算为 false 后,程序从这里继续执行
3. 关键组成部分详解
-
do { ... }
:-
do
关键字标记循环体的开始。 - 大括号
{}
内是循环体,包含需要重复执行的语句。这部分代码块保证至少执行一次。
-
-
while (condition);
:-
condition
: 这是一个控制表达式,其计算结果必须能转换为布尔类型 (bool
)。 - 这个
condition
在每次循环体执行完毕之后被求值。 -
分号
;
: 在while (condition)
之后必须有一个分号。这是do-while
循环语法的强制要求,也是初学者容易遗漏的地方。
-
4. 执行流程
-
无条件执行循环体
{ ... }
内的所有语句(这是第一次执行)。 -
计算
condition
表达式的值。 -
判断
condition
:- 如果
condition
为true
,返回步骤 1,再次执行循环体。 - 如果
condition
为false
,终止循环,程序执行while (condition);
之后的下一条语句。
- 如果
5. 与 while
循环和 for
循环的比较
-
主要区别 (执行次数保证):
-
do-while
: 循环体至少执行一次。条件在循环体之后检查。 -
while
和for
: 循环体可能一次都不执行。条件在循环体之前(或第一次迭代之前)检查。
-
-
语法差异:
do-while
的检查条件在循环体之后,并且需要一个分号结束。while
的条件在前面,没有这个末尾的分号。 -
适用场景:
-
do-while
: 需要先执行一次操作,然后根据结果判断是否重复时(如菜单显示、输入验证)。 -
while
: 迭代次数未知,且需要在执行前就判断条件是否满足时。 -
for
: 迭代次数已知或有清晰的计数逻辑时。
-
6. 示例:菜单系统
一个常见的 do-while
应用是实现一个简单的菜单,至少显示一次,然后根据用户输入决定是否继续显示或退出。
#include <iostream>
#include <limits> // 用于 std::numeric_limits
int main() {
int choice;
do {
// 1. 执行循环体:显示菜单 (至少执行一次)
std::cout << "\n--- 菜单 ---" << std::endl;
std::cout << "1. 选项一" << std::endl;
std::cout << "2. 选项二" << std::endl;
std::cout << "0. 退出" << std::endl;
std::cout << "请输入你的选择: ";
// 获取用户输入
std::cin >> choice;
// 处理可能的输入错误 (例如用户输入了非数字字符)
if (std::cin.fail()) {
std::cout << "输入错误,请输入数字!" << std::endl;
std::cin.clear(); // 清除错误标志
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 忽略掉缓冲区中无效的输入
choice = -1; // 给 choice 一个无效值,确保不意外匹配下面的 case,并能继续循环
}
// 根据选择执行操作 (这里仅作演示)
switch (choice) {
case 1:
std::cout << "你选择了选项一。" << std::endl;
break;
case 2:
std::cout << "你选择了选项二。" << std::endl;
break;
case 0:
std::cout << "正在退出程序..." << std::endl;
break;
default:
if (choice != -1) { // 避免对上面处理输入错误时设置的 -1 报错
std::cout << "无效选择,请重新输入。" << std::endl;
}
break;
}
// 2. 检查条件:只要用户选择的不是 0 (退出选项),就继续循环
} while (choice != 0);
std::cout << "程序已退出。" << std::endl;
return 0;
}
在这个例子中,菜单 (std::cout
部分) 保证会先显示一次。然后程序获取用户输入 choice
,并执行相应的 switch
逻辑。最后,while (choice != 0);
检查用户是否选择了退出选项 0。如果不是 0,条件为 true
,循环回到 do
再次显示菜单;如果是 0,条件为 false
,循环终止。
7. break
和 continue
-
break;
: 立即终止当前的do-while
循环,程序跳转到循环后面的语句。即使条件仍然为true
,也会强制退出。 -
continue;
: 跳过当前迭代中continue
语句之后的所有代码,直接跳转到循环末尾的while (condition);
进行条件检查,然后根据结果决定是否开始下一次迭代。
想象一下,你面前有一盘你从来没吃过的饼干。妈妈说:“你可以尝一块,然后告诉我还想不想要。”
先做 (
do { ... }
): 你先拿起一块饼干,尝一尝!嗯,味道怎么样?这个“尝一尝”的动作,是你必须先做一次的,不管你喜不喜欢。这就是do
的部分,它让你先行动!再检查 (
while (condition);
): 尝完之后,妈妈问你:“好吃吗?还要不要再来一块?” (这就是condition
:还要不要)。这个提问发生在你尝过之后。-
决定是否重复:
- 如果你觉得:“哇,太好吃了!我还要!”(条件是真的),那你就再拿一块尝尝,尝完妈妈又会问你“还要吗?”。
- 如果你觉得:“嗯...味道一般,我不要了。”(条件是假的),那你就不再拿饼干了,吃饼干的环节就结束了。
和 while
(堆积木游戏) 的区别:
- 堆积木 (
while
) 是先看手里有没有积木,再决定堆不堆。 - 吃饼干 (
do-while
) 是先尝一块,再决定要不要继续吃。do-while
保证你至少会尝到第一块饼干!
我们把这个“尝饼干”的过程画出来:
graph TD
A[开始] --> B[拿起一块饼干尝尝!];
B --> C{还要再来一块吗?};
C -- 要! --> B; % 如果还要,就回去再尝一块
C -- 不要了 --> D[停! 不吃饼干了];
D --> E[去找别的零食吧!];
看这个流程图:
- 从 “A点” 开始。
- 立刻就走到 “B点”:“拿起一块饼干尝尝!” (先做动作)。
- 做完动作后,才到达 “C点” 的问题:“还要再来一块吗?” (条件检查在后面)。
- 如果回答 “要!”,箭头把你带回到 B 点,让你再尝一块。
- 你就一直在 B -> C 这个圈里转,每次都是先 B 再 C。
- 直到在 C 点检查时,你回答 “不要了”。
- 这时,你就顺着 “不要了” 的路走到 “D点” 停下来。
- 最后到达 “E点”。
关键就是,你肯定会经过 B 点至少一次,然后才在 C 点做决定要不要回去!
现在我们用电脑的“暗号”来写这个尝饼干的故事。
-
do
: 告诉电脑,“先做一次大括号里的事!” -
{ ... }
: 大括号里面就是要先做一次,并且可能重复做的事,比如“尝一块饼干”。 -
while (还要不要);
: 这就是那个在后面的检查。意思是“做完一次后,检查‘还要不要’这个条件。如果条件是真的,就回去再做一次大括号里的事。” -
;
: 最后这个小小的分号非常重要,一定要记得加在while(...)
的后面!就像说完一句话要加句号一样。
用代码写出来可能是这样:
bool wantMoreCookies = false; // 先假设不想要,但 do 会让我们至少尝一次
do {
// 尝一块饼干! Yummy!
// std::cout << "Mmm, I tasted a cookie!" << std::endl;
// 问问自己还要不要? (在真实代码里,可能会问用户输入)
// 假设我们尝了一块就觉得够了
wantMoreCookies = false; // 尝完后决定不要了
} while (wantMoreCookies == true); // 检查:还要吗?(这里会是 false) 别忘了这个分号 ;
// std::cout << "Okay, no more cookies for me." << std::endl;
在这个例子里,即使 wantMoreCookies
一开始可能是 false
或者在第一次尝过之后变成 false
,"尝一块饼干" 这个动作也至少执行了一次。
总结一下 do-while
循环:
它是“先斩后奏”或者“先试后买”型的循环!它保证大括号 {}
里的动作至少发生一次。做完之后,它才在 while(...) ;
这里检查条件,看要不要回头再做一遍。如果你需要确保某个操作(比如显示提示信息、进行一次计算尝试)至少发生一次,那么 do-while
就是你的好帮手!记得那个在最后的小尾巴——分号 ;
哦!