4.3  循环控制语句

在现实世界中,有这样一类现象:

只要油箱中的当前油量小于油箱容量100升,就一直往油箱中加油;

一直不断地为祖国辛勤工作,只要我还活着;

公司100000位员工,每个人的工资都增加10000元;

这些现象虽然各不相同,但它们都有一个共同的特点,那就是在某个条件(只要我还活着)下,或者某个范围(所有100000位员工)内,这些动作(辛勤工作、增加10000元工资)都是循环往复重复多次地出现。为了表达这类循环现象,C++提供了循环控制结构。又因为这些循环现象各有特点,为了准确而简便地表达它们,C++有针对性地分别提供了while、do…while…以及for语句。

4.3.1  while循环:只要…就一直…

对于上面的第一个循环现象,我们可以用“只要…就一直…”这样的句式来描述。在现实世界中,这种循环现象非常普遍:

只要天还没黑,就一直在工地干活;

只要硬盘还有剩余空间,就一直往硬盘上面存储文件。

在自然语言中,我们用“只要…就一直…”这样的句式来表达这种在某个条件下某个动作循环发生的循环现象,与之对应地,在C++中,我们用while循环结构来表达这种循环现象。其语法格式如下:

while( 条件表达式 )
{
循环体语句;
}

在条件表达式中,我们对某个条件进行判断,得到表示条件成立与否的true或者false值,以此来表达这个循环是在“某个条件”下进行的。而while结构中的循环体语句,则表示会被循环执行的动作。例如,我们将“只要油箱中的当前油量小于油箱容量100升,就一直往油箱中加油”这个循环现象用while结构表达出来就是:

// 当前油量
int nL = ;
// …
// 循环条件:当前油量小于油箱容积
while(nL < )
{
nL += ; // 循环动作:往油箱中加1升油
}

在执行的时候,while语句首先会计算条件表达式(nL < 100)的值,也就是判断循环条件(当前油量小于油箱容量100升)是否满足。如果其值为true,表示循环条件满足,则进入循环执行循环体语句,完成循环动作(往油箱中加1升油);反之,则表示循环条件不再满足,从而直接结束整个while语句的执行。当循环体语句执行完一次后,会再次计算条件表达式的值,判断循环条件是否仍然满足。如果满足,则继续进入循环执行循环体语句,开始第二次循环。如此不断循环往复,直到条件表达式的值为false,循环条件不再满足,整个循环才结束。可以把while理解成自然语言中的“只要”,只要循环条件满足,就不断执行循环体语句。当循环条件不再满足时,就结束while循环语句。while循环语句的执行流程如图4-3所示。

知道更多:单步调试执行程序,查看代码执行过程

while循环语句的执行过程,要比之前介绍的if条件语句复杂的多,再加上后面我们将要学到的break和continue对执行过程的控制,这样while循环语句的执行过程就更复杂了。稍不留意,就可能导致代码的实际执行过程与我们的设计不符,从而使程序执行得到错误结果。在这种情况下,我们可以利用Visual Studio所提供的单步调试运行功能,查看while循环语句真实的执行过程,从而找到与设计预期不符的地方,进而改正错误,使程序按照正确的过程执行得到正确的执行结果。

所谓的单步调试执行,就是在调试状态下,按照程序的执行流程逐条地依次执行每一条语句,而在这个过程中,我们可以清楚地看到程序的执行过程——哪一条语句先执行,哪一条语句后执行,哪一条语句被跳过而没有得到执行——以此判断代码的执行过程是否与设计预期相符。同时在这个过程中,我们还可以利用Visual Studio提供的“观察”、“变量”等工具窗口,查看各个变量的当前数值,以此判断执行结果是否与设计预期相符。如果执行过程或者执行结果与设计预期不符,那么这就意味着当前执行的代码可能是程序中出现问题的地方。当程序执行出现问题,也就是所谓出现bug的时候,我们通常用这种方式来寻找出现问题的代码位置进而对其进行修正,而这个过程也被称为debug。

要想使用单步调试执行来查看某段代码的执行过程,我们可以先将输入焦点定位在这段代码的开始位置,然后按下F9快捷键在当前代码行设置一个断点。所谓断点,就是在程序调试执行的过程中会暂停的代码位置。设置断点后,按下F5快捷键调试执行程序,当程序执行到之前设置的断点位置就会暂停下来,这时我们可以利用F10快捷键,按键一次就向下执行一条语句,从而可以看到整个代码的执行过程。利用这种方式,我们就可以查看while语句的执行过程,从而对while语句的执行过程有一个更深刻更直观的认识。

4.3.2  do…while循环:一直…只要…

前面介绍的while语句表达的“只要…就一直…”循环现象,是“先判断循环条件后执行循环动作”。然而在现实世界中,还有另外一类循环现象。例如:

