4.3 循环语句
循环语句在程序设计中有什么作用呢?
【实例4.7】下面先看一段简单的程序段,再来看看使用循环语句编写程序的好处在哪里。
01 ///将x连续加1加10次 02 public class control4 03 { 04 public static void main(String[] args) 05 { 06 int x=1; 07 x=x+1; 08 x=x+1; 09 x=x+1; 10 x=x+1; 11 x=x+1; 12 x=x+1; 13 x=x+1; 14 x=x+1; 15 x=x+1; 16 x=x+1; 17 System.out.println(x); 18 } 19 }
【代码说明】代码的含义是让变量“x”连续加1共加10次。如果想要加1加100次,那要让“x=x+1”这个表达式重复100次。
【运行效果】
11
这样庞大的程序段所要完成的功能,不过是一个很简单的相加功能。为了解决这类问题,程序设计中引入了循环语句。循环语句总共有3种常见的形式:for语句、while语句、do/while语句。下面将逐个进行详细的介绍。
4.3.1 for语句
for语句的基本结构如下所示。
01 for(初始化表达式;判断表达式;递增(递减)表达式) 02 { 03 执行语句 04 }
【实例4.8】针对for语句,来修改上面的程序段。
01 public class control5 02 { 03 public static void main(String[] args) 04 { 05 int x; 06 int n=10; 07 for( x=1;n>0;n--,x++) 08 {System.out.println(x);} 09 } 10 }
【代码说明】在这个程序段里,用第5~8行共4句代码完成了前面程序段里12句代码所解决的事情。
【运行效果】
1 2 3 4 5 6 7 8 9 10
【实例4.9】如果前面的程序段中,需要连续加1加100次。则参考下面的程序段。
01 public class control6 02 { 03 public static void main(String[] args) 04 { 05 int x; 06 int n=100; 07 for(x=1;n>0;n--,x++){} 08 System.out.println(x); 09 } 10 }
【代码说明】在这个程序段里,使用第5~8行共4句代码可以解决前面程序段中12句代码所解决的问题,这就是循环语句的优势。
【运行效果】
101
下面详细地解释for循环语句中各个子项的意义。
❑初始化表达式:初始化表达式的意义,在于定义循环之前变量的值是多少,如果没有这一项,就不知道该从哪个值开始循环。
❑判断表达式:判断表达式的作用在于规定循环的终点。如果没有判断表达式,那么此循环就成了死循环。
❑递增(递减)表达式:这一项规定每执行一次程序,变量以多少增量或减量进行变化。
注意
一定要注意递增(递减)表达式中可以有多个表达式,它们以逗号间隔,而不是分号。
其实也可以利用在条件判断语句中提到的流程图来编写程序,在流程图中可以看出程序运行的顺序,如图4.4所示。
【实例4.10】下面再看一个九九乘法表的程序段。先来绘制流程图,如图4.5所示。
图4.4 循环语句流程图
图4.5 九九乘法表流程图
根据流程图,使用循环语句编写一个乘法口诀表。
01 ///这是一个多重for循环语句 02 public class control7 03 { 04 public static void main(String[] args) 05 { 06 for(int x=2;x<10;x++) 07 { 08 for(int y=1;y<10;y++) 09 { 10 System.out.print(x+"*"+y+"="+(x*y)); 11 System.out.print(""); 12 } 13 System.out.println(""); 14 } 15 } 16 }
【代码说明】第6~14行是外围的for循环,第8~12行是一个嵌入在外围循环中的循环,这样的我们称之为嵌套循环。为什么要使用两重循环呢?因为它涉及两个变化的量。在一个程序里,有多少个不同变量,就要使用多少个for循环,当然也不是非常绝对的。
【运行效果】
2*1=22*2=42*3=62*4=82*5=102*6=122*7=142*8=162*9=18 3*1=33*2=63*3=93*4=123*5=153*6=183*7=213*8=243*9=27 4*1=4 4*2=8 4*3=12 4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36 5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 5*6=30 5*7=35 5*8=40 5*9=45 6*1=2 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 6*7=42 6*8=48 6*9=54 7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 7*8=56 7*9=63 8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 8*9=72 9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
在上面的程序段中,使用了嵌套for语句。其实真正复杂的程序段中,可能会出现4个嵌套的for语句,这要在实践中慢慢体会。
4.3.2 while循环
在英文中“while”这个词的意思是“当”,而在Java程序设计中,也可以将其理解为“当”。其语法结构是:
01 while (条件) 02 { 03 目的一; 04 目的二; 05 ... 06 }
当满足某种条件,就执行“目的一”、“目的二”等,while语句的循环体在{}中。
【实例4.11】下面看一段程序段,通过分析它,让读者更加清楚循环语句。
01 ///通过判断y是否大于0 02 ///如果y大于0则将计费次数减1,x加1 03 public class control8 04 { 05 public static void main(String[] args) 06 { 07 int x=0; 08 int y=100; 09 int sum=0; 10 while(y>0) 11 { 12 x=x+1; 13 y--; 14 sum+=x; 15 } 16 System.out.println(sum); 17 } 18 }
【代码说明】这个程序段是将数字从1一直加到100,条件是只要“y”大于0,就会执行大括号里的语句。“y”初始值是100,满足条件,所以执行大括号的表达式。先将“x+1”赋给“x”,因为x的初始值是0,所以x从1开始计数,然后,将“y”自减1,此时“y”变成了99,将“sum”加上“x”赋给“sum”。此时,执行语句结束了,又会回到小括号的条件,最后再比较“y=99”是否大于0,如果大于0,再继续执行大括号里的语句。
一旦“y”自减到小于0,则将结束执行大括号里的语句,开始执行大括号外的语句。在上面的程序段中,y就相当于一个计数器。
【运行效果】
5050
同样,在编写while语句时,要先绘制流程图,根据流程图再来编写程序段,整个思路就会很清晰了。下面先看while的流程图,如图4.6所示。
其实while语句很简单,根据这个流程图,就可以思路很清晰地编写程序段。下面针对上面的程序段来绘制流程图,如图4.7所示。
图4.6 循环语句流程图
图4.7 一个循环语句实例的流程图
看了这个流程图,会发现按照流程图来编写程序简单多了。为了巩固以上所说,再看一个例子。
【实例4.12】试编写程序实现输出1~100间的整数,并且此整数必须满足:它是3的倍数,但不是5的倍数,也不是9的倍数。针对这个例子,先来绘制一个流程图,如图4.8所示。
根据流程图,现在来编写程序段。
01 ///通过判断是否在100以内,并且是3的倍数 02 ///然后再判断这些数是否不是5的倍数 03 ///最后判断这些数是否不是9的倍数 04 public class control9 05 { 06 public static void main(String[] args) 07 { 08 int x=1; 09 while(((3*x>1)&&(3*x<100))) 10 { 11 if((3*x)%5!=0) 12 { 13 if((3*x)%9!=0) 14 { 15 System.out.println(3*x); 16 } 17 } 18 x++; 19 } 20 } 21 }
图4.8 输出特殊数字的循环流程图
【代码说明】第9行是一个循环判断条件,判断是否在100以内,并且是3的倍数。第11行是一个条件语句,判断这些数是否不是5的倍数,第13行也是一个条件语句,判断这些数是否不是9的倍数。
【运行效果】
3 6 12 21 24 33 39 42 48 51 57 66 69 78 84 87 93 96
按照先绘制流程图,后编写程序的步骤,会显得思路更清晰。其实从上面的程序段中,可以总结一点:当由多个条件形成循环条件时,可以选择其中一个作为循环条件,而剩下的条件可以在循环体中作条件语句。
4.3.3 do...while语句
在学习do...while语句之前,先清楚while语句是如何工作的。while语句是先进行条件判断,再执行大括号内的循环体。do...while语句与while语句不同的是,它先执行大括号内的循环体,再判断条件,如果条件不满足,下次不再执行循环体。也就是说,在判断条件之前,就已经执行大括号内的循环体。
【实例4.13】下面先看一个程序段。
01 ///通过先判断这个数是否是3的倍数,并且是否是5的倍数 02 ///再判断是否是9的倍数 03 ///最后判断是否在 100以内 04 public class control10 05 { 06 public static void main(String[] args) 07 { 08 int x=1; 09 do 10 { 11 if((3*x)%5!=0) 12 { 13 if((3*x)%9!=0) 14 {System.out.println(3*x);} 15 } 16 x++; 17 } 18 while(((3*x>1)&&(3*x<100))); 19 } 20 }
【运行效果】
3 6 12 21 24 33 39 42 48 51 57 66 69 78 84 87 93 96
【代码说明】从上面的程序段输出结果可以看出,与使用while语句的输出结果是一样的,为什么会是一样的呢?下面来分析:
当“x=33”时,先不会检验“3*33=99”是否小于100,而会先执行大括号内的循环体。当检测到99是9的倍数时,条件是“false”,于是就会退出条件语句,继续执行“x”自加1表达式,于是“x”变成了34,由于“34*3=102”大于100,所以结束循环体。因此程序执行到“x=32”后就无输出了,最后输出的结果当然和while语句的输出一样。
其实在实际程序开发中,不经常使用do...while循环语句。因为这种语句是先执行循环体再检测条件,所以会有一些危险数据不经检测,就会被执行。建议使用while语句或者for循环语句来编写代码。