当前位置: 首页 > news >正文

C++ 循环语句`while`、`for` 与 `do…while`(六十七)

一、while 循环

语法与执行流程

while (condition) statement;
  • condition
    • 任何可隐式转换为 bool 的表达式,或是“带初始化”的变量声明(C++17 起支持)。
    • 每次迭代前都会重新求值;如果条件为假(false),循环一律终止,跳出到后续代码。
  • statement
    • 通常是一条简单语句,也可以是一个【复合语句块(block)】{ … }
    • 如果需要多条语句共同构成循环体,务必用 {} 括起来,否则只有紧跟的第一条语句属于循环体。

何时选用 while

  1. 无法预知迭代次数
    • 读取标准输入直到 EOF:
      std::vector<int> data;
      int x;
      while (std::cin >> x)            // 读取失败(EOF 或格式错误)时结束data.push_back(x);
      
  2. 循环结束后仍需访问循环条件或控制变量
    • 查找第一个负数元素,并在循环结束后检查是“找到”还是“遍历完毕”:
      auto it = data.begin();
      while (it != data.end() && *it >= 0)++it;
      if (it == data.end()) {// 没有负数
      } else {// *it 是第一个负数
      }
      

注意事项

  • 避免“空循环体”陷阱
    while (std::cin >> x && x != sentinel);  // 空语句:循环体什么都不做,仅依赖条件部分“副作用”读入
    
  • 防止漏写/多写分号
    while (cond);   // 错!分号会让循环体变成“空语句”,后面的代码将不受循环控制do_something();  // 永远只执行一次
    
  • 循环变量作用域
    • 在 C++17 及以后,你可以在 while 条件中声明变量:
      while (int n = getValue()) {  // 每次迭代 n 都被创建并初始化// … 使用 n …
      }
      // 这里的 n 已超出作用域
      

二、for 循环 快速概览

如果你对迭代次数大致有个概念,或者想把“初始化–条件–更新”三要素集中在一行,for 循环往往更简洁:

for (std::size_t i = 0; i < vec.size(); ++i) {process(vec[i]);
}
  • 初始化语句(init-stmt):在循环开始前执行一次
  • 条件表达式(cond):每次迭代前检查
  • 更新表达式(increment):每次迭代后执行
  • 循环体(statement):前面三部分控制何时进入、如何前进、何时退出

范围 for(C++11)
当你只需遍历容器或数组时,推荐使用更简洁的

for (auto &elem : container) {// … 使用 elem …
}

三、do…while 循环

do…while 保证至少执行一次循环体,然后在末尾检查条件:

do {work();
} while (condition);
  • 适用场景:需要先执行操作,再决定是否继续,例如:
    • 菜单驱动程序:先显示菜单并读取一次用户选择,至少一次才有意义。

四、小结与实践指南

循环类型检查条件时机至少执行一次常见用途
while不确定次数、基于外部输入的循环
for已知次数或可整合 init/cond/incr 的常规迭代
do…while必须执行一次后再决定是否继续
  • 规范花括号:即使循环体只有一行,也推荐使用 { … },避免后期添加代码时引入“悬垂 else”或分号陷阱。
  • 变量作用域:尽量将循环控制变量限制在最小作用域中——C++17 之后可在 whilefor 头部声明。
  • 空循环:对“仅依赖条件副作用”的场景(如读取输入直至 EOF),可使用空语句;但要注释清晰,避免误删。
  • 选择合适的循环
    • 以数据驱动(“有没有数据”)为主 → while
    • 以计数驱动(“执行 N 次”)为主 → for
    • 需要至少执行一次 → do…while

掌握这三种循环及其差异,配合 范围 for算法库标准容器,就能灵活、高效地应对绝大多数“重复执行”需求。希望这篇干货能帮助你在 C++ 项目中写出更清晰、健壮的循环代码!

相关文章:

  • C# 操作符
  • 多协议 Tracker 系统架构与传感融合实战 第五章 卡尔曼滤波定位算法实战
  • 计算机网络八股文--day4 --传输层TCP与UDP
  • k8s 探针
  • TFT(薄膜晶体管)和LCD(液晶显示器)区别
  • Socket 编程 UDP
  • 基于LangChain 实现 Advanced RAG-后检索优化(下)-上下文压缩与过滤
  • 基于Springboot高校网上缴费综合务系统【附源码】
  • SpringSecurity配置(权限认证)
  • redis延时队列详细介绍
  • 计算机基础:二进制基础17,八进制减法
  • 第 13 届蓝桥杯 C++ 青少组省赛中 / 高级组 2022 年真题(编程第一题)
  • 360驱动大师v2.0(含网卡版)驱动工具软件下载及安装教程
  • 【AI面试准备】银行UI测试效率提升案例解析
  • LeetCode算法题 (设计链表)Day16!!!C/C++
  • [Vue]props解耦传参
  • Python刷题:流程控制(下)
  • 基于开源AI大模型与AI智能名片S2B2C商城小程序的线上活动执行优化研究
  • Java开发经验——ali编码规范经验总结
  • 【Mytais系列】Type模块:源码
  • 网民反映“潜水时遭遇服务质量不佳”,三亚开展核查调查
  • 专访|“甲亢哥”的操盘手,带NBA球星们玩转中国流量
  • 夜读丨最美的风景,在亲人的目光里
  • 商务部:自5月7日起对原产于印度的进口氯氰菊酯征收反倾销税
  • 秦洪看盘|涌现新逻辑,A股放量回升
  • 为什么所有动物里,只有人类幼崽发育得这么慢?