- Java语言程序设计
- 陆迟编著
- 1575字
- 2020-08-27 13:55:04
3.3 循环语句
循环语句的作用是使某一段程序根据需要重复执行多次。循环语句由循环体和循环条件两部分构成,循环体是要重复执行的语句,循环条件决定循环的开始、重复执行以及结束循环。循环语句实现的循环(或称重复)结构,是一种封闭结构,当循环条件被满足时,重复执行循环结构内的操作,当循环条件不被满足时,退出循环结构。
一个循环一般包括四个部分:
(1)初始化部分,用来设置循环的一些初始条件,如累加器清零等。
(2)循环体部分,重复执行的一段程序,可以是一条语句,也可以是一块语句。
(3)迭代部分,在当前循环结束,下一次循环开始前执行的语句。常用形式为一计数器值在增减。
(4)终止部分,一般为布尔表达式,每一次循环都要对该表达式求值,以检查是否满足循环终止条件。
Java语言提供三种形式的循环语句:while循环语句、do - while循环语句和for循环语句,下面分别予以介绍。
3.3.1 while语句
while语句的一般格式为:
while(布尔表达式) 语句
Java执行while循环语句时,先检查布尔表达式(循环条件)的值是否为true,若为true,则执行给定语句(即循环体),然后,再检查布尔表达式的值,反复执行上述操作,直到布尔表达式的值为false,退出循环结构。
while语句的执行是:先判断条件,根据条件再决定是否继续执行循环体(简称先判断后执行)。每执行一次循环体,循环条件均应发生相应的变化,使得执行若干次循环后,循环条件会从true变为false,以便能够结束循环。若执行循环时,循环条件总是为true,则不能终止循环,这种死循环在程序设计中是要注意避免的。
若首次执行while语句时,循环条件为false,则循环体一次也未执行,即while语句循环体最少执行次数为0次。
【例3.7】计算1 + 2 + 3 + … + 100。
一组有规律的数据的连续加或连续乘等计算一般都用循环程序来解决。
class Sum1To100{ public static void main(String args[]){ int i,sum = 0; i=1; // 设循环初值 while(i <= 100){ // 设循环条件为i<=100 sum += i ++; // 在循环体中执行i++,当i的值到101时,循环条件即为false } System.out.println("1到100的和为: "+sum); } }
程序运行结果如下:
1到100的和为:5050
3.3.2 do - while语句
while语句在执行循环体前先检查boolean表达式(循环条件),有些情况下,不管条件表达式的值是true还是false,都希望把循环体至少执行一次,那么就应使用do - while循环。do - while循环语句的一般格式为:
do 语句
while(布尔表达式);
do循环语句首先执行给定的语句(循环体),然后再计算布尔表达式(判断循环条件),若表达式值为false则结束循环,否则重复执行循环体。do语句的循环体至少被执行一次。这是do循环与while循环最大的区别。一般称while循环为“当型” 循环(先判断后执行),do循环为“直到型”循环(先执行后判断)。
【例3.8】将键盘输入的数累加并显示累加和,直到输入0为止。
import java.util.Scanner; class ParseDemo { public static void main(String args[]){ Scanner sc = new Scanner(System.in); int n,sum=0; System.out.println("请输入数据,输入0 结束。"); do { n = sc.nextInt(); sum += n; System.out.println("当前的和是: " + sum); } while(n != 0); System.out.println("结束!" ); } }
3.3.3 for语句
for循环语句在几种循环语句中的格式与用法最灵活,它有两种格式。它的一种常用格式为:
for([表达式1];[表达式2];[表达式3])语句
其中,表达式1 指出for循环的循环初值;表达式2 是一关系或逻辑表达式,值为false时循环结束;表达式3 指出每次循环时所进行的计算和更新。3 个表达式在使用中可根据需要,部分或全部省略。
执行for语句时,先计算表达式1(只计算一次,省略时表示无初始内容),接着检查表达式2的值是true还是false,若为false,则不执行语句(循环体),退出循环;若为true,就执行循环体语句,再计算表达式3,然后,又检查表达式2 的值,再根据值为true或为false决定是否执行循环体。
简言之,for循环的各部分执行的顺序为:表达式1,表达式2,语句,表达式3;根据表达式2的值决定后三部分是否循环执行。
可以在for循环的表达式1中说明仅在循环中使用的变量,例如:
for(int i = 10;i >= 0;)i--;
注意:这里定义的i在循环中可用,但出了循环就无效了。
【例3.9】用for循环语句按10度的增量打印出一个从摄氏10~90 度到华氏温度的转换表。
class TempConversion{ public static void main (String args[]){ int fahr,cels; System.out.println("摄氏温度 华氏温度");
for(cels = 10;cels <= 90;cels += 10){ fahr = cels * 9 / 5 + 32; System.out.println(" " + cels + " " + fahr); } } }
程序的运行结果如下:
摄氏温度 华氏温度 10 50 20 68 30 86 40 104 50 122 60 140 70 158 80 176 90 194
在理解了for语句的功能后,可灵活地使用该语句的各种形式来编写循环程序。例如,对温度变换的例3.9,for语句可改写为下面几种形式(只写出有关部分)。
(1)省略表达式1
若for语句的初值部分在for循环外已全部设置,则for语句的相关部分可省略。
int fahr,cels = 10; System.out.println("摄氏温度 华氏温度"); for(;cels <= 90;cels += 10){ fahr = cels * 9 / 5 + 32; System.out.println(" " + cels + " " + fahr); }
(2)在表达式1中包含变量定义等更多的内容
在for语句的初值部分可包含变量定义(仅在for循环中使用)、赋值等内容,各项之间用逗号分隔。
for(int fahr,cels = 10;cels <= 90;cels += 10){ fahr = cels * 9 / 5 + 32; System.out.println(" " + cels + " " + fahr); }
(3)省略表达式3
若将表达式3写到循环体中,则可省略表达式3部分。
for(int fahr,cels = 10;cels <= 90;){ fahr = cels * 9 / 5 + 32; System.out.println(" " + cels + " " + fahr); cels += 10; }
(4)在表达式3中包含更多内容
用逗号表达式将循环体的部分或全部写到表达式3部分,Java也能正确执行。
for(int fahr,cels = 10;cels <= 90;
fahr = cels * 9 / 5 + 32, // 下面3行都属于表达式3 System.out.println(" " + cels + " " + fahr), cels += 10) // 循环体为空 }
(5)同时省略表达式1和表达式3
int fahr,cels = 10; for(;cels <= 90;){ fahr = cels * 9 / 5 + 32; System.out.println(" " + cels + " " + fahr); cels += 10; }
(6)同时省略所有表达式
当所有表达式都省略时,为for的无限循环形式,这时,可在循环体中添加其他控制语句来终止循环。
int fahr,cels = 10; for(;;){ if(cels > 90)break; fahr = cels * 9 / 5 + 32; System.out.println(" " + cels + " " + fahr); cels += 10; }
当然,上述for的几种形式还有其他的写法。在充分理解for语句功能的基础上,写出for语句的更多种形式也是不难的。善于使用for循环语句,可使程序简洁清晰。
另一种称为for-each格式的for语句通常用在数组、集合等的应用中,相关内容在数组章节中再做介绍。
3.3.4 循环嵌套
循环嵌套是指在某个循环语句的循环体中又包含另一个循环语句,也称多重循环。外面的循环语句称为“外层循环”,外层循环的循环体中的循环称为“内存循环”。
设计循环嵌套结构时,要注意内存循环语句必须完整地包含在外层循环的循环体中,不得出现内外层循环体交叉的情况。Java语言中的三种循环语句都可以组成多重循环。
【例3.10】求3~100之间的所有素数(素数是只能被自身或1整除的自然数)。
public class PrimeNumber{ public static void main(String args[]){ System.out.println(" ** 3~100之间的所有素数 **"); int n = 0; for(int i = 3;i < 100;i += 2){ // 外层循环 int k = (int)Math.sqrt(i); boolean isPrime = true; for(int j = 2;j <= k;j ++ ){ // 内层循环 if( i%j == 0 )isPrime = false; } if(isPrime){ System.out.printf("%4d ", i);
n ++; // 控制每行打印10个素数 if( n % 10 == 0 )System.out.println(); } } System.out.println(); } }
程序运行结果如下:
** 3~100之间的所有素数 ** 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
该程序结构是一个二重循环:内层循环对数据i判断是否为素数,若不是素数,则赋isPrime值为false;外层循环使得数据i从3至100变化。两层循环配合就可求出3至100之间的所有素数。
【例3.11】输出5行星号字符组成的菱形图案。
字符图案的程序设计有一定的规律,在本例中可将每行的输出内容分为空格、星号和回车换行三个部分来考虑。如果希望将图案输出在屏幕的左边,则各行星号前的空格数按行序分别为2、1、0、1、2;各行的星号个数按行序分别为1、3、5、3、1。可构造合适的循环变量,使得程序设计比较简单。
class PrintStar{ public static void main(String args[]){ for(int i=-2;i<=2;i++){ // 图案有5行,外循环5次 for(int j=1;j<=Math.abs(i);j++) // 1: 内循环1,输出空格 System.out.print(" "); for(int j=1;j<=(3-Math.abs(i))*2-1;j++) // 2: 内循环2,输出星号 System.out.print("*"); System.out.println(); // 3: 输出回车换行 } } }