11.1.1 break的作用与用法

 

循环就象绕圈子。比如,体育课,跑1200米,跑道一圈400米,所以我们要做的事就是一边跑一边在心里计数(当然要已数,否则老师万一少计一圈,我们可就玩完了),当计数到3圈时,“循环”结束。

如果,我在跑步时不幸由于体力不支而晕倒……怎么办?

 

有两种办法,一种是在判断是否继续循环的条件中加入新增条件的判断:

假设原来的循环表达为:

 

while(已跑完的圈数 < 3)

{

跑一圈……;

}

 

那么,加上附加条件后,循环表达为:

 

while(已跑完的圈数 <3 && 我还跑得好好的) //&& 就是"并且",没忘吧?

{

跑一圈……

}

 

第二种方法是在循环中使用条件分支,在指定的条件成立时,中途跳出循环,用于实现跳出的关键字为:break。

 

while(已跑的圈数 < 3 )

{

跑一圈……;

if(我身体感觉不妙)

break;

}

 

在循环中,每跑完一圈,都检查一下自已是否感觉不妙,如果是,则程序执行break,直接跳出while,而不管此时圈数是否到达3圈。

 

还记得“小女孩买裙子”的故事吗?那时候,我们将“父母不给买小红裙 && 我还没有哭累”作为循环继续的条件,如果使用break,则可以写成这样:

while(父母不给买小红裙)

{

我哭;

if(我哭累了)

break;

}

 

在循环中,“我”每哭一次,都想想是否累了,如果是,则程序执行break,直接跳出while,而不管此时爸妈是否已经买了我的裙。

 

通过这两个例子,你应该注意到了,如果要用break,则if的条件(也就是要执行break分支的条件),正好是把原来放在循环判断中的条件反正过来。比如,原来是判断“我还跑得好好的”,现在则是判断“我身体感觉不妙”;原来是判断“我还没有哭累”,现在是判断“我哭累了”。

一句话,原来是判断“是否继续循环”,现在是判断“是否跳出循环”……

 

再来看那个“可以多次统计”的统计程序。看看是否也能把它改成使用break来结束循环。

为了节省篇幅同时也是为了突出重点,我们将其中用于实现一次统计的代码,用一句伪代码来实现。(什么叫伪代码?我们用得很经常啊,就是那些用自然语言写的“代码”,这些代码当然无法在计算机上运行,它们只是要方便地表达实际代码要实现的功能)。

 

int main(int argc, char* argv[])

{

实现统计一个学员的成绩; //伪代码,详细代码请见上章相关部分

 

  do

{

//提问是否继续统计:

cout <<"是否开始新的统计?(Y/N)?";

cin >> c;

}

while( c == 'y' || c == 'Y');

}

 

改成用 break;

int main(int argc, char* argv[])

{

实现统计一个学员的成绩; //伪代码,详细代码请见上章相关部分

 

  do

{

//提问是否继续统计:

cout <<"是否开始新的统计?(Y/N)?";

cin >> c;

     //如果用户输出的不是字母Y,说明他不想继续统计了,我们需要中断循环。

     if( c != 'y' && c != 'Y')

         break;

}

while (true);

}

 

请首先 while(true)部分,其条件直接写上真(true),表明这是一个无条件的循环(即,循环将无条地一直持续下去),这岂不犯了程序界的武林大岂:成了一个“死循环”?其实,相信你已明白,在循环体内,有一个break的分支在呢,当判断用户输入的字母既不是小写的y,也不是大写的Y,break就起它能起的作用了。

 

三个例子,都是从循环判断的条件摘出一部分或全部(最后一个例子),然后循环体中,采用一个if判断,结束break来跳出循环。可能你会问:为什么要break呢?直接用原来的方法,在while处判断条件不是很好吗?

 

break的长处在于,它可以在循环体内的任意位置进行判断。

继续上一例。假设我们出于慎重,想在用户按入 N 时,再问他一句是否真的退出统计,则此时显示出了break的方便:

int main(int argc, char* argv[])

