
第6章 循环控制语句
(
视频讲解:57分钟)
当程序要反复执行某一操作时,就必须使用循环结构,比如遍历二叉树、输出数组元素等。本章将对程序设计的另外一种结构—循环结构进行详细讲解。
通过学习本章,读者主要掌握以下内容:
while语句的使用
do…while语句的使用
while语句与do…while语句的区别
for语句的使用
循环语句的嵌套使用
跳转语句的使用
6.1 while和do…while循环

视频讲解
学习和使用C#语言的目的是使用它编写出能够解决现实生活中问题的程序。生活中存在着很多重复性的工作,有时甚至不知道这种工作需要重复的次数,那么如何用简单的C#语句解决这种复杂的、带有重复性的问题呢?C#中提供了循环控制语句来解决这类问题。C#中的循环语句主要有while,do…while和for,本节将首先对while和do…while循环的使用进行讲解。
6.1.1 while循环
while语句用来实现“当型”循环结构,它的语法格式如下:


图6.1 while循环流程图
表达式一般是一个关系表达式或一个逻辑表达式,其表达式的值应该是一个逻辑值真或假(true和false),当表达式的值为真时,开始循环执行语句;而当表达式的值为假时,退出循环,执行循环外的下一条语句。循环每次都是执行完语句后回到表达式处重新开始判断,重新计算表达式的值。
while循环的流程图如图6.1所示。
【例6.01】200多年以前,在德国的一所乡村小学里,有一个很懒的老师,他总是要求学生们不停地做整数加法计算,在学生们将一长串整数求和的过程中,他就可以在旁边名正言顺地偷懒了。有一天,他又用同样的方法布置了一道从1加到100的求和问题。正当他打算偷懒时,就有一个学生说自己算出了答案。老师自然是不信的,不看答案就让学生再去算,可是学生还是站在老师面前不动。老师被激怒了,认为这个学生是在挑衅自己的威严,他是不会相信一个小学生能在几秒钟内就将从1到100这100个数的求和问题计算出结果。于是抢过学生的答案,正打算教训学生时,突然发现学生写的答案是5050。老师愣住了,原来这个学生不是一个数一个数的加起来的,而是将100个数分成1+100=101、2+99=101一直到50+51=101等50对,然后使用101*50=5050计算得出的,这个聪明的学生就是德国著名的数学家高斯。本实例将使用while循环挑战高斯,通过程序实现1到100的累加,代码如下:(实例位置:资源包\源码\06\6.01)

程序运行结果如下:

注意
(1)循环体如果是多条语句,需要用大括号括起来,如果不用大括号,则循环体只包含while语句后的第一条语句。
(2)循环体内或表达式中必须有使循环结束的条件,例如,例6.01中的循环条件是iNum <=100,iNum的初始值为1,循环体中就用iNum++来使得iNum趋向于100,使循环结束。
6.1.2 do…while循环
有些情况下无论循环条件是否成立,循环体的内容都要被执行一次,这时可以使用do…while循环。do…while循环的特点是先执行循环体,再判断循环条件,其语法格式如下:


图6.2 do…while循环流程图
do为关键字,必须与while配对使用。do与while之间的语句称为循环体,该语句是用大括号{}括起来的复合语句。循环语句中的表达式与while语句中的相同,也为关系表达式或逻辑表达式,但特别值得注意的是:do…while语句后一定要有分号“;”。do…while循环的流程图如图6.2所示。
从图6.2中可以看出,当程序运行到do…while时,先执行一次循环体的内容,然后判断循环条件,当循环条件为“真”的时候,重新返回执行循环体的内容,如此反复,直到循环条件为“假”,循环结束,程序执行do…while循环后面的语句。
【例6.02】使用do…while循环编写程序实现1到100的累加,代码如下:(实例位置:资源包\源码\06\6.02)

说明
程序运行结果与例6.01的运行结果一样。
6.1.3 while和do…while语句的区别
while语句和do…while语句都用来控制代码的循环,但while语句适用于先条件判断,再执行循环结构的场合;而do…while语句则适合于先执行循环结构,再进行条件判断的场合。具体来说,使用while语句时,如果条件不成立,则循环结构一次都不会执行,而如果使用do…while语句时,即使条件不成立,程序也至少会执行一次循环结构。
练一练
请分析下边两段代码分别执行几次循环?

6.2 for循环

视频讲解
for循环是C#中最常用、最灵活的一种循环结构,for循环既能够用于循环次数已知的情况,又能够用于循环次数未知的情况,本节将对for循环的使用进行详细讲解。
6.2.1 for循环的一般形式
for循环的常用语法格式如下:

for循环的执行过程如下:
(1)求解表达式1;
(2)求解表达式2,若表达式2的值为“真”,则执行循环体内的语句组,然后执行下面第(3)步,若值为“假”,转到下面第(5)步;
(3)求解表达式3;
(4)转回到第(2)步执行;
(5)循环结束,执行for循环接下来的语句。
for循环的流程图如图6.3所示。
for循环最常用的格式如下:

图6.3 for循环流程图

【例6.03】使用for循环编写程序实现1到100的累加,代码如下:(实例位置:资源包\源码\06\6.03)

说明
程序运行结果与例6.01的运行结果一样。
多学两招
可以把for循环改成while循环,代码如下:

6.2.2 for循环的变体
for循环在具体使用时,有很多种变体形式,比如,可以省略“表达式1”、省略“表达式2”、省略“表达式3”或者3个表达式都省略,下面分别对for的常用变体形式进行讲解。
1. 省略“表达式1”的情况
for循环语句的一般格式中的“表达式1”可以省略,在for循环中“表达式1”一般是用于为循环变量赋初值,若省略了“表达式1”,则需要在for循环的前面为循环条件赋初值,例如:

