
3.2 选择结构
选择结构提供了这样一种控制机制,它根据条件表达式值的不同,选择执行不同的语句序列,其他与条件值或表达式值不匹配的语句序列则被跳过不执行。选择结构分为条件结构(if语句)和多分支结构(switch语句)。
3.2.1 if语句
1.if结构
if语句是Java中的条件选择语句。一般语法格式如下:
if(条件) statement;
或者
if(条件) { block }
格式中的“条件”为关系表达式或逻辑表达式,其值为布尔值。
第一种情况下,在条件为真时,执行一条语句statement;否则跳过statement执行下面的语句。
第二种情况下,在条件为真时,执行多条语句组成的代码块block;否则跳过block执行下面的语句。
if结构的流程如图3-1所示。

图3-1 if结构的流程图
【例3-1】 输入数据x,测试其是否小于一个标识符常量。若小于标识符常量,则输出x的值。
//文件名:InputTest.java import java.io.*; //导入所需要的公用类 public class InputTest{ public static void main(String args[]) throws IOException { final int MAX_NUM=50; //定义标识符常量MAX_NUM=50 //下面7行语句的作用是从键盘输入一个整数并存放到变量x中 InputStreamReaderir; BufferedReader in; ir=new InputStreamReader(System.in); in=new BufferedReader(ir); System.out.println("Input x is:"); String s=in.readLine(); int x=Integer.parseInt(s); //下面用if结构判断x的值是否小于MAX_NUM if (x<MAX_NUM){ System.out.println("x="+x); } } }
2.if-else结构
Java语言中,较常见的条件结构是if-else结构。一般语法格式如下:
if (条件) statement1;或{bolck1} else statement2;或{block2}
在条件为真时,执行statement1或代码块block1,然后跳过else和statement2(或代码块block2)执行下面的语句;在条件为假时,跳过语句statement1(或代码块block1)执行else后面的statement2(或代码块block2),然后继续执行下面的语句。
if-else结构的流程如图3-2所示。

图3-2 if-else结构的流程示意图
知识提示 else子句不能单独作为语句使用,它必须和if子句配对使用。
3.if-else if结构
当需要处理多个分支时,可以使用if-else if结构。一般语法格式如下:
if (条件1) statement1;或 { block1 } else if (条件2) statement2; 或{ block2 } … else if (条件N) statementN; 或{ blockN } [else statementN+1;或{ blockN+1 }]
if-else if结构的流程如图3-3所示。

图3-3 if-else if结构的流程示意图
其中,else部分是可选的。else总是与离它最近的if配对。下面举一个例子加以说明。
【例3-2】 某公司为经销员制定了产品的销售任务,用task表示。下面的程序根据经销员实际完成销售值的不同分别输出不同的信息,并发给不同的红利。
//文件名:SalesTest.java import java.io.*; //导入所需要的公用类 public class SalesTest { public static void main(String args[]) throws IOException { int task=30; //销售任务 int bonus; //红利 //从键盘输入实际完成的销售值存放到变量yourSales中 InputStreamReader ir; BufferedReader in; ir=new InputStreamReader(System.in); in=new BufferedReader(ir); System.out.println("Input your Sales is: "); String s=in.readLine(); int yourSales=Integer.parseInt(s); //用if-else if结构判断yourSales的大小,决定红利多少并输出不同的信息 if (yourSales>=2*task) { //实际销售值达到或超出销售任务的2倍 bonus=1000; System.out.println("Excellent! bonus="+bonus); } else if (yourSales>=1.5*task) { //达到或超出1.5倍,但小于2倍 bonus=500; System.out.println("Fine! bonus="+bonus); } else if (yourSales>=task) { //达到或超出销售任务,但小于1.5倍 bonus=100; System.out.println("Satisfactory! bonus="+bonus); } else { //未完成销售任务 System.out.println("You're fired"); } } }
程序的运行结果如下:
Input your Sales is: 50 Fine! bonus=500
再次运行结果如下:
Input your Sales is: 20 You're fired
【例3-3】 用if-else if结构实现下面的符号函数:

//文件名:SignFunction.java import java.io.*; //导入所需要的公用类 public class SignFunction { public static void main(String args[]) throws IOException { InputStreamReader ir; BufferedReader in; ir=new InputStreamReader(System.in); in=new BufferedReader(ir); System.out.println("Input x is:"); String s=in.readLine(); int x=Integer.parseInt(s); int y; //下面用if-else if结构求y的值 if (x<0){ y=-1; } else if (x==0){ y=0; } else { y=1; } System.out.println("x="+x+"y="+y); // 输出x和y的值 } }
3.2.2 案例分析:闰年问题
1.案例描述
创建一个程序,通过输入的年份,判断是否为闰年。
2.案例分析
根据案例描述中的要求信息,分析如下:因为闰年的年份可被4整除而不能被100整除,或者能被400整除。因此,首先输入年份存放到变量year中,如果表达式(year%4==0 &&year%100! =0||year%400==0)的值为true,则为闰年;否则就不是闰年。
3.案例实现
本例的代码如下:
//文件名:LeapYear.java import java.io.*; //导入所需要的公用类 public class LeapYear { public static void main(String args[]) throws IOException { //下面7行语句的作用是从键盘输入年份存放到变量year中 InputStreamReader ir; BufferedReader in; ir=new InputStreamReader(System.in); in=new BufferedReader(ir); System.out.println("Input year is: "); String s=in.readLine(); int year=Integer.parseInt(s); //下面用if-else结构判断year中的年份是否为闰年 if (year % 4 ==0 && year % 100 ! =0 || year % 400 ==0){ System.out.println("year"+year+"is a leap year."); } else{ System.out.println("year"+year+"is not a leap year."); } } }
4.归纳与提高
本例中,应掌握if-else定义的形式和方法。需要注意的是,else语句一定要和if语句配对使用,不可单独使用,if或else语句体中的语句若多于一条,则外面需用花括号括起来。
3.2.3 switch语句
必须在多个备选方案中处理多项选择时,再用if-else结构就显得很烦琐,这时可以使用switch语句来实现同样的功能。switch语句基于一个表达式值来执行多个分支语句中的一个,它是一个不需要布尔求值的流程控制语句。switch语句的一般语法格式如下:
switch(表达式) { case值1:语句1; break; case值2:语句2; break; … case值N:语句N; break; [ default: 上面情况都不符合情况下执行的语句;] }
switch结构的流程如图3-4所示。