{

实现统计一个学员的成绩; //伪代码,详细代码请见上章相关部分

 

  do

{

//提问是否继续统计:

cout <<"是否开始新的统计?(Y/N)?";

cin >> c;

 

//如果用户输出的不是字母Y,说明他不想继续统计了,我们需要中断循环。

if( c != 'y' && c != 'Y')

     {

          //出于慎重起见,我们要再问一句用户是否真的不统计了?

          cout << "您真的不想继续计算了?(Y:真的结束 / N:继续统计)";

          cin >> c;

          

          //这回,如果用户输入Y,表明他真的不统计了:

          if( c == 'Y' || c == 'y')

               break;

}

}

while (true);

}

 

在上面例子,由于用户的两次输入我们都采用变量 c (char 类型)接收。但如果第一次输入 字母‘Y’时,循环需继续,但如果用户是在第二次输入‘Y',则表示是真的不统计了,循环却必须结束;所以,此时while无法仅凭c的值来做出正确判断,但,采用break,正如上面代码,我们在合适的位置安排一个break,从而直观地实现了。

 

当然,这里仅为了讲学方便而举此例,如果你真的在程序中为了一个“是否继续统计”而问了用户两遍,可能会被用户骂做“神经质”。不过,如果是删除某些重要数据(直接删除,不可恢复的情况),多问一次就选得很重要了。(比如句神英语删除用户操作就会在最后多问一句“真的要说再见吗?我们会想你的……”)

 

 

再举一例,看我们前面关于跑步的例子:

 

while(已跑的圈数 < 3 )

{

跑一圈……;

if(我身体感觉不妙)

break;

}

 

这段代码有点问题,因为判断“我身体感觉不妙”是在跑完一圈之后……很可能我在某一圈刚开始跑时就觉得肚子剧痛,极可能是得阑尾炎啊!按照这段程序,我只有坚持跑完一圈后,才能break了……

要完美解决这个问题,我们将在本章再后讲到,现在先采用一个“通融”的办法,我们允许你每跑100米就检查一次吧:

 

while(已跑完图数 < 3)

{

跑第1个100米;

if(我身体感觉不妙)

break;

 

跑第2个100米;

if(我身体感觉不妙)

break;

 

跑第3个100米;

if(我身体感觉不妙)

break;

 

跑第4个100米;

if(我身体感觉不妙)

break;

}

代码中,我们将1圈拆为4个100米,每跑完1/4,我们就检查一次是否身体不对。看明白这个例子,我想你对break的用途和用法,可以算是理解了。

 

11.1.2 break 的一个“高级用法”

 

本小节不是很适于没有多少实际编程经历的初学者,所以初学者可以跳过,以后再回头阅读。当然,所谓的“高级用法”的确是应该加对引号的,所谈的内容只是一个高手们常用小小技巧。

使用do...break...while简化多级条件判断的结构。

 

如果你写过不少代码,那么一定会不时遇到类似下的情况:

假设要找到文件A,复制该文件为B;然后打开B文件,然后往B文件内写入一些内容;最后在写入成功后,我们需要再进行一些相关操作。

在此过程,遇到以下情况时将放弃后续的操作,认为是操作失败:

1、如果A文件不存在;

2、如果B文件已经存在,并且询问用户是否覆盖时,用户回答“不”;

3、无法复制出B文件;

4、无法打开B文件;

5、无法写入B文件;

6、无法正常关闭B文件。

 

用伪代码写该段程序为:

 

if( A文件存在 )

{

执行A文件的相关操作;

if( B文件不存在 || 用户允许覆盖原有B文件)

{

复制A文件为B文件;

if(复制文件成功)

{

 打开B文件;

       if(打开文件成功)

{

写入文件;

         if(写入成功)

         {

关闭B文件;

if(关闭成成功)

           {

执行其它必须在一切成功后进行的操作。

             ……

}

  }

 }

}

}

}

 

可能有些操作和判断可以同时处理,但这个程序的繁琐仍然不可避免,而现实中程序的复杂性往往要远过于此例。从语法上看,这个例子没有任何错误,但它的一层套一层的条件判断却让人难以书写,阅读,调试,在复杂的情况就容易造成人为的错误(比如最马虎的,花括号匹配不对等……)。

 

同样一段代码“程序老鸟”是这样写的:

 

do