一直不断地为祖国辛勤工作,只要我还活着;

一直接受用户输入数据,只要用户输入不为0 。

这类循环现象刚好与while语句表达的循环现象相反,总是先执行循环动作(工作、输入数据)后判断循环条件(还活着,输入不为0)。在自然语言中,我们可以用“一直…只要…”这样的句式来表达这种现象,刚好是”只要…就一直…”的倒置。与之对应地,在C++中,我们也将while语句倒置形成do…while…语句来表达这种循环现象。其语法格式如下:

do
{
循环体语句;
}
while ( 条件表达式 );

在执行的时候,do…while循环语句首先会执行一次循环体语句,然后再利用条件表达式对循环条件进行判断。如果条件表达式的值为true,则意味着循环条件仍然满足,可以再次执行循环体语句,开始下一次循环;反之,则意味着循环条件不再满足,直接结束整个循环。do…while循环语句的执行流程如图4-4所示。

下面来看一个实际的例子。在生活中,精打细算的妈妈们总是喜欢统计每月的收支情况。用自然语言来描述这一统计过程就是:一直不断地输入收支数目并将其累加到收支总数,只要还有剩下的收支数目。在这里,“还有剩下的收支数目”是do…while…的循环条件,我们用输入的收支数目为0表示没有剩余数目,换而言之,循环条件成了“只要收支数目不为0”。而“输入收支数目并将其累加到收支总数”就是这个do…while…循环要反复执行的动作了。这是一个典型的“一直…只要…”循环现象,用do…while…循环结构将其表达出来就是:

// 每月收支统计程序
#include <iostream>
using namespace std; int main()
{
// 输出用户提示
cout << "======每月收支统计程序======" << endl;
cout << "请输入你本月的收入(正数)和支出(负数),0表示输入结束。" << endl; // 收支数目,这里的初始值不是必须的
int nInput = ;
// 收支总数
int nTotal = ;
// 第一次循环,无条件执行循环动作
// 其后的循环,要在循环条件满足的情况下才能执行
do
{
// 接受用户输入的收支数目并保存到nInput
cin>>nInput;
// 对收支进行统计,将其加和到收支总数nTotal
nTotal += nInput;
} while( != nInput ) // 对循环条件进行判断,以决定是否进行下一次循环 // 输出统计结果
cout << "你本月的结余是:" << nTotal << endl; return ;
}

在执行的时候,do…while…语句第一次会无条件地执行一次循环体语句,然后才执行条件判断“while( 0 != nInput )” ,判断收支数目nInput是否为0,也就是判断循环条件是否依然满足,以决定是否进入下一次循环。这时的nInput中已经是用户第一次输入的收支数目了,如果为0,则表示后面没有收支数据了,“0 != nInput”的值为false,循环条件不再满足而直接结束整个do…while…循环语句。反之,则继续进行下一次循环,接受用户输入并将其累加到收支总数,然后再次判断循环条件是否依然满足以决定是否进行下一次循环。这个过程会不断循环往复地进行下去,直到用户输入nInput为0,循环条件不再满足为止。整个过程只需要输入各个收支数目,程序会循环接收这些数据并进行累加统计得到结果,这可比按计算器省事多了。赶紧把这个统计程序拿去献给老妈吧,肯定会得到一番奖赏的。

while和do…while都是用来表达循环现象的结构,且很多时候,两者之间可以相互转换。两者的差别在于,while语句是先判断循环条件后执行循环动作,而do…while…语句却刚好是反过来,先执行循环动作后判断循环条件。这也就意味着,do…while…语句的第一次循环可以无条件地执行,所以它更加适合于表达哪些第一次循环没有初始条件限制的循环现象。比如在收支统计程序中第一次输入收支数目时,任何时候任何情况都可以,没有什么初始条件限制。而while语句的每一次循环动作都要在循环条件满足的前提下执行,所以它更适合于表达哪些每次循环都有前提条件的循环现象。比如,在给汽车加油时,每一次我们都需要判断油箱是否已满,无论是第一次还是最后一次。

