- Java程序设计与应用开发(第3版)
- 吴敏 於东军 李千目主编 成维莉 邵杰 姜小花副主编
- 1658字
- 2025-03-22 04:39:44
2.4 控制流
控制流用于控制程序的执行顺序,包括条件语句、循环语句和选择语句等。
2.4.1 if条件语句
if条件语句的使用方式为:
if(条件表达式) 语句;
其含义是,如果条件表达式的值为true,则执行语句;否则,该语句不被执行。
例如:
if(salary>10000) level="high";
当满足条件表达式,需要执行多条语句时,需要使用一对花括号将多条语句包含起来,例如:
if(salary>10000){ level="high"; taxrate=0.006; }
上面的代码片段中如果不使用花括号,那么不论salary>10000是否成立,语句taxrate=0.006均会执行。而加上花括号后,只有在salary>10000成立时,才执行语句taxrate=0.006。
如果希望在if的条件表达式不满足时,执行特定的语句,则可以将else和if配对使用:
if(salary>10000){ level="high"; taxrate=0.006; }else{ level="low"; taxrate=0.004; }
如果需要进行多次条件判断,可使用else if,例如:
if(salary>10000){ level="high"; taxrate=0.006; }else if(salary>6000){ level="medium"; taxrate=0.005; }else{ level="low"; taxrate=0.004; }
if语句还可以嵌套使用。例如下面这段代码完成同样的功能,却是使用了嵌套的if语句:
if(salary>10000){ level="high"; taxrate=0.006; }else{ if(salary>6000){ level="medium"; taxrate=0.005; }else{ level="low"; taxrate=0.004; } }
2.4.2 for循环语句
for语句是一种常用的循环语句,其一般形式为:
for(循环变量初始化;结束条件判断;修改循环变量值){ 语句; ...; 语句; }
for语句的圆括号之间包含了3个部分,分别是循环变量初始化、结束条件判断和修改循环变量值,并且这3个部分用两个分号隔开。一对花括号所包括的内容称为循环体。
for语句的执行过程可以用图2.12来表示:执行for循环语句时,首先进入循环变量初始化①;然后立即进入循环结束条件判断②,结束条件判断的值为false时,结束循环,否则,执行循环体中的语句③;循环体中的语句执行完毕后,修改循环变量值④;再进行结束条件判断⑤,以确定是否需要再次执行循环体中的语句。