图3-4 switch结构的流程示意图
对switch结构有以下几点说明:
(1)表达式只能返回这几种类型的值:int、byte、short和char。多分支结构把表达式的值依次与每个case子句中的值相比较,如果遇到匹配的值,则执行该case子句后的语句序列。
(2)case子句中的值(value)必须是常量,而且所有case子句中的值应是不同的。
(3)default子句是可选择的。当表达式的值与任一一个case子句中的值都不匹配时,程序执行default后面的语句;如果表达式的值与任一一个case子句中的值都不匹配而且没有default子句,则程序不做任何操作,而是直接跳出switch语句结构。
(4)break语句用来在执行完一个case分支后,使程序跳出switch结构,即终止switch结构的执行。因为case子句只是起到一个标号的作用,用来查找匹配的入口并从此处开始执行。如果没有break语句,当程序执行完匹配的case语句序列后,后面的case子句起不到跳出switch结构的作用,程序还会继续执行后面的case语句序列。因此应该在每个case分支后,用break语句终止后面的case分支语句序列的执行。
在一些特殊情况下,多个相邻的case分支执行一组相同的操作。为了简化程序的编写,相同的程序段只需出现一次,即出现在最后一个case分支中。这时为了保证这组case分支都能执行正确的操作,只在这组case分支的最后一个分支后加break语句,组中其他case分支则不使用break语句。
(5)case分支中包含多条语句时,可以不用花括号{}括起。
(6)switch结构的功能可以用if-else if结构来实现,但在某些情况下,使用switch结构更简练,可读性强,而且程序的执行效率也得到提高。
与if-else if结构相比,switch结构在数据类型上受到了限制,即只能用int、byte、short和char型。若数据类型是double型,便不能用switch结构,这是Java的不足之处。
【例3-4】 使用switch语句结构输出四月份的季节。
//文件名:SwitchSample.java public class SwitchSample { public static void main(String args[]) { int month=4; String season; switch (month){ case 12: case 1: case 2: season="Winter"; break; case 3: case 4: case 5: season="Spring"; break; case 6: case 7: case 8: season="Summer"; break; case 9: case 10: case 11: season="Autumn"; break; default: season="Bogus Month"; } System.out.println("April is in the "+season+"."); } }
程序的运行结果如下:
April is in the Spring.
【例3-5】 设x=10, y=5,试用switch结构实现当输入字符+、-、*、/时,分别计算x、y的和、差、积、商。
//文件名:Calculator.java import java.io.*; //导入所需要的公用类 public class Calculator { public static void main(String args[]) throws IOException { int x=10, y=5, z; char ch; //变量ch用来存放从键盘输入的字符 //下面7行语句的作用是从键盘输入ch的值 InputStreamReader ir; BufferedReader in; ir=new InputStreamReader(System.in); in=new BufferedReader(ir); System.out.println("Input ch is:"); String s=in.readLine(); ch=s.charAt(0); //下面用switch结构实现计算器的功能 switch (ch) { case '+': z=x+y; System.out.println("x+y="+z); // '+’时输出x+y的值 break; case '-': z=x-y; System.out.println("x-y="+z); //'-’时输出x-y的值 break; case '*': z=x*y; System.out.println("x*y="+z); //'*’时输出x*y的值 break; case '/': z=x/y; System.out.println("x/y="+z); //'/’时输出x/y的值 break; default: System.out.println("Input Error! "); //输入其他字符时提示出错 } } }
程序的运行结果如下:
Input ch is: + x+y=15
再次运行结果为:
Input ch is: = Input Error!
3.2.4 案例分析:划分成绩等级
1.案例描述
将学生的考试成绩转换成不同的等级:90分以上为A,80分以上90分以下为B,70分以上80分以下为C,60分以上70分以下为D, E表示不及格。
2.案例分析
根据案例描述中的信息,本案例通过键盘输入学生成绩,由于学生成绩数据较为分散,若直接用switch结构判断成绩是哪个等级不具备可行性,因此可以利用除法操作来辅助。例如:90分以上的成绩为A,若用变量score来存储分数,则可令score=score/10,由于除法操作只保留商值,舍弃余数,所以90分以上的分数经过除法运算之后,其值是9;80~90之间的成绩,经除法后,其值为8;70~80之间的成绩,经除法后,其值为7,以此类推,完全可以用switch语句结构来实现。
3.案例实现
本例的代码如下:
//文件名:GradeDevide.java import java.io.*; public class GradeDevide { public static void main(String args[]) throws IOException{ int ch; //下面7行语句的作用是从键盘输入ch的值 InputStreamReader ir; BufferedReader in; ir=new InputStreamReader(System.in); in=new BufferedReader(ir); System.out.println("Input ch is:"); String s=in.readLine(); ch=Integer.parseInt(s); char grade; ch=ch/10; switch(ch) { case 9: grade='A'; break; case 8: grade='B'; break; case 7: grade='C'; break; case 6: grade='D'; break; default: grade='F'; } System.out.println("grade= "+grade); } }
4.归纳与提高
本例中,应掌握switch语句的定义形式和方法。在定义switch语句时,注意case语句后的变量值一定是唯一的,而且不重复。对于本例,也可以利用if-else-if语句实现,从而进一步熟悉switch语句及if语句的使用方法。