C++(三十九):do-while 循环

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. 执行流程

  1. 无条件执行循环体 { ... } 内的所有语句(这是第一次执行)。
  2. 计算 condition 表达式的值。
  3. 判断 condition:
    • 如果 conditiontrue返回步骤 1,再次执行循环体。
    • 如果 conditionfalse终止循环,程序执行 while (condition); 之后的下一条语句。

5. 与 while 循环和 for 循环的比较

  • 主要区别 (执行次数保证):
    • do-while: 循环体至少执行一次。条件在循环体之后检查。
    • whilefor: 循环体可能一次都不执行。条件在循环体之前(或第一次迭代之前)检查。
  • 语法差异: 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. breakcontinue

  • break;: 立即终止当前的 do-while 循环,程序跳转到循环后面的语句。即使条件仍然为 true,也会强制退出。
  • continue;: 跳过当前迭代中 continue 语句之后的所有代码,直接跳转到循环末尾的 while (condition); 进行条件检查,然后根据结果决定是否开始下一次迭代。

想象一下,你面前有一盘你从来没吃过的饼干。妈妈说:“你可以尝一块,然后告诉我还想不想要。”

  1. 先做 (do { ... }): 你先拿起一块饼干,尝一尝!嗯,味道怎么样?这个“尝一尝”的动作,是你必须先做一次的,不管你喜不喜欢。这就是 do 的部分,它让你先行动!

  2. 再检查 (while (condition);): 尝完之后,妈妈问你:“好吃吗?还要不要再来一块?” (这就是 condition:还要不要)。这个提问发生在你尝过之后

  3. 决定是否重复:

    • 如果你觉得:“哇,太好吃了!我还要!”(条件是真的),那你就再拿一块尝尝,尝完妈妈又会问你“还要吗?”。
    • 如果你觉得:“嗯...味道一般,我不要了。”(条件是假的),那你就不再拿饼干了,吃饼干的环节就结束了。

while (堆积木游戏) 的区别:

  • 堆积木 (while) 是先看手里有没有积木,再决定堆不堆。
  • 吃饼干 (do-while) 是先尝一块再决定要不要继续吃。do-while 保证你至少会尝到第一块饼干!

我们把这个“尝饼干”的过程画出来:

graph TD
    A[开始] --> B[拿起一块饼干尝尝!];
    B --> C{还要再来一块吗?};
    C -- 要! --> B; % 如果还要,就回去再尝一块
    C -- 不要了 --> D[停! 不吃饼干了];
    D --> E[去找别的零食吧!];

看这个流程图:

  1. 从 “A点” 开始。
  2. 立刻就走到 “B点”:“拿起一块饼干尝尝!” (先做动作)。
  3. 做完动作后,才到达 “C点” 的问题:“还要再来一块吗?” (条件检查在后面)。
  4. 如果回答 “要!”,箭头把你带回到 B 点,让你再尝一块。
  5. 你就一直在 B -> C 这个圈里转,每次都是先 B 再 C。
  6. 直到在 C 点检查时,你回答 “不要了”。
  7. 这时,你就顺着 “不要了” 的路走到 “D点” 停下来。
  8. 最后到达 “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 就是你的好帮手!记得那个在最后的小尾巴——分号 ; 哦!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容