图2.12 for循环语句
注意:循环变量初始化只在首次进入时执行一次。
注意:每次执行循环体之前,都必须进行结束条件判断。
例2.2的作用是对1~100所有的整数求和。
例2.2 Sum.java
public class Sum{ public static void main(String []args){ int sum=0; for(int i=1;i<=100;i++) sum=sum+i; System.out.println(sum); //i 不再有效 } }
需要注意的是,在循环变量初始化中定义的变量(如例2.2中的i),只在循环体内有效,在循环体外是不能对其进行访问的。
for语句圆括号中的3个组成部分都是可选的,下面的for语句是一个无限循环:
for ( ; ; ) { ... }
2.4.3 while/do while循环语句
while循环语句的使用方式为:
while(条件表达式){ 语句; ... 语句; }
同样,花括号之间的语句称为while循环体,如果没有花括号,那么最靠近while的一条语句作为循环体。每次执行循环体之前都需要进行条件表达式的计算,如果其值为true,那么执行循环体;否则,退出循环。
while循环常用在事前不能知道循环次数的场合。
例如:已知sum(k)=1+2+3+,…,+k,问k最小为什么值时能够使得sum(k)>2000。
例2.3求解了该问题。
例2.3 FindMinimalK.java
public class FindMinimalK{ public static void main(String []args){ int sum=1; int k=1; while(sum<=2000){ k++; sum=sum+k; } System.out.println("the minimal k="+k); } }
do while语句也常用在未知循环次数的场合,与while语句不同之处在于:while语句是先判断后执行,而do while是先执行后判断,也即do while的循环体至少执行一次。do while循环语句的使用方式为:
do{ 语句; ... 语句; } while(条件表达式); //注意,这里要以分号结束
下面的代码片段使用do while循环语句来求解k的最小值:
int sum=1; int k=1; do{ k++; sum=sum+k; }while(sum<=2000); System.out.println("the minimal k="+k);
2.4.4 switch分支选择语句
在程序设计过程中,常常需要依据不同的条件选择执行不同的语句。当然,我们可以使用if-else语句,但是Java中也提供了switch语句可以完成同样的功能。例2.4的作用是将一个数值类型表示的月份转化为一个字符串描述的月份。
例2.4 MonthTranslator.java
public class MonthTranslator{ public static void main(String []args){ String stringMonth=""; for(int digitalMonth=1;digitalMonth<=13;digitalMonth++){ switch (digitalMonth){ case 1: stringMonth="January"; break; case 2: stringMonth="February"; break; case 3: stringMonth="March"; break; case 4: stringMonth="April"; break; case 5: stringMonth="May"; break; case 6: stringMonth="June"; break; case 7: stringMonth="July"; break; case 8: stringMonth="August"; break; case 9: stringMonth="September"; break; case 10: stringMonth="October"; break; case 11: stringMonth="November"; break; case 12: stringMonth="December"; break; default: stringMonth="Error month"; } System.out.println(digitalMonth+" ---> "+stringMonth); } } }
运行后输出:
1 ---> January 2 ---> February 3 ---> March 4 ---> April 5 ---> May 6 ---> June 7 ---> July 8 ---> August 9 ---> September 10 ---> October 11 ---> November 12 ---> December 13 ---> Error month
switch语句从与选择值相匹配的case标签处开始执行,一直执行到break处(执行break将跳出switch语句)或是switch的末尾。注意,switch只能接收整数类型的值。此外,当传递进来的值与所有的case标签均不匹配时,如果switch中含有default标签,将执行default标签后面的语句;如果default标签也不存在,那么switch中没有任何语句得到执行。
还有一点需要注意的就是:如果一个case子句后面不加break,那么当该子句执行完毕后,下一个case子句将被继续执行,直至遇到break或是switch语句结束。有的时候,这一性质可以被有效利用,例2.5用于求得某一月份所在的季度。
例2.5 QuarterTranslator.java
public class QuarterTranslator{ public static void main(String []args){ String stringQuarter=""; for(int digitalMonth=1;digitalMonth<=13;digitalMonth++){ switch (digitalMonth){ case 1: case 2: case 3: stringQuarter="一季度"; break; case 4: case 5: case 6: stringQuarter="二季度"; break; case 7: case 8: case 9: stringQuarter="三季度"; break; case 10: case 11: case 12: stringQuarter="四季度"; break; default: stringQuarter="Error month"; } System.out.println(digitalMonth+" ---> "+stringQuarter); } } }
程序运行后输出:
1 ---> 一季度 2 ---> 一季度 3 ---> 一季度 4 ---> 二季度 5 ---> 二季度 6 ---> 二季度 7 ---> 三季度 8 ---> 三季度 9 ---> 三季度 10 ---> 四季度 11 ---> 四季度 12 ---> 四季度 13 ---> Error month
Java 7增强了switch语句的功能,允许switch语句控制表达式是java.lang.String类型的变量或表达式——只能是java.lang.String类型,不能是StringBuffer或StringBuilder这两种字符串类型。
2.4.5 break、continue
在switch语句中,我们已经使用过break,其作用是跳出switch语句,将控制流转到紧跟在switch之后的语句。实际上,break更多的是用作跳出一个循环体,同样以求解2.4.3小节中k的最小值为例:
int sum=1; int k=1; while(true){ if(sum>2000) break; k++; sum=sum+k; } System.out.println("the minimal k="+k);
在该代码中,while是一个无限循环,当条件sum>2000满足时,break跳出循环,然后执行紧跟其后的打印语句。
需要注意的是,break只是跳出其所在的最内层循环体。例如,在下面的程序片段中,如果break执行,只是跳出while循环体,并不能跳出外层的for循环:
for(...){ while(...){ if(...) break; ... } }
如果需要直接跳出多层循环,可以使用带标签的break语句,例如:
abc: for(...){ while(...){ if(...) break abc; ... } }
其中abc是为for语句定义的标签。上面的代码中,当if的条件满足时,将直接跳出for循环体。
标签定义在一个有效的Java语句之前,格式如下:
标签名: 语句;
注意:使用带标签的break语句时,标签必须定义在break之前。
与break语句不同,continue语句不跳出所在的循环体,而只是中断执行当前循环体的剩余部分,并进入下一轮循环。
例如,求解0~100所有偶数的和,sum=0+2+4+…+98+100。
例2.6求解了该问题。
例2.6 SumEven.java
public class SumEven{ public static void main(String []args){ int sum=0; for(int i=0;i<=100;i++){ if(i%2!=0) continue; sum=sum+i; } System.out.println("sum="+sum); } }
当i为奇数时,continue语句被执行。这时候,for循环体的剩余部分(sum=sum+i;)将不被执行,也就是不对奇数进行累加,而是转而执行for的循环变量值修改(i++),然后依据循环条件(i<=100),判断是否进入下一轮循环。