第4章-Java程序流程控制.ppt
第第4章章 Java程序流程控制程序流程控制 本章学习目标本章学习目标 l理解复合语句概念。l掌握if、if-else语句以及switch语句等分支结构。l掌握while、do-while以及for语句等循环结构。l掌握break和continue等跳转语句。l基本掌握分支及循环结构的相互嵌套编程。l学会分析较复杂程序的执行流程。4.1 复合语句复合语句l在Java语言中,有简单语句和复合语句之分。l一条简单语句总是以分号结束,它代表一个要执行的操作,可以是赋值、判断或者跳转等语句,甚至还可以是只有分号的空语句(;),空语句表示不需要执行任何的操作。l而复合语句则是指用大括号括起来的语句块(block),它一般由多条语句构成,但也允许只有一条简单语句。复合语句复合语句l格式如下:简单语句1;简单语句2;简单语句n;l比如以下例子均为复合语句:a=1;b=2;或 S=0;l复合语句在后面的流程控制结构中经常要用到,比如需要多个语句作为一个“整体语句”出现时就必须用大括号将其括起来作为一条复合语句。lJava程序的语句流程可以分为以下三种基本结构:顺序结构、分支(选择)结构以及循环结构。l对于分支结构和循环结构,当条件语句或者循环体语句多于一条时,必须采用复合语句的形式,即用大括号将其括起来,否则系统将默认条件语句或循环体语句仅有一条,即最近的那一条。l反过来说,当条件语句或者循环体语句只有一条时,则可用可不用大括号,这点请初学者学习后面内容时注意留心。4.2 顺序结构顺序结构l由赋值语句以及输入输出语句构成的程序,只能按其书写顺序自上而下,从左到右依次执行,将此类程序结构称为顺序结构。l它是最简单的程序结构,也是计算机执行的最一般流程。【例4-1】交换两变量的值。public class Testpublic static void main(String args)int a=5,b=8,c;System.out.println(a,b的初始值);System.out.println(a=+a);System.out.println(b=+b);c=a;a=b;b=c;System.out.println(a,b的新值);System.out.println(a=+a);System.out.println(b=+b);【例4-2】已知三角形的三条边长,求它的面积。提示:面积=其中,public class Test public static void main(String args)double a=3,b=4,c=5,s;/三角形的三条边 double area;/三角形的面积 s=(a+b+c)/2;area=Math.sqrt(s*(s-a)*(s-b)*(s-c);System.out.println(该三角形的面积为:+area);4.3 分支结构分支结构 l分支结构也叫选择结构,分支结构表示程序中存在分支语句,这些语句根据条件的不同,将被有选择地加以执行(取决于条件表达式的取值情况)。l分支结构:单分支、双分支和多分支结构。lJava语言的单分支是if语句,双分支是if-else语句,多分支是switch语句,实现时,也可以用switch语句构成双分支结构,或者用if-else语句嵌套构成多分支结构。4.3.1 单分支条件语句单分支条件语句 l单分支条件语句的一般格式是:if(布尔表达式)语句;int i=0,j=0;if(i!=j)i+;j+;int i=0,j=0;if(i!=j)i+;j+;int i=0,j=0;if(i!=j)i+;j+;【例例4-4】乘坐飞机时,每位顾客可以免费托运乘坐飞机时,每位顾客可以免费托运20kg以内的行李,超过部分假定按每公斤收费以内的行李,超过部分假定按每公斤收费1.2元的话,试编写相应计算收费的程序。元的话,试编写相应计算收费的程序。l(1)数据变量:w-行李重量(以公斤为单位)fee-收费(单位元)根据数据的特点,变量的数据类型必须为浮点型,不妨定为float类型。l(2)算法:0 w 20 (3)由System.out.println();语句提示用户输入数据(行李重量),然后通过利用前述的交互式输入方法给w变量赋值。l(4)由单分支结构,构成程序段即对用户敲入的数据进行判断,并按收费标准计算收费额。程序段局部如下:.fee=0;if(w20)fee=1.2*(w-20);.import java.io.*;public class Test public static void main(String args)throws IOException float w,fee;/以下代码为通过控制台交互输入行李重量 InputStreamReader reader=new InputStreamReader(System.in);BufferedReader input=new BufferedReader(reader);System.out.println(请输入旅客的行李重量:);String temp=input.readLine();w=Float.parseFloat(temp);/字符串转换为单精度浮点型 fee=0;if(w 20)fee=(float)1.2*(w-20);System.out.println(该旅客需交纳的托运费用:+fee+元);【例4-5】根据年龄,判断某人是否为成年。public class Test public static void main(String args)byte age=20;if(age=18)System.out.println(成年);if(age=0&rabbit=0)System.out.println(鸡有+chick+只);System.out.println(兔有+rabbit+只);4.3.2 双分支条件语句lJava语言的双分支结构由if-else语句实现,一般格式如下:if(布尔表达式)语句1;else 语句2;int i=0,j=0;if(i=j)i+;j+;else i-;j-;int i=0,j=0;if(i=j)i+;j+;else i-;j-;int i=0,j=0;if(i=j)i+;j+;else i-;j-;【例4-7】鸡兔问题的改进。public class Test public static void main(String args)double chick,rabbit;short heads=10,feet=33;chick=(heads*4-feet)/2.0;rabbit=heads-chick;if(chick=(short)chick&chick=0&rabbit=0)System.out.println(鸡有+chick+只);System.out.println(兔有+rabbit+只);else System.out.println(数据输入可能有误!);【例4-8】根据年龄,判断某人是否为成年,用双分支实现。public class Test public static void main(String args)byte age=20;if(age=18)System.out.println(成年);else System.out.println(未成年);【例4-9】判断2020的奇偶性,并进行输出?public class Test public static void main(String args)short n=2020;if(n%2=0)System.out.println(2020是偶数。);else System.out.println(2020是奇数。);l【例4-10】判断并输出2020年是否为闰年?l 闰年的判断是能被4整除但又不能被100整除,或能被400整除的公元年,因此闰年的判断可以用一个布尔表达式来实现。public class Test public static void main(String args)boolean leapYear;short year=2020;leapYear=(year%4=0&year%100!=0)|(year%400=0);if(leapYear)System.out.println(2020是闰年。);else System.out.println(2020不是闰年。);4.3.3 分支结构嵌套lJava语言允许对if-else条件语句进行嵌套使用。前述分支结构的语句部分,可以是任何语句(包括分支语句本身),我们把分支结构的语句部分仍为分支结构的情况,称为分支结构嵌套。l构造分支结构嵌套的主要目的是解决条件判断较多,较复杂的一些问题。l常见的嵌套结构如下所示:if(布尔表达式1)if(布尔表达式2)语句1;if(布尔表达式1)语句1;else if(布尔表达式2)语句2;else 语句3;if(布尔表达式1)if(布尔表达式2)语句1;else 语句2;else 语句3;请分析以下分支嵌套程序段执行后的输出结果。请分析以下分支嵌套程序段执行后的输出结果。int i=1,j=2;if(i!=j)-if(ij)-i-;-else j-;-System.out.println(“i=”+i+”,j=”+j);-else System.out.println(“i=”+i+”,j=”+j);-.-【例例4-11】根据某位同学的分数成绩,判断其等级:优秀(根据某位同学的分数成绩,判断其等级:优秀(90分以分以上);良好(上);良好(80分以上分以上90分以下);中等(分以下);中等(70分以上分以上80分以下);分以下);及格(及格(60分以上分以上70分以下);不及格(分以下);不及格(60分以下)。分以下)。public static void main(String args)throws IOException float score;InputStreamReader reader=new InputStreamReader(System.in);BufferedReader input=new BufferedReader(reader);System.out.println(请输入分数:);String temp=input.readLine();score=Float.parseFloat(temp);if(score 90)if(score 80)if(score 70)if(score 60)System.out.println(该同学的分数等级为:不及格);else System.out.println(该同学的分数等级为:及格);else System.out.println(该同学的分数等级为:中等);else System.out.println(该同学的分数等级为:良好);else System.out.println(该同学的分数等级为:优秀);【例例4-13】假定个人收入所得税的计算方式如下:当收入额小于等于假定个人收入所得税的计算方式如下:当收入额小于等于1800元时,免征个人所得税;超出元时,免征个人所得税;超出1800元但在元但在5000元以内的部分,元以内的部分,以以20%的税率征税;超出的税率征税;超出5000元但在元但在10000元以内的部分,按元以内的部分,按35%的的税率征税;超出税率征税;超出10000元的部分一律按元的部分一律按50%征税。试编写相应的征税征税。试编写相应的征税程序。程序。double income,tax;tax=0;if(income=1800)System.out.println(免征个税.);else if(income=5000)tax=(income-1800)*0.2;else if(income=10000)tax=(5000-1800)*0.2+(income-5000)*0.35;else tax=(5000-1800)*0.2+(10000-5000)*0.35 +(income-10000)*0.5;System.out.println(您的个人收入所得税额为:+tax);if(income=1800)System.out.println(免征个税免征个税.);else if(income=5000)tax=(income-1800)*0.2;else if(income=10000);tax=(5000-1800)*0.2+(income-5000)*0.35;else tax=(5000-1800)*0.2+(10000-5000)*0.35+(income-10000)*0.5;4.3.4 switch语句lJava语言多分支结构的实现语句是switch,switch语句的一般语法格式如下:switch(表达式表达式)case 判断值判断值1:语句语句1;case 判断值判断值2:语句语句2;.case 判断值判断值n:语句语句n;default:语句语句n+1;switch语句l表达式的值必须为有序数值(如整型数或字符等),不能为浮点数。lcase语句中的判断值则须为常量值,也可称之为标号,它代表一个case分支的入口,每一个case分支后面的语句可以是单条的,也可以是多条的,并且当有多条语句时,不需要加大括号将其括起来。ldefault子句是可选的,并且其位置必须在switch结构的末尾,当表达式的值与任何case常量值均不匹配时,就执行default子句,然后就退出switch结构了。l若表达式的值与任何case常量值均不匹配,且无default子句,则程序不执行任何操作,直接跳出switch结构,继续后续的程序。【例4-14】在控制台敲入0至6的数字,输出对应的星期数(0对应星期天,1对应星期一,依此类推)。public static void main(String args)throws IOExceptionint day;System.out.print(请输入星期数(0-6):);day=(int)(System.in.read()-0;switch(day)case 0:System.out.println(day+表示是星期日);case 1:System.out.println(day+表示是星期一);case 2:System.out.println(day+表示是星期二);case 3:System.out.println(day+表示是星期三);case 4:System.out.println(day+表示是星期四);case 5:System.out.println(day+表示是星期五);case 6:System.out.println(day+表示是星期六);default:System.out.println(day+是无效数!);switch(day)case 0:System.out.println(day+表示是星期日表示是星期日);break;case 1:System.out.println(day+表示是星期一表示是星期一);break;case 2:System.out.println(day+表示是星期二表示是星期二);break;case 3:System.out.println(day+表示是星期三表示是星期三);break;case 4:System.out.println(day+表示是星期四表示是星期四);break;case 5:System.out.println(day+表示是星期五表示是星期五);break;case 6:System.out.println(day+表示是星期六表示是星期六);break;default:System.out.println(day+是无效数是无效数!);使用使用switch结构时应注意的问题结构时应注意的问题 l(1)允许多个不同的case标号执行相同的一段程序,比如以下情形:.case 常量i:case 常量j:语句;break;.l(2)每一个case子句的常量值必须各不相同。4.4 循环结构l在进行程序设计时,经常会碰到一些计算并不很复杂,但却要重复进行相同的处理操作的问题。比如:l(1)计算累加和1+2+3+100。l(2)计算阶乘,如10!。l(3)计算一笔钱在银行存了若干年后,连本带息有多少?l问题(1),用一条语句:sum=1+2+3+100 来求解,则赋值表达式太长,l改成多条赋值语句:sum+=1;sum+=2;sum+=3;sum+=100;也不行,即便加到100那也有100条语句,程序过于臃肿,不利编辑、存储和运行。lJava语言引入三种语句:while、do-while以及for来解决这类问题。我们把这类问题的结构称为循环结构,把这三种实现语句称为循环语句。这三种循环语句的流程图如下所示:4.4.1 while语句lwhile语句的一般语法格式如下:while(条件表达式)循环体;while是关键字,首先计算条件表达式的值,若为true则执行循环体,然后再计算条件表达式的值,只要是true就循环执行,直到布尔值为false才结束退出while结构。循环体可以是复合语句、简单语句甚至是空语句,一般情况下,循环体中应包含有能修改条件表达式取值的语句,否则就容易出现“死循环”(程序毫无意义地无限循环下去)。例如:while(1);这里,循环体为一空语句,而条件表达式为一常量1(Java语言里,0代表false,非0为true),因此这是一死循环。【例4-17】利用while语句实现1到100的累加。public static void main(String args)int sum=0;/累加和变量sum int i=1;/控制变量i while(i=100)sum+=i;i+;System.out.println(累加和为:+sum);(1)存放累加和的变量初始值一般赋值为0。(2)变量i既是累加数,同时又是控制变量(控制循环体的循环次数)。(3)循环体语句sum+=i;i+;可以合并简写为:sum+=i+;但对于初学者而言,不建议这么写。()while循环体语句多于一条,因而必须以复合语句形式出现,千万别漏了大括号。【例4-18】利用while语句求10的阶乘。public class Test public static void main(String args)long jc=1;int i=1;while(i=10)jc*=i;i+;System.out.println(i-1)+!结果:+jc);本程序需要注意的要点有:(1)求阶乘的积时,变量jc初始值应为1。(2)由于阶乘的积,数值往往比较大,因此要注意防止溢出,比如尽量选用取值范围大的长整型long。【例4-20】有一条长的阶梯,如果每步2阶,则最后剩1阶,每步3阶则剩2阶,每步5阶则剩4阶,每步6阶则剩5阶,只有每步7阶的最后才刚好走完,一阶不剩,问这条阶梯最少共有多少阶?public class Test public static void main(String args)int i=1;while(!(i%2=1&i%3=2&i%5=4&i%6=5&i%7=0)i+;System.out.println(这条阶梯最少有:+i+阶);l假如现在想算出在1万个阶梯内,都有哪些阶梯数满足题意的话,可以这样改写程序中的while结构:while(i=10000)if(i%2=1&i%3=2&i%5=4&i%6=5&i%7=0)System.out.print(i+阶阶);i+;l新程序运行结果如下:l119阶 329阶 539阶 749阶 959阶 1169阶 1379阶 1589阶 1799阶 2009阶 2219阶 2429阶 2639阶 2849阶 3059阶 3269阶 3479阶 3689阶 3899阶 4109阶 4319阶 4529阶 4739阶 4949阶 5159阶 5369阶 5579阶 5789阶 5999阶 6209阶 6419阶 6629阶 6839阶 7049阶 7259阶7469阶 7679阶 7889阶 8099阶 8309阶 8519阶 8729阶 8939阶 9149阶 9359阶 9569阶 9779阶 9989阶4.4.2 do-while语句语句 ldo-while语句的语法格式如下:do循环体;循环体;while(条件表达式);(条件表达式);【例4-21】假定在Bank中存款额5000元,按6.25%的年利率计算,试问过多少年后 就会连本带利翻一翻?试编程实现之。public class Testpublic static void main(String args)double m=5000.0;/初始存款额 double s=m;/当前存款额 int count=0;/存款年数 do s=(1+0.0625)*s;count+;while(s2*m);System.out.println(count+年后连本带利翻一翻!);4.4.3 for语句语句 lfor语句的一般语法格式如下:for(表达式(表达式1;条件表达式;条件表达式2;表达式;表达式3)循环体;循环体;l表达式1一般用来给循环控制变量赋初值,它仅在刚开始时被执行一次,以后就不再被执行。l表达式2是一个条件表达式,根据其取值的不同,决定循环体是否被执行,若为true,则执行循环体,然后再执行表达式3。l表达式3通常用作修改循环控制变量之用,接着又判断条件表达式2的布尔值,若还为true,则继续上述循环,直至布尔值变为false。【例4-22】利用for语句实现1到100的累加。public class Test public static void main(String args)int sum=0;/累加和变量sum for(int i=1;i=100;i+)/控制变量i sum+=i;System.out.println(累加和为:+sum);【例4-23】假定在Bank中存款额5000元,按6.25%的 年利率计算,试问过多少年后就会连本带利翻一翻?试用for语句编程实现之。public class Test public static void main(String args)double m=5000.0;/初始存款额double s=m;/当前存款额int count=0;/存款年数for(;s2*m;s=(1+0.0625)*s)count+;System.out.println(count+年后连本带利翻一翻!);4.4.4 循环嵌套循环嵌套 l当循环体语句又是循环语句时,就构成了循环嵌套,即多重循环,循环嵌套可以是两重的、三重的甚至更多重(较复杂的算法)。【例4-24】编程实现打印以下图案:*public class Testpublic static void main(String args)int i,j;/i控制行数,j控制*的个数 for(i=1;i=6;i+)for(j=1;j=i*2-1;j+)System.out.print(*);System.out.println();/换行 *?4.4.5 跳转语句跳转语句 lbreak lcontinue lreturn 1 break lbreak语句的作用是使程序的流程从一个语句块的内部跳转出来,如前述的switch结构以及循环结构。break语句的语法格式为:break 标号;l标号是可选的,如前面介绍的switch结构程序就没有使用标号。不使用标号的break语句只能跳出当前的switch或循环结构,而带标号的则可以跳出由标号指出的语句块,并从语句块的下条语句处继续程序的执行。l因此,带标号的break语句可以用来跳出多重循环结构。【例4-25】写出以下程序执行后的输出结果。public class Test public static void main(String args)int i,s=0;for(i=1;i50)break;System.out.println(s=+s);【例4-26】写出以下程序执行后的输出结果。public class Test public static void main(String args)int jc=1,i=1;while(true)jc=jc*i;i=i+1;if(jc100000)/首先突破10万的阶乘 break;System.out.println(i-1)+的阶乘值是+jc);【例4-27】写出以下程序执行后的输出结果。public class Test public static void main(String args)int s=0,i=1;label:while(true)while(true)if(i%2=0)break;/不带标号 if(s50)break label;/带标号 s+=i+;i+;System.out.println(s=+s);2 continue lcontinue语句只能用于循环结构,它也有两种使用形式:不带标号和带标号。l前者的功能是提前结束本次循环,即跳过当前循环体的其他后续语句,提前进入下一轮循环体继续执行。对于while和do-while循环,不带标号的continue语句会使流程直接跳转到条件表达式,而对于for循环,则跳转至表达式3,修改控制变量后再进行条件表达式2的判断。l带标号continue语句多用在多重循环结构中,标号的位置与break语句的标号位置相类似,一般需放至整个循环结构的前面,用来标识这个循环结构,一旦内层循环执行了带标号continue语句,程序流程则跳转到标号处的最外层循环,具体是:while和do-while循环,跳转到条件表达式,for循环,跳转至表达式3。【例4-28】写出以下程序执行后的输出结果。public class Test public static void main(String args)int s=0,i=0;do i+;if(i%2!=0)continue;s+=i;while(s50);System.out.println(s=+s);【例4-29】写出以下程序执行后的输出结果。public class Test public static void main(String args)int i,j;label:for(i=1;i=200;i+)/查找1到200以内的素数 for(j=2;ji;j+)/检验是否不满足素数条件 if(i%j=0)/不满足 continue label;/跳过后面不必要的检验 System.out.print(+i);/打印素数 Hintsl 跳转语句break及continue的使用,使得程序流程设计变得更灵活,但同时也给编程者增加了分析负担,建议应少用,慎用。l学会分析程序的执行流程是掌握程序设计的关键,也是基础,建议初学者应读透本章的例子,为后面的进一步学习打下一个良好的开端。4.5 小结小结 l简单语句和复合语句的区别 lJava语言的三种基本程序流程 l跳转语句break和continue的用法