你好,C++(21)只要天还没黑,就一直在工地干活-4.3.1 while循环:只要…就一直…的更多相关文章

  1. php大力力 [013节]mySQL数据库乱码问题我还没解决

    <?php echo"测试<br>"; $sql_connection = mysql_connect("localhost","e ...

  2. 在各方面还没准备好的时候,大家一定要慎用border-box样式!!!!

    这几天,我被一个js问题困扰到癫狂了! 事情是这样的,我之前写了个功能非常复杂的纯jquery代码的前端gridview控件,实现了大量的功能和效果,在一些项目里也用得很好. 最近有个项目,样式做了调 ...

  3. 成功熬了四年还没死?一个IT屌丝创业者的深刻反思

    三个IT屌丝创业的故事 从前有三个屌丝,聚在一起做网络.提供免费的网络服务,砸锅卖铁,通宵达旦,除了卖肾,啥都做了.3年后终于做到了五百万用户.对于年轻人来说,能把五百万人玩弄于鼓掌之间,已经是很牛逼 ...

  4. 谁还没遇上过NoClassDefFoundError咋地——浅谈字节码生成与热部署

    谁还没遇上过NoClassDefFoundError咋地--浅谈字节码生成与热部署 前言 在Java程序员的世界里,NoClassDefFoundError是一类相当令人厌恶的错误,因为这类错误通常非 ...

  5. noi2018还没想好记

    前面说点什么.. 没想到吧 嘴上说着不写的彩笔博主最后还是写了这篇东西.. Day -inf 在雅礼集训,打了四场模拟赛.. 真正说打得好的.. 也就那么一场 身体很差 心态很差 状态很差 虽然有书读 ...

  6. C-Lodop提示“网页还没下载完毕,请稍等一下再操作.”

    该提示在Lodop旧版本中是: 提示"WebSocket没准备好,点确定继续",提示“C-Lodop没准备好”,新版本修改了该提示的描述“网页还没下载完毕,请稍等一下再操作.”,让 ...

  7. web工程启动时,在一个类中延迟加载Bean,因为该Bean类可能还没被JVM加载

     问题描述: (1)javaWeb项目启动中,还没启动完成,在下面这个类加载另一个Bean类, (2)通过getBean方法获取到该Bean,可以获取到,不为null (3)但是,调用该Bean的方法 ...

  8. 趁webpack5还没出,先升级成webpack4吧

    上一次将webpack1升级到3,也仅是 半年前,前端工具发展变化太快了,如今webpack4已经灰常稳定,传说性能提升非常高,值得升级. 一直用着的webpack3越来越慢,一分多钟的编译时间简直不 ...

  9. [转帖]速度快散热好 为什么U.2 SSD还没普及?

    速度快散热好 为什么U.2 SSD还没普及?   经典的影视剧中总有那么几位武林高手,江湖上只闻其名,不见其形.今天我们要聊的这位爷,誓要拳打南山M.2,脚踩北海SATA 3!它就是固态硬盘界久负盛名 ...

随机推荐

  1. 10 - 删除vtkDataObject中的Update Extent方法 VTK 6.0 迁移

    VTK6 引入了许多不兼容的变.其中之一是删除vtkDataObject中所有有关管道的方法.下面列出来的就是其中的一些方法: SetUpdateExtent(int piece, int numPi ...

  2. wireshark tcp 协议分析

      虽然知道wireshark是抓包神器,只会大概大概用一下,还用一下下tcpdump,略懂一点BPF过滤器,也知道一点怎么用wirkshark过滤相关的报文,但是对于详细的字段的含义,如何查看TCP ...

  3. 用C#实现网络爬虫(一)

    网络爬虫在信息检索与处理中有很大的作用,是收集网络信息的重要工具. 接下来就介绍一下爬虫的简单实现. 爬虫的工作流程如下 爬虫自指定的URL地址开始下载网络资源,直到该地址和所有子地址的指定资源都下载 ...

  4. optimize the performance

    http://en.wikipedia.org/wiki/Web_Performance_Optimization http://www.stevesouders.com/blog/2011/08/2 ...

  5. 主流屏幕对比:IPS/LTPS/CGS/IGZO/AMOLED

    IPS.LTPS.CGS.IGZO.AMOLED都是什么屏幕又有什么区别?目前的手机屏幕技术实在太多,本文旨在介绍各种面板以及屏幕技术,便于大家更好地进行区分. 近年来手机屏幕技术层出不穷,早在几年前 ...

  6. KEIL C51中的_at_关键字

    绝对位置变量 变量可以在你的C程序中的绝对内存地址位于源模块使用_at_关键字.此功能的用法是: 类型 _ memory_space _ 变量名 _at _  常数 ; 其中:memory_space ...

  7. Chapter 6 — Improving ASP.NET Performance

    https://msdn.microsoft.com/en-us/library/ff647787.aspx Retired Content This content is outdated and ...

  8. mysql 主从 配置和同步管理

    首先呢,需要有两个mysql服务器.如果做测试的话可以在同一台机器上装两个mysql服务程序,注意要两个运行程序的端口不能一样.我用的是一个是默认的3306,从服务器用的是3307端口. 在主服务创建 ...

  9. C++ BigInteger 大整数类模板(转)

    #include <deque> #include <vector> #include <iostream> #include <string> #in ...

  10. 【数学】HDU 5761 Rower Bo

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5761 题目大意: 船在(0,a),船速v1,水速v2沿x轴正向,船头始终指向(0,0),问到达(0, ...