第3 章 学生成绩分级 学习目标 . 理解分支结构的作用; . 学会应用分支语句设计程序; . 掌握多分支程序设计的方法。 3.1 示例程序 第2章完成了一个有点实际意义的程序,显示了一个学生的姓名、年龄和成绩。下面 继续来丰富这个程序,根据学生成绩不同,显示出学生是否通过考试。判断的条件为: 通过:成绩>=60 未通过:成绩<60 想显示学生考试结果,就需要根据学生的成绩进行判断,看成绩是否大于等于60分, 是则通过,否则不通过。在程序2.3的基础上修改代码,结果如程序3.1所示。 【程序3.1】 程序StudentInfo.java。 /** * 程序功能:显示一个学生信息 * 作者:XXX * 日期:XX 年XX 月XX 日 */ import java.util. Scanner; public class StudentInfo{ /** * main 方法是Java 主方法 * 功能:显示一个学生信息 * 参数:没有用到 * 返回值:无 */ public static void main(String [] args){ //name 学生姓名 String name = "张三"; //age 学生年龄 34 Java 基础与应用(第2 版) int age = 23; //grade 学生成绩 double grade; //是否通过考试 String result = "通过"; //输入学生成绩 System.out.println("输入学生成绩:"); Scanner sc = new Scanner(System.in); grade = sc.nextDouble(); if(grade < 60 ){ result = "不通过"; } System.out.println("姓名:" + name); System.out.println("年龄:" + age); System.out.println("成绩:" + grade); System.out.println("考试结果:" + result); } } 程序3.1的编译和运行结果如图3.1所示。 图3.1 程序3.1运行结果 输入学生成绩值为87.67,保存到变量grade中,if语句中的条件grade<60不成立, result变量值不变,因此输出考试结果为“通过”。 3.2 相关知识 3.2.1 基本语句 Java语言的基本语句包括方法调用语句、表达式语句和复合语句。方法调用语句是 调用某个类或者对象的方法。例如输入学生成绩时调用Scanner 类对象sc 的 nextDouble()方法的语句: grade = sc.nextDouble(); 表达式语句,是在表达式的末尾加上分号“;”,例如,上面例子中给一个字符串变量赋 第3 章 学生成绩分级 35 值语句: result = "不通过"; Java语言允许使用一对大括号“{”和“}”把一条或者多条语句扩起来,组成一个代码 块,称为复合语句。逻辑上一个代码块相当于一条语句,如在下面程序段中,条件成立时 执行的语句块: if(grade < 60 ){ result = "不通过"; System.out.println("成绩" + grade); } 上面介绍的三种语句是Java的基本语句,这些基本语句可以组成不同的程序段,也 可以作为其他复合语句的基本组成部分。 3.2.2 条件分支语句 语句if是Java语言中的条件分支语句,作用是根据不同条件来执行不同的操作,if 语句格式如下: if(条件表达式){ 若干条语句 }[ else{ 若干条语句 } ] 其中,条件表达式是一个逻辑表达式,结果是一个逻辑值,如果这个值为true,则执行 条件后面紧跟着的若干条语句。方括号[]里的else部分是可选的,如果有else部分,则 在条件表达式为false的时候执行else后面的若干条语句。如果没有else部分,条件表 达式为false时执行if语句的下一条语句。例如下面程序段就是一个没有else部分的if 语句。 if(grade < 60 ){ result = "不通过"; } 上面这个程序段是程序3.1中的一段,可以修改这段程序,增加else部分,修改后的 程序码如下: String result = ""; …i f(grade < 60 ){ 36 Java 基础与应用(第2 版) result = "不通过"; }e lse{ result = "通过"; } 修改后的程序,与原来的程序段功能完全一样,读者可以想想为什么是一样的,可以 自己多找几个成绩来试试,看看两段程序的运行结果是否一致。 3.2.3 多分支语句 如果有多个条件需要判断,则需要使用多分支条件语句。多分支if语句格式如下: if(条件表达式1){ 若干条语句1 }e lse if(条件表达式2){ 若干条语句2 } …e lse if(条件表达式n){ 若干条语句n } [else{ 若干条语句 }] 与条件分支语句相同,所有的多分支语句中条件表达式都是一个逻辑表达式,结果为 true或者false。如果条件表达式1的结果为true,执行后面的若干条语句1,执行完结 束;否则判断条件表达式2,如果条件表达式2的结果为true,则执行后面的若干条语句 2,执行完结束;否则继续判断后面的条件表达式。如果所有条件表达式全部为false,则 执行最后else部分的语句。 另外,还有一种多分支switch语句使用相对较少,除非应用中特别适合使用该语句, 一般情况下尽量使用多分支if语句来实现。如果使用对象的状态常量作为条件,也可以 考虑使用多态技术来实现,对象多态技术参见第14章。 3.3 训练程序 参照程序3.1增加新功能。根据学生的成绩进行分级,级别包括优秀、良好、及格和 不及格四个等级,等级与成绩对应关系如下: 优秀:成绩>= 90 良好:成绩>=75 且成绩< 90 第3 章 学生成绩分级 37 及格:成绩>=60 且成绩< 75 不及格:成绩<60 要求从键盘读入学生成绩,显示学生成绩等级。 3.3.1 程序分析 由于学生成绩分成多个级别,因此适合使用多分支语句来实现。上面列出的判断方 法就是不同的条件,等级就是执行结果。程序思路如下: 先判断学生成绩是否大于等于90,如果是则等级为优秀 否则再判断成绩是否大于等于75,如果是则等级为良好 否则再判断成绩是否大于等于60,如果是则等级为及格 否则学生成绩等级为不及格 3.3.2 参考程序 根据上面的分析过程,参考程序3.1把这个分析过程转化成多分支语句,得到程序结 果如程序3.2所示。 【程序3.2】 多分支程序StudentInfo.java。 /** * 程序功能:显示一个学生信息 * 作者:XXX * 日期:XX 年XX 月XX 日 */ import java.util.Scanner; public class StudentInfo{ /** * main 方法是Java 主方法 * 功能:显示一个学生信息 * 参数:没有用到 * 返回值:无 */ public static void main(String [] args){ //name 学生姓名 String name = "张三"; //age 学生年龄 int age = 23; //grade 学生成绩 double grade = 0; //成绩级别 String result = ""; System.out.println("请输入学生成绩:"); Scanner sc = new Scanner(System.in); grade = sc.nextDouble(); 38 Java 基础与应用(第2 版) if(grade >= 90 ){ result = "优秀"; } else if(grade<90 && grade >=75){ result="良好"; } else if(grade<75 && grade>=60){ result="及格"; } else{ result="不及格"; } System.out.println("姓名:" + name); System.out.println("年龄:" + age); System.out.println("成绩:" + grade); System.out.println("成绩级别:" + result); } } 程序3.2的运行结果如图3.2所示。 图3.2 程序3.2运行结果 输入学生成绩67.5,根据多分支语句中的判断条件,条件“grade<75&&grade>= 60”成立,执行该条件对应的语句,将result变量赋值为“及格”,多分支语句结束。程序最 后输出成绩级别为“及格”。有兴趣的读者可以继续改进这个程序,增加输入成绩在0~ 100范围内的判断。 3.3.3 进阶训练 在上面的程序中,学生信息和教师信息都是直接将键盘输入的数据赋给变量,没有经 过处理。但程序设计时,许多变量的值输入后并不直接使用,而要经过有效性判断。如果 是合法数据进行处理,不合法数据给出提示。 【程序3.3】 计算圆面积进阶2。在程序2.8的基础上,从键盘输入圆的半径值,如果 圆的半径大于等于0,则计算出圆的面积并输出;否则打印提示:“圆半径错误!”。 程序设计思路分析: (1)定义double类型的变量r和area,分别表示圆的半径和面积; 第3 章 学生成绩分级 39 (2)从键盘输入半径r的值; (3)使用分支语句,判断r>=0是否为真; (4)为真则使用圆面积公式(r×r×π)计算出面积的值,并赋值给变量area;将area 的值输出; (5)否则输出字符串“圆半径错误!”。 读者可以根据前面给出的设计思路,自己编写这个程序,并编译、运行程序,查看结果 是否正确。 3.4 拓展知识 3.4.1 分支语句讨论 从上面的例子可以看出分支语句的格式比较简单,但是在实际应用中还是有很多需 要注意的问题,恰当处理这些问题可以提高代码的可读性和质量。下面讲解三个常见问 题的处理方法。 第一个问题,如果分支中只有一条语句是否可以看作一个语句块。分支语句根据条 件不同执行不同的分支,每个分支可以是一条语句也可以是一个语句块,前面的例子中每 个分支都看作一个语句块,使用大括号括了起来,例如下面代码段: if(grade < 60 ){ result = "不通过"; }e lse{ result = "通过"; } 在这个代码段中,每个分支只有一条语句,但是仍然用大括号括起来。从语法上讲, 上面代码段的两个分支可以不用大括号,写成如下形式: if(grade < 60 ) result = "不通过"; else result = "通过"; 从程序设计规范角度来讲,建议把每个分支作为一个语句块处理,这样增加程序可读 性,降低出错可能性。 第二个问题是多个if语句相互配合的问题。在实际的程序设计中,分支语句的每个 分支可能也是if分支语句,例如下面程序段: double grade = 70; if(grade >= 60) if(grade >=90) System.out.println("优秀"); 40 Java 基础与应用(第2 版) else System.out.println("什么等级? "); 分析上面的程序段,里面的else语句和哪个if相匹配呢? 刚开始看到这样的程序是 很难一下子说清楚的。按照语法上讲,else应该和离它最近的且没有配对的if相匹配。 实际程序设计中尽量避免出现这样容易产生歧义的语句。处理方法很简单,一种方法是 按照前面说的每个分支都作为语句块处理,加上大括号;还有一种方法就是使用多分支if 语句实现。感兴趣的读者可以自己尝试使用这两种方法完成这个程序。 第三个常见的问题是,对于多分支if语句,应该按照什么次序来排列这些分支。常 见的处理方法有两种:第一种方法就是程序3.2给出的方法,按照问题给出的先后顺序 来排列。程序3.2中就是按照等级优秀、良好、及格和不及格的次序进行处理,这样做方 便用户阅读和理解程序。对于问题中没有明显次序的多分支程序,建议可以按照出现的 频率把经常使用的分支排在前面,这样可以提高程序处理效率。 3.4.2 数据合法性检查 在编写Java程序过程中,经常使用输入语句从键盘输入数据,例如程序3.2中就使用输 入语句输入学生成绩。程序3.2能够正确运行并得到结果,但这个程序是否还存在问题? 如果输入的数据不是双精度数,而是一个字符串,结果会如何? 下面运行程序3.2,输 入数据1a2,运行结果如图3.3所示。 图3.3 程序3.2运行结果 可以看到程序出现了错误,出错的原因是因为输入的数据不正确,系统提示抛出一个 InputMismatchException类异常,有关异常知识在第17章中进行介绍。 如果编写的程序是交付给用户使用的实际软件,那么无法保证用户每次的输入数据 都符合程序的需要。这时候程序就需要先对用户输入的数据进行合法性检查,只有通过 检查,格式正确的数据程序才能进行下一步处理,否则提示用户输入数据格式不正确。改 进后的程序如程序3.4所示。 【程序3.4】 合法性检查程序StudentInfo.java。 /** * 程序功能:显示一个学生信息 * 作者:XXX * 日期:XX 年XX 月XX 日 */ 第3 章 学生成绩分级 41 import java.util.Scanner; import java.util.InputMismatchException; public class StudentInfo{ /** * main 方法是Java 主方法 * 功能:显示一个学生信息 * 参数:没有用到 * 返回值:无 */ public static void main(String [] args){ //name 学生姓名 String name = "张三"; //age 学生年龄 int age = 23; //grade 学生成绩 double grade = 0; //是否通过考试 String result = "通过"; try{ Scanner sc = new Scanner(System.in); grade = sc.nextDouble(); } catch(InputMismatchException ime){ System.out.println("输入数据格式不正确"); } if(grade < 60 ){ result = "不通过"; } System.out.println("姓名:" + name); System.out.println("年龄:" + age); System.out.println("成绩:" + grade); System.out.println("考试结果:" + result); } } 程序3.4的运行结果如图3.4所示。 图3.4 程序3.4运行结果 42 Java 基础与应用(第2 版) 程序中增加了异常处理,用来处理输入数据格式不正确这种异常的情况。有关异常 处理详见第17章。 最后做个简单的总结,本章学习了分支结构关键字:if、else,同时涉及到switch、 case,但没有详细说明,另外,goto语句已经废弃不再进行讲解,表3-1中分别用粗体和斜 体表示上述关键字。其余关键字将在后续章节讲解。 表3-1 Java关键字 abstract do implements protected this assert*** else import public throw break enum**** instanceof return throws case extends interface static transient catch final native strictfp** try class finally new super void const* for package switch volatile continue goto* private synchronized while default if 3.5 实做程序 1.请根据错误提示找出下列程序中存在错误并分析原因。 (1)程序Test.java,根据成绩判断考试是否通过,考试不通过则输出成绩,通过则不 输出,运行结果如下。 public class Test { public static void main(String[] args){ double grade = 70; if(grade >= 60) System.out.println("考试通过"); else System.out.println("考试成绩:" + grade); System.out.println("考试不通过"); } } (2)程序Test.java,程序编译报错。 public class Test { 第3 章 学生成绩分级 43 public static void main(String[] args){ int flag; flag = 0; if(flag){ System.out.println("标志不为0"); } } } 2.从键盘输入两个数,按照由大到小顺序输出。要点提示: (1)方法一:比较a和b的大小,如果a>b则先输出a再输出b,否则先输出b再输 出a; (2)方法二:比较a和b的大小,如果a= 60){ } else{ System.out.println("考试不通过"); } } } 44 Java 基础与应用(第2 版) 要点提示: (1)分支语句中需要处理的分支按照重要性从前到后排列; (2)不提倡使用空分支。 6.输入整数n,判断n是否可以同时被3和7整除,输出判断的结果。要点提示,判 断n是否整除3,可以使用表达式:n%3==0。 7.输入三个整数a、b、c,将三个数按从小到大的顺序输出。要点提示: (1)方法一:直接比较a、b、c三个数,根据比较的结果输出; (2)方法二:先比较a和b,如果a>b则交换a、b,再与c比较大小。 8.已知x 和y 的关系是一个分段函数,编写程序,输入x 的值,计算输出y 的值。 y= 10+2x,x<0 1,x=0 5+x,x>0 ì . í .. .. 9.PM2.5是指大气中直径小于或等于2.5微米的颗粒物,也称为可入肺颗粒物,它含 有大量的有毒、有害物质且在大气中的停留时间长、输送距离远,因而对人体健康和大气 环境质量的影响很大。我们用空气中PM2.5的浓度反映空气污染的程度。编写空气质 量预报程序,输入PM2.5的值,显示空气质量的分级结果。空气质量的等级标准如下表。 PM2.5浓度(μg/m3) 等 级 0~35 优 35~75 良 75~115 轻度污染 115~150 中度污染 150~250 重度污染 250以上严重污染 10.编写程序,输入自己的身高和体重,根据公式计算身体质量指数BMI值,并输出 所对应的分类。BMI的计算公式:BMI=体重(kg)÷身高2(m2)。 国内BMI值(kg/m2) 分 类 <18.5 偏瘦 18.5~24 正常 24~28 偏胖 >=28 肥胖 11.购物时如果买的商品数量比较多,商家往往会打相应的折扣。购买瓶装水时,如 果购买数量为1~5瓶,按原价结账;如果购买数量为6~10瓶,结账时打9.5折;如果购 买11~23瓶,结账时打9折;如果购买24瓶及以上,结账时打8.5折。编写程序,输入购 买数量和单价,计算并输出付款金额,计算结果保留小数点后两位。 45 第 3 章 学生成绩分级 12. 实做程序2.7实现了摄氏温度和华氏温度的相互转换。现在我们把这两 6和2. 个程序合并成一个完整的温度转换程序,如果输入摄氏温度则转换为华氏温度,如果输入 华氏温度则转换为摄氏温度,输出转换结果。要点提示: (1)设置一个标志位用来判断进行哪种转换,例如值为1和2,从键盘输入标志位 的值; (2)使用分支结构,将标志位的取值作为条件表达式,根据标志位的值不同执行不同 的分支; (3)两个分支中分别编写摄氏温度转换华氏温度、华氏温度转换摄氏温度的代码。