2.1.2 循环语句
循环语句可以实现一个程序模块的重复执行,它对于简化程序、更好地组织算法有着重要的意义。C#提供了四种循环语句,分别适用于不同的情形:while语句、do-while语句、for语句、foreach语句。
2.1.2.1 while语句
while语句有条件地将内嵌语句执行0遍或若干遍,语句的格式为
它的执行顺序是:
1)计算布尔表达式boolean-expression的值。
2)当布尔表达式的值为真时,执行内嵌语句embedded-statement一遍,程序转至第1)步。
3)当布尔表达式的值为假时,while循环结束。
下面来看一个简单的例子,该例在数组中查找一个指定的值,如找到就返回数组下标,否则返回并报告。
程序清单 2-3:
while语句中允许使用break语句结束循环,执行后续语句;也可以用continue语句来停止内嵌语句的执行,继续进行while循环。
我们使用下面的程序片段来计算一个整数x的阶乘值:
2.1.2.2 do-while语句
do-while语句与while语句不同的是:它将内嵌语句执行至少一遍。语句的格式为
它按如下顺序执行:
1)执行内嵌语句embedded-statement一遍。
2)计算布尔表达式boolean-expression的值,为true则回到第1)步,为false则终止do循环。在do-while循环语句同样允许用break语句和continue语句实现与while语句中相同的功能。
我们看一下如何使用do-while循环来实现求整数的阶乘:
2.1.2.3 for语句
for语句是C#中使用频率最高的循环语句,在事先知道循环次数的情况下使用for语句是比较方便的。for语句的格式为
其中,initializer、condition、iterator这三项都是可选项:initializer为循环控制变量做初始化,循环控制变量可以有一个或多个(用逗号隔开);condition为循环控制条件,也可以有一个或多个语句;iterator按规律改变循环控制变量的值。应注意初始化循环控制条件和循环控制都是可选的。如果忽略了条件,就会产生死循环,要用跳转语句break或goto才能退出。
for语句执行顺序如下:
1)按书写顺序将initializer部分(如果有的话)执行一遍,为循环控制变量赋初值。
2)测试condition(如果有的话)中的条件是否满足。
3)若没有condition项或条件满足,则执行内嵌语句一遍,按iterator改变循环控制变量的值回到第2)步执行。
4)若条件不满足则for循环终止。
下面的例子非常简单,打印数字1到9,但它却清楚地显示出了for语句是怎样工作的:
for语句可以嵌套使用,帮助我们完成大量重复性、规律性的工作。
下面的例子用于打印杨辉三角形:
程序清单 2-4:
运行程序的结果为
还以求整数的阶乘为例,代码可以这样写:
同样可以用break和continue语句来和循环判断符合语句中的逻辑表达式配合使用达到控制循环的目的。仍然以打印数字为例,如果要求打印除7以外的0到9之间的数字,只要在for循环执行到7时,跳过打印语句就可以了。
2.1.2.4 foreach语句
foreach语句是在C#中新引入的,C和C++中没有这个语句,而Visual Basic的程序员应该对它不会陌生,它表示收集一个集合中的各元素,并针对各个元素执行内嵌语句。语句的格式为
其中,类型(type)和标识符(identifier)用来声明循环变量表达式(expression)对应集合,每执行一次内嵌语句,循环变量就依次取集合中的一个元素,代入其中。在这里,循环变量是一个只读型局部变量,如果试图改变它的值或将它作为一个ref或out类型的参数传递,都将引发编译时错误。
foreach语句中的expression必须是集合类型,如果该集合的元素类型与循环变量类型不一致,则必须将集合中的元素类型显式转换为循环变量元素类型。
集合表示一组相同或相似的数据项总的描述。那么在C#中究竟什么样的类型算是集合类型呢?我们从语法上给出集合类型的定义:
1)该类型必须支持一个形为GetEnumerator的公有的非静态方法,该方法的返回类型为结构类或接口。
2)形为GetEnumerator的方法,返回的结构类或接口应当包含一个公有的非静态的方法MoveNext,该方法的返回类型为布尔型。
3)形为GetEnumerator的方法,返回的结构类或接口应当包含一个公有的非静态的属性Current,该属性可以读出。
如果一个类型同时满足以上三个条件,该类型称为集合类型,Current属性的类型叫作该集合类型的元素类型。
我们姑且不论集合类型的具体形式,只从foreach语句的使用角度举一个例子。假设Prime是一个满足条件的集合类型,它的元素类型为1000以内的质数,MyInt是我们自定义的一个类型,其范围为200到300之间的整数。下面这段程序用于在屏幕上显示出从200到300之间的所有质数:
程序清单 2-5:
顺便说一句,数组类型是支持foreach语句的。对于一维数组执行顺序是从下标为0的元素开始,一直到数组的最后一个元素。对于多维数组元素,下标的递增是从最右边那一维开始的,依此类推。同样break和continue可以出现在foreach语句中,功能不变。