{

if(A文件不存在)

break;

执行A文件的相关操作;

if(B文件存在 && 用户不允许覆盖)

break;

复制A文件为B文件;

if(复制不成功)

break;

 

打开B文件;

if(打开B文件不成功)

break;

 

写入文件;

if(写入文件不成功)

break;

 

关闭B文件;

if(关闭不成功)

break;

 

执行其它必须在一切成功后进行的操作。

  ……

}

while(false);

 

看,代码是不是“直”了很多?这里用了do..while,可是根本不是为了循环,而是为了使用它的break功能。每当有操作不成功,就直接用break跳出循环。所以循环条件总是一个“永假” false。

在一个程序中,这种结构相当的多,为了更加一步淡化while的原来的循环用途,我们非常值得在代码加入两个共用的宏:

#define BEG_DOWHILE do {

#define END_DOWHILE } while(false);

 

这里举的是do...while结构,在某些情况下,可以使用while...来实现类似功能。

 

11.1.3 break 在for循环中的一点注意

 

前面举的例子都是do...while或while,break在for循环也一个样。请看下面例题:

 

例一:从1开始累加,每次递增1,请问累加到哪个数,累加和超过2000?请输出该数,及当时的累加和。

 

分析:和求1~100的累加和类似,只是在发现累加和已经超过2000时,就输出当前累加的数,然后结束循环。

 

for(int i=1,sum=0;;i++)

{

sum += i;

if(sum > 2000)

{

cout << i << "," << sum << endl;

break;

}

}

 

输出结果为:

 

63,2016

 

关于这段例子,需要注意三点:1、循环条件初始的位置,我们同时声明两个变量;2、没有循环条件。为了解这两点注意。

 

最后一点注意是关于break和“条件因子变化”的注意。我们知道,for每执行一遍循环体后,都将执行一次“条件因子变化”语句(见上图③)。现在需要注意的是:

在for循环中,执行break后,“条件因子变化”语句同样被跳过,没有被执行循环就被中断。

至此,break 在 while,do...while,for中的用法我们都已见过。不过,你还记得吗,我们最早学到break是在哪里?在讲条件分支语句中switch里。如果你有点忘了那里的break是起什么作用,现在就去看看吧。

 

11.1.4 多层循环中的break

 

break 只能跳出当前层的循环,所以,如果有多层循环,则在内层的break跳出循环后,外层的循环还将继续。

前面说跑步的例子,一圈400米,我们每跑100检查一下是否肚子疼什么的,如果疼得利害就break,不跑了。这和现实不符,我们应该每跑一步就检查一次是否肚子疼最合理。

一圈得分成几步呢?显然不能再像上面分成四次检查那样写代码了。我们加一层循环,也就是把跑一圈的工作用一个循环来实现:

 

while(一圈未结束)

{

跑一步;

}

 

然后,我们在每跑完一步时加入一个判断:

 

while(一圈未完)

{

跑一步;

if(我身体感觉不妙)

break;

}

 

把这跑一圈的代码加入外层循环:

while(已跑完图数 < 3)

{

while(一圈未完)

{

跑一步;

if(我身体感觉不妙)

     break;

}

}

外层的while用于负责一圈一圈循环跑完三圈,内层的while用于负责一步一步地循环跑完一圈,同时负责每跑一步就检查是否身体不妙,若身体不舒服,就跳出循环,不跑了。看起来代码很完美,其实BUG已经产生:问题就在那个break。当“我身体感觉不妙”后,程序遇上break,跳出内层while,落入外层的while,外层的循环可没有被break,所以程序将继续外层的循环。假如你跑第一圈跑了一半时肚子疼,按照这段程序逻辑,那好这第一圈剩下的一半你可以不用跑了,但后面的两圈你还得继续。

解决的第一种方法是:

while(已跑完图数 < 3)

{

while(一圈未完)

{

跑一步;

if(我身体感觉不妙)

     break;

}

if(我身体感觉不妙)

   break;

}

我们在外层也进行了一次判断,这样当然就可保证从内层跳出来以后,外层的循环也被跳出。但在内层已经做过一次“感觉”的情况下,外层还要重新“感觉”一次,这种代码让人不爽,所以我们可以加一个变量,用于记住现在的身体状态:

