
3.2 循环
在程序设计中,有时需要反复执行一段相同的代码,这时就需要使用循环结构来实现。Java语言提供了4种循环结构:while循环、do-while循环、for循环和增强的for循环。
一般情况下,一个循环结构包含4部分内容:
(1)初始化部分:设置循环开始时变量初值。
(2)循环条件:一般是一个布尔表达式,当表达式值为true时执行循环体,为false时退出循环。
(3)迭代部分:改变变量的状态。
(4)循环体部分:需要重复执行的代码。
3.2.1 while循环
while循环是Java最基本的循环结构,这种循环是在某个条件为true时,重复执行一个语句或语句块。它的一般格式如下:

其中,initialization为初始化部分;condition为一个布尔表达式,它是循环条件;中间的部分为循环体,用一对大括号定界;iteration为迭代部分。
该循环首先判断循环条件,当条件为true时,一直反复执行循环体。这种循环一般称为“当循环”。一般用在循环次数不确定的情况下。while循环的执行流程如图3-3所示。

图3-3 while循环结构
下面一段代码使用while结构求1~100之和。

下面程序随机产生一个100~200的整数,用户从键盘上输入所猜的数,程序显示是否猜中的消息,如果没有猜中要求用户继续猜,直到猜中为止。
程序3.6 GuessNumber.java

程序中使用了java.lang.Math类的random()方法,该方法返回一个0.0~1.0(不包括1.0)的double型随机数。程序中该方法乘以101再转换为整数,得到0~100的整数,再加上100,则magic为100~200的整数。
3.2.2 do-while循环
do-while循环的一般格式如下:


图3-4 do-while循环结构
do-while循环执行过程如图3-4所示。
该循环首先执行循环体,然后计算条件表达式。如果表达式的值为true,则返回到循环的开始继续执行循环体,直到condition的值为false循环结束。这种循环一般称为“直到型”循环。该循环结构与while循环结构的不同之处是,do-while循环至少执行一次循环体。
下面程序要求用户从键盘输入若干个double型数(输入0则结束),程序计算并输出这些数的总和与平均值。
程序3.7 DoWhileDemo.java

3.2.3 for循环
for循环是Java语言中使用最广泛的、也是功能最强的循环结构。它的一般格式如下:

其中,initialization为初始化部分,condition为循环条件,iteration为迭代部分,三部分用分号隔开。循环开始执行时首先执行初始化部分,该部分在整个循环中只执行一次。在这里可以定义循环变量并赋初值。
接下来判断循环条件,若为true则执行循环体部分,否则退出循环。当循环体执行结束后,程序控制返回到迭代部分,执行迭代,然后再次判断循环条件,若为true则反复执行循环体。
下面代码使用for循环计算1~100之和。

在初始化部分可以声明多个变量,中间用逗号分隔,它们的作用域在循环体内。在迭代部分也可以有多个表达式,中间也用逗号分隔。下面循环中声明了两个变量i和j。

for循环中的一部分或全部可为空,循环体也可为空,但分号不能省略。例如:

for循环和while循环及do-while循环有时可相互转换。例如,有下面的for循环:

可以转换为下面等价的while循环结构。

提示:在Java 5中增加了一种新的循环结构,称为增强的for循环,它主要用于对数组和集合元素迭代。关于增强的for循环在5.1.2节中讨论。
3.2.4 循环的嵌套
在一个循环的循环体中可以嵌套另一个完整的循环,称为循环的嵌套。内嵌的循环还可以嵌套循环,这就是多层循环。同样,在循环体中也可以嵌套另一个选择结构。
下面程序打印输出九九乘法表,这里使用了嵌套的for循环。
程序3.8 NineTable.java

程序输出结果为:

3.2.5 break语句和continue语句
在Java循环体中可以使用break语句和continue语句。
1.break语句
break语句是用来跳出while、do、for或switch结构的执行,该语句有两种格式:

break语句的功能是结束本次循环,控制转到其所在循环的后面执行。对各种循环均直接退出,不再计算循环控制表达式。下面程序演示了break语句的使用。
程序3.9 BreakDemo.java

程序输出结果为:

使用break语句只能跳出当前的循环体。如果程序使用了多重循环,又需要从内层循环跳出或从某个循环开始重新执行,此时可以使用带标签的break。
例如:

这里,标签start用来标识外层的for循环,因此语句“break start;”跳出了外层循环。上述代码的运行结果如下:

2.continue语句
continue语句与break语句类似,但它只终止执行当前的迭代,导致控制权从下一次迭代开始。该语句有下面两种格式:

以下代码会输出0~9之间的数字,但不会输出5。

当i=5时,if语句的表达式运算结果为true,使得continue语句得以执行。因此,后面的输出语句不能执行,控制权从下一次循环处继续,即i=6时。
continue语句也可以带标签,用来标识从那层循环继续执行。下面是使用带标签的continue语句的例子。

这段代码的运行结果如下:

注意:
(1)带标签的break可用于循环结构和带标签的语句块,而带标签的continue只能用于循环结构。
(2)标签命名遵循标识符的命名规则,相互包含的块不能用相同的标签名。
(3)带标签的break和continue语句不能跳转到不相关的标签块。
提示:在C/C++语言中,可以使用goto语句从内层循环跳到外层循环。在Java语言中,尽管将goto作为关键字,但不能使用,也没有意义。