此时,需要在for循环之前,为iNum这个循环变量赋初值。程序执行时,跳过“表达式1”这一步,其他过程不变。
常见错误
把上面for循环语句改成for(iNum <= 100; iNum ++),进行编译,会出现如图6.4所示的错误提示。

图6.4 使用for循环语句中缺少分号错误
出错是因为省略“表达式1”,但是其后面的分号不能省略。
2. 省略“表达式2”的情况
使用for循环时,“表达式2”也可以省略,如果省略了“表达式2”,则循环没有终止条件,会无限地循环下去,针对这种使用方法,一般会配合后面将会学到的break语句等来结束循环。
省略“表达式2”情况的举例:

这种情况的for循环相当于以下while语句:

3. 省略“表达式3”的情况
使用for循环时,“表达式3”也可以省略,但此时程序设计者应另外设法保证循环变量的改变。例如,下面的代码在循环体中对循环变量的值进行了改变:

此时,在for循环的循环体内,对iNum这个循环变量的值进行了改变,这样才能使程序随着循环的进行逐渐趋近并满足程序终止条件。程序执行时,跳过“表达式3”这一步,其他过程不变。
4. 3个表达式都省略的情况
for循环语句中的3个表达式都可以省略,这种情况既没有对循环变量赋初值的操作,又没有循环条件,也没有改变循环变量的操作,这种情况下,同省略“表达式2”的情况类似,都需要配合使用break语句来结束循环,否则,会造成死循环。
例如,下面的代码就将会成为死循环,因为没有能够跳出循环的条件判断语句:

6.2.3 for循环中逗号的应用
在for循环语句中,“表达式1”和“表达式3”处都可以使用逗号表达式,即包含一个以上的表达式,中间用逗号间隔。例如,在“表达式1”处为变量iNum和iSum同时赋初值:

6.3 循环的嵌套

视频讲解
在一个循环里可以又包含另一个循环,组成循环的嵌套,而里层循环还可以继续进行循环嵌套,构成多层循环结构。
3种循环(while循环、do…while循环和for循环)之间都可以相互嵌套。例如,下面的6种嵌套都是合法的嵌套形式:
while循环中嵌套while循环

do…while循环中嵌套do…while循环

for循环中嵌套for循环

while循环中嵌套do…while循环

while循环中嵌套for循环

for循环中嵌套while循环

【例6.04】使用嵌套的for循环打印九九乘法表,代码如下:(实例位置:资源包\源码\06\6.04)

说明
本实例的代码使用了双层for循环,第一个循环可以看成是对乘法表的行数的控制,同时也是每一个乘法公式的第二个因子;因为输出的九九乘法表是等腰直角三角形排列的,第二个循环控制乘法表的列数,列数的最大值应该等于行数,因此第二个循环的条件应该是在第一个循环的基础上建立的。
程序运行效果如图6.5所示。

图6.5 使用循环嵌套打印九九乘法表
6.4 跳转语句

视频讲解
C#语言中的跳转语句主要包括break语句和continue语句,跳转语句可以用于提前结束循环,本节将分别对它们进行详细讲解。
6.4.1 break语句
第5章中已经介绍过使用break语句可以使流程跳出switch多分支结构,实际上,break语句还可以用来跳出循环体,执行循环体之外的语句。break语句通常应用在switch,while,do…while或for语句中,当多个switch,while,do…while或for语句互相嵌套时,break语句只应用于最里层的语句。break语句的语法格式如下:

说明
break一般会结合if语句进行搭配使用,表示在某种条件下,循环结束。
【例6.05】修改例6.01,在iNum的值为50时,退出循环,代码如下:(实例位置:资源包\源码\06\6.05)

程序运行结果如下:

6.4.2 continue语句
continue语句的作用是结束本次循环,它通常应用于while,do…while或for语句中,用来忽略循环语句内位于它后面的代码而直接开始一次的循环。当多个while,do…while或for语句互相嵌套时,continue语句只能使直接包含它的循环开始一次新的循环。continue的语法格式如下:

说明
continue一般会结合if语句进行搭配使用,表示在某种条件下不执行后面的语句,直接开始下一次的循环。
【例6.06】通过在for循环中使用continue语句实现1到100之间的偶数的和,代码如下:(实例位置:资源包\源码\06\6.06)

程序运行结果如下:

6.5 小结
本章对流程控制语句中的循环结构控制语句进行了详细讲解,学习本章时,读者应该重点掌握while语句、do…while语句和for语句,同时应该对循环结构中常用的跳转语句有所了解。通过对本章的学习,读者应该能够熟练掌握循环结构控制语句的使用方法,并能在实际应用中使用。
6.6 实战
6.6.1 实战一:猜数字游戏
使用C#开发一个猜数字的小游戏,随机生成一个1~200的数字作为基准数,玩家每次通过键盘输入一个数字,如果输入的数字和基准数相同,则成功过关,否则重新输入。如果玩家输入–1,表示退出游戏,运行结果如图6.6所示。(实例位置:资源包\源码\06\实战\01)

图6.6 猜数字游戏
6.6.2 实战二:输出金字塔形状
使用循环嵌套输出金字塔形状,具体实现时,需要考虑的问题有3点:首先要控制三角形输出的行数,其次控制三角形的空白位置,最后将三角形进行显示,运行效果如图6.7所示。(实例位置:资源包\源码\06\实战\02)

图6.7 使用循环嵌套输出金字塔形状