bool needBreak = false; //是否需要跳出循环

while(已跑完图数 < 3)

{

while(一圈未完)

{

跑一步;

if(我身体感觉不妙)

{

needBreak = true; //做一标志,需要break;

     break;

}

if(needBreak)

   break;

}

虽然本人的课程并不是绕什么圈子,可是在这有关break的长篇累牍的文字中,想必各位现在头脑里只有一个词,只有一个念头:break。想 break?后面的课程就不要啦?不可能,我们还是continue吧。

 

11.2 continue

 

continue 汉意为继续。它的作用及用法和break类似。重要区别在于,当前循环遇到break,是直接结束循环,而若遇上continue,则是停步当前这一遍循环,然后直接尝试下一遍循环。我把“尝试”加粗以引起注意,为什么要注意原因后面再说,请先看下面关于break和continue的对比:

 

continue并不结束整个循环,而仅仅是中断的这一遍循环,然后跳到循环条件处,继续下一遍的循环。当然,如果跳到循环条件处,发现条件已不成立,那么循环也将结束,所以我们称为:尝试下一遍循环。

 

例二:求整数1~100的累加值,但要求跳过所有个位为3的数。

分析:在循环中加一个判断,如果是该数个位是3,就跳过该数不加。

 

如何判断一个1到100中,哪些整数的个位是3呢?还是 % ,将一个2位以内的正整数,除以10以后,余数是3,就说明这个数的个位为3。

比如: 23 ,除以10,商2,余数3。这里我们不需要商,所以用求余(也称为求模)运算:23 % 10 = 3。

int sum = 0;

for(int i = 1; i<=100;i++)

{

if( i % 10 == 3)

continue;

sum += i;

}

cout << sum << endl;

和break正相反:

在for循环中,执行continue后,“条件因子变化”语句没有被跳过,将被执行一次,然后再尝试循环的下一遍。

在上例中,当条件 i %10 ==3 成立时,continue 被执行,于是,程序首先执行 i++;然后执行 i <= 100 的判断。如果将该段程序改成while,正确答案为:

int sum = 0;

int i = 1;

while(i <= 100)

{

if( i % 10 == 3)

{

i++;

continue;

}

sum += i;

i++;

}

cout << sum << endl;

请注意程序中的两句"i++;",缺一不可。

11.3 goto

臭名昭著的goto出场了。

goto的汉义为“转到”,在计算机语言里,它的完整名称为:“无条件跳转语句”。几乎所有高级语言都会劝你尽量不要使用它goto。因为它会破坏程序的模块性,严重降低一段程序的可读性。若是老外写的书,则比喻使用大量goto的代码:“像意大利面条”。嗯,其实北京的杂酱面也很缠绕……可惜没有走向世界。

goto的用法是,首先要在代码中某处加上一个位标(也称标号),然后在代码中的需处,加上goto,并写让要跳转到位标。比如你在第三行代码加一个位标:A : ,然后可以在第10行写上一个goto A,程序执行到该行时,就将跳到第三行。

加位标的方法是在一空行加上位标的名称,命名规则和变量一样,但最后要加上一冒号“:”。

例如:

int i = 1;

A :

cout << i << endl;

i++;

if(i <= 10)

goto A;

... ..

goto 虽然号称“无条件跳转”,事实上倒是有些条件限制。主要是三条。

1、goto只能在当前的同一程序段内跳转;

2、goto 可以从循环内跳转到循环外的代码,但不能从循环外的代码跳到循环内;

3、在有goto的跳转范围内,不能再使用C++允许的临时变量声明。

  好了,其实笔者写程序近10年,惟一用到goto的地方就是:将一段简单的程序故意用goto写得面目全非,以期能让破解程序的人因为眼晕而放弃功击……一句老话:如果没有什么特殊理由,不要在程序里使用goto。

break的作用与用法相关推荐

  1. PreTranslateMessage作用和用法

    PreTranslateMessage作用和用法 PreTranslateMessage是消息在送给TranslateMessage函数之前被调用的,绝大多数本窗体的消息都要通过这里,比較经常使用,当 ...

  2. break 和continue的用法 java——CSDN

    /*** * @Title: test_break_coutuint* @Description: 该方法的主要作用:break 和continue的用法* 如果成绩等于5结束当前循环* 如果等于10 ...

  3. python中continue用法案例_记录今天学习python中for与while循环针对break和continue的用法...

    python中有两个主要的循环for与while,其中针对这两个循环有两种不同的中断用法break与continue. 首先先看下面的循环代码: 1: for i in range(10):#变量i带 ...

  4. c语言break语句作用,解析c语言switch中break语句的具体作用

    解析c语言switch中break语句的具体作用 问题:break在for循环.while循环等循环流程控制中起的作用是停止执行break后面的语句,跳出本次循环,并跳出该循环控制体: 在switch ...

  5. CyclicBarrie(循环栅栏)的作用与用法

    CyclicBarrie的作用与用法 一.CyclicBarrie的作用 CyclicBarrier循环栅栏(循环屏障)是一个多线程同步的辅助工具类,它允许一组线程在到达某个等待屏障点(common ...

  6. break的三种用法

    break的三种用法 1.switch中使用 /*** switch*/ System.out.println("----------switch"); switch (1) {c ...

  7. java package作用_java import、package作用与用法

    java import.package作用与用法 有些人写了一阵子Java,可是对於Java 的package 跟import 还是不太了解很多人以為原始码 .java 档案中的import 会让编译 ...

  8. MySQL数据类型中DECIMAL的作用和用法

    在MySQL数据类型中,例如INT,FLOAT,DOUBLE,CHAR,DECIMAL等,它们都有各自的作用,下面我们就主要来介绍一下MySQL数据类型中的DECIMAL类型的作用和用法. 一般赋予浮 ...

  9. JAVA中的break[标签]continue[标签]用法

    原文:JAVA中的break[标签]continue[标签]用法 注意:JAVA中的标签必须放在循环之前,且中间不能有其他语句.例如:tag:for或while或do--while; 1.使用brea ...

最新文章

  1. python中opencv安装_怎么为python安装opencv模块-百度经验
  2. caj转pdf_CAJ转PDF文件,这恐怕是最全的方法总结了!
  3. 安装 SharePoint 2013 Foundation
  4. 两个重要极限_算法数学基础-概率论最重要两个结论:大数定律及中心极限定理...
  5. 待支付取件费用是什么意思_1元保管费与直接取件,你赞赏丰巢快递柜了吗?...
  6. SSM错误:Exception in thread “main“ java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletReque
  7. 单实例数据库迁移到rac环境(四)下
  8. 使用代码对现实世界进行抽象,软件设计和思维。
  9. 用正则验证用户输入文本框的内容是否是中文汉字
  10. 离线手动更新卡巴斯基
  11. java读取和写入txt_Java读取和写入txt文件
  12. python编的俄罗斯方块游戏_Python编写俄罗斯方块小游戏
  13. 移动硬盘无法访问设备未就绪资料找到的法子
  14. 保姆级教程:手把手教你搭建个人网站
  15. D. Factorial Divisibility
  16. 如何判断样本标注的靠谱程度?置信度学习(CL)简述
  17. vue项目中动态创建模块以满足客户定制化需求的解决方案
  18. Kylin常见错误及解决方法
  19. Windows10消费版和商业版有什么区别
  20. RobotStudio软件:机器人仿真视频录制功能使用方法

热门文章

  1. Can‘t bind to ‘xxx‘ since it isn‘t a known property of ‘xxx‘,dom配置动态属性时候报错
  2. Android动画学习记录一(Android动画种类、补间动画和帧动画)
  3. 笔记本用联通3G上网卡上网掉线
  4. android开发 wifi开发不稳定性测试
  5. 两台计算机ping上传文件,两台电脑传文件(两台电脑之间如何快速传输几百G的文件)...
  6. mysql导入与导出(备份)
  7. Visual Studio 2012未能正确加载解决方案中一个或多个项目。有关详细信息,请参见“输出”窗口。
  8. hey! 最后给你的一封信!
  9. 青龙面板的安装与使用
  10. matlab szj,matlab求微分方程的解实验报告4.doc