1.8 分支结构
分支结构提供了这样一种控制机制:它根据条件值的不同选择执行不同的语句序列,其他与条件值不匹配的语句序列则被跳过不执行。这对应现实生活中“如果明天是雨天,我们做XX;如果明天是晴天,我们做YY”这样的句式。
1.8.1 if…else分支结构
Java语言中,最简单的分支结构是if结构,采用格式如下:
说明:如果条件表达式的值为true,就执行语句1,接下来顺序执行后续语句序列;否则,不执行语句1,直接执行后续语句序列。
例如:
if(x>y) x=y;
如果x大于y,就把y的值赋给x。
当条件为true,且要执行的语句不只一条语句时,将这些语句用花括号({ })括起来,形成一条复合语句。
例如,如果x的值大于y,将x和y的值交换,可以用以下语句实现。
if语句的执行流程如图1-24所示。
图1-24 if语句的执行流程
注意:if语句后合法的条件值是布尔类型。if语句后的条件,不管是简单还是复杂,都应使用小括号包含起来。
【思考】在已有语句“int i=0;”的前提下,下面哪一个是正确的if语句?
A.if(i!=2){} B.if(!i){} C.if(i){} D.if(i=2){}
学过C++的读者看了之后会觉得前三项都是正确的。而在Java中,if后的部分,必须是一个布尔值。因此,只有A选项“if(i!=2){}”是正确的if语句。
简单的if语句只能处理一部分问题,如果条件表达式的值为假也能进行相应操作,此时就要用到if…else语句。
if…else语句的格式如下:
说明:当条件表达式的值为true时,执行语句序列1,然后跳过语句序列2执行后续语句序列;当条件表达式的值为false时,跳过语句序列1,执行语句序列2,然后执行后续语句序列。
注意:else子句不能单独作为语句使用,它必须和if子句配对使用。
下面举一个简单的例子:
1.8.2 if…else嵌套
有时候,简单的if…else分支情况还不足以用来描述现实生活中的问题。以闰年为例,闰年的年份可被4整除且不能被100整除,或者能被400整除。这样的问题,就需要用if…else的嵌套。语法与前面类似,只是需要注意:在嵌套使用if…else语句时,if和else一定要配对使用,else总是与它上面最近的if配对。记住,一个else语句总是和它同在一个块的最近的if语句相匹配,并且该if语句没有和其他的else关联。
分析下面的代码片段,执行后输出的i值是多少?
虽然代码看起来很复杂,但实际上第一个if选择就不满足,因此将直接执行输出语句,输出的i值为2。
可以嵌套使用if和else if语句,例如:
1.8.3 switch语句
if和if…else语句只有两个分支可供选择执行,而实际问题中却经常遇到多分支选择执行的情况,虽然可以使用嵌套的if和if…else语句来处理。但是多重嵌套的if语句会造成代码冗长而降低程序的可读性。在Java语言中,使用switch语句实现多分支条件选择。它根据一个变量或表达式的值来执行不同的操作语句。
switch语句的格式如下:
说明:switch语句的执行过程如下。根据表达式的值来判断,表达式的值和value的值相同就进入相应的case语句,执行相应的语句序列,遇到break,就跳出switch语句,执行后续语句序列;如果表达式的值与任何value都不相同,此时如果有default语句,就进入执行其中的语句序列,没有default语句,就直接跳出switch语句,执行后续语句序列。
使用switch语句需要注意以下几点:
(1)表达式的值只能是int、byte、short或char类型中的一种。
(2)case子句中的值value必须是上述4种类型的常量,而且所有case子句中的值应该不相同。
(3)break语句用来执行完一个case分支后,使程序跳出switch结构。因为case子句只起到一个标号作用,用来查找匹配的程序入口并从此处开始执行。如果没有break语句,当程序执行完匹配的case语句序列后,还会继续执行后面的case语句中的语句序列。
(4)在一些特殊的情况下,多个相邻的case分支执行一组相同的操作。为了简化程序的编写,相同的程序段只需出现一次,即出现在最后一个case分支中。为了保证这组case分支都能执行正确的操作,只在这组case分支的最后一个case分支后加break语句。例如:
在选择分支结构时注意,用于比较的是double类型时,不能选择switch语句。也就是if语句能实现的功能,switch未必能实现。二者有各自的应用场景。switch后表达式的类型必须为char、byte、short、int,不能是整型中的long,更不能是float或double类型。
1.8.4 编程实例
【程序1-4】编写程序,对三个整型变量进行排序,按照从小到大的顺序排列,要求使用简单的if分支结构。
【分析】程序中定义了一个临时变量t。当要交换两个相同类型的变量中所存放的值时,一般都需要再定义一个变量。就好像两个杯子中装了两种不同的液体,要把两个杯子中装的液体交换,需要借助第三个空杯子来完成。
对数值进行排序如图1-25所示。
图1-25 对数值进行排序
【程序1-5】用if语句的嵌套,根据学生的成绩判断等级。
图1-26 判断学生成绩的等级
【分析】学生成绩分为不及格、及格、中、良、优5个等级。在使用if语句时,需要用到if的嵌套。一般情况下,if语句的嵌套不要超过三个层次。
判断学生成绩的等级如图1-26所示。
【程序1-6】在程序中编写一个名为showDays的方法,要求使用switch结构,根据传递的表示月份的参数,显示该月有多少天。程序中假定2月份固定为28天,不考虑闰年问题。
【分析】因为不考虑闰年问题,假定2月份的天数固定为28天。剩下的11个月中,1月、3月、5月、7月、8月、10月、12月是31天,而4月、6月、9月、11月是30天。为了让程序简单,switch语句中把2月份和其他为30天的月份列出来了。剩下的情况,执行default分支部分。
switch演示如图1-27所示。
图1-27 switch演示