第三章 流程控制
今日内容
- if else判断语句
- switch选择语句
学习目标
- 掌握键盘输入各种数据类型的值
- 理解if语句的格式和执行流程
- 理解if…else语句的格式和执行流程
- 理解if…else if语句的格式和执行流程
- 了解if语句和三元运算符互换
- 理解switch选择语句的格式和执行流程
- 掌握switch选择语句接收的数据类型
- 理解case的穿透性
- 掌握break在switch中的使用
- 掌握default在switch中的使用
3.1 顺序结构
顺序结构就是程序从上到下逐行地执行,中间没有任何判断和跳转。
public static void main(String[] args){
//顺序执行,根据编写的顺序,从上到下运行
System.out.println(1);
System.out.println(2);
System.out.println(3);
}
3.2 扩展:输入语句
如何从键盘获取不同类型的变量:需要使用Scanner类;
3.2.1 具体实现步骤:
-
导包:import java.util.Scanner;
-
Scanner的实例化
-
调用Scanner类的相关方法(next() / nextXxx()),来获取指定类型的变量
注意:
需要根据相应的方法,来输入指定类型的值。如果输入的数据类型不匹配时,
会报异常:InputMisMatchException,导致程序终止。
//列出各种数据类型的输入
int num = input.nextInt();
long bigNum = input.nextLong();
double d = input.nextDouble();
boolean b = input.nextBoolean();
String s = input.next();
char c = input.next().charAt(0);//先按照字符串接收,然后再取字符串的第一个字符(下标为0)
3.2.2 案例
- 从键盘输入个人信息
//导包:import java.util.Scanner;
import java.util.Scanner;
class ScannerTest{
public static void main(String[] args){
//Scanner的实例化
Scanner scan = new Scanner(System.in);
//调用Scanner类的相关方法
System.out.println("请输入你的姓名:");
String name = scan.next();
System.out.println("请输入你的年龄:");
int age = scan.nextInt();
System.out.println("你的姓名是:" + name + "\n你的年龄是:" + age);
//对于char型的获取,Scanner没有提供相关的方法。只能获取一个字符串。
//.charAt(0):从字符串中取出一个字符,(0)表示取第一个字符,(1)表示取第二个字符
System.out.println("请输入你的性别:");
String gender = scan.next();
char genderChar = gender.charAt(0);获取索引位置上的字符
System.out.println("您的性别是:" + genderChar);
}
}
next()
与nextLine()
3.3 分支结构(if-else)
3.3.1 if-else的第一种格式
- 一选一结构:
if(条件表达式){
执行代码块;
}
- 执行流程
-
首先判断条件表达式看其结果是true还是false;
-
如果是true就执行语句体
-
如果是false就不执行语句体
- 案例演示
public static void main(String[] args){
System.out.println("开始");
// 定义两个变量
int a = 10;
int b = 20;
//变量使用if判断
if (a == b){
System.out.println("a等于b");
}
int c = 10;
if(a == c){
System.out.println("a等于c");
}
System.out.println("结束");
}
3.3.2 if-else的第二种格式
- 二选一结构
if(条件表达式) {
执行代码块1;
}else {
执行代码块2;
}
- 执行流程
-
首先判断关系表达式看其结果是true还是false;
-
如果是true就执行语句体1;
-
如果是false就执行语句体2。
- 案例演示1
public static void main(String[] args){
// 判断给定的数据是奇数还是偶数
// 定义变量
int a = 1;
if(a % 2 == 0) {
System.out.println("a是偶数");
} else{
System.out.println("a是奇数");
}
System.out.println("结束");
}
- 案例演示2(if-else与三元运算符的转换)
public static void main(String[] args) {
int a = 10;
int b = 20;
//定义变量,保存a和b的较大值
int max;
if(a > b) {
max = a;
} else {
max = b;
}
//可以上述功能改写为三元运算符形式
max = a > b ? a : b;
}
-
说明的问题:
- if-else是可以互相嵌套的;
- 条件表达式的结果必须是boolean类型;
- 如果if-else结构中的执行语句只有一行时,对应的一对{}可以省略,但是不建议省略。
3.3.3 if-else的第三种格式
- 多选一结构
if (判断条件1) {
执行语句1;
} else if (判断条件2) {
执行语句2;
}
...
}else if (判断条件n) {
执行语句n;
} else {
执行语句n+1;
}
- 执行流程
-
首先判断关系表达式1看其结果是true还是false;
-
如果是true就执行语句体1,然后结束当前多分支;
-
如果是false就继续判断关系表达式2看其结果是true还是false;
-
如果是true就执行语句体2,然后结束当前多分支;
-
……
-
如果没有任何关系表达式为true,就执行语句体n+1,然后结束当前多分支。
- 案例演示1
/*
通过指定考试成绩,判断学生等级:
90-100 优秀;
80-89 好;
70-79 良;
60-69 及格;
60以下 不及格.
*/
public static void main(String[] args) {
int score = 89;
if(score<0 || score>100){
System.out.println("你的成绩是错误的");
}else if(score>=90){
System.out.println("你的成绩属于优秀");
}else if(score>=80){
System.out.println("你的成绩属于好");
}else if(score>=70){
System.out.println("你的成绩属于良");
}else if(score>=60){
System.out.println("你的成绩属于及格");
}else {
System.out.println("你的成绩属于不及格");
}
}
- 案例演示2
/*
假设你想开发一个玩彩票的游戏,程序随机地产生一个两位数的彩票,提示用户输入一个两位数,然后按照下面的规则判定用户是否能赢。
1)如果用户输入的数匹配彩票的实际顺序,奖金10 000美元。
2)如果用户输入的所有数字匹配彩票的所有数字,但顺序不一致,奖金 3 000美元。
3)如果用户输入的一个数字仅满足顺序情况下匹配彩票的一个数字,奖金1 000美元。
4)如果用户输入的一个数字仅满足非顺序情况下匹配彩票的一个数字,奖金500美元。
5)如果用户输入的数字没有匹配任何一个数字,则彩票作废。
*/
import java.util.Scanner;
class Test03{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int lotteryNum = (int)(Math.random()*90+10);
System.out.println("----------彩票游戏-----------");
System.out.println("请输入您彩票的两位数:");
int lottery = scan.nextInt();
if(lottery == lotteryNum){
System.out.println("恭喜您,中奖10000$");
}else if((lottery%10 == lotteryNum/10) && (lottery/10 == lotteryNum%10)){
System.out.println("恭喜您,中奖3000$");
}else if((lottery%10 == lotteryNum%10) || (lottery/10 == lotteryNum/10)){
System.out.println("恭喜您,中奖1000$");
}else if((lottery%10 == lotteryNum/10) || (lottery/10 == lotteryNum%10)){
System.out.println("恭喜您,中奖500$");
}else{
System.out.println("谢谢惠顾!");
}
}
}
- 说明(语句顺序关系)
-
如果多个条件表达式之间是“互斥”关系(或没有交集的关系),哪个判断和执行语句声明在上下不影响运算的正确性;
-
如果多个条件表达式之间有交集的关系,需要根据实际情况,考虑清楚应该将哪个结构声明在上面;
-
如果多个条件表达式之间有包含关系,通常情况下,需要将范围小的声明在范围大的上面,否则,范围小的就没有机会执行。
3.3.4 分支结构-嵌套
在if的语句块中,或者是在else语句块中,又包含了另外一个条件判断(可以是单分支、双分支、多分支)
- 执行的特点:
(1)如果是嵌套在if语句块中的只有当外部的if条件满足,才会去判断内部的条件;
(2)如果是嵌套在else语句块中的只有当外部的if条件不满足,进入else后,才会去判断内部的条件。
- 案例演示1
/*
从屏幕输入三个数值,然后比较三个数值的大小关系。
*/
import java.util.Scanner;
class IfTest03{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
//输入三个数值
System.out.println("请输入第一个整型数字:");
int num1 = scan.nextInt();
System.out.println("请输入第二个整型数字:");
int num2 = scan.nextInt();
System.out.println("请输入第三个整型数字:");
int num3 = scan.nextInt();
//数字排序
if(num1 >= num2){
if(num2>=num3){
System.out.println("三个数字从小到大排序结果为:"+num3+"、"+num2+"、"+num1);
}else{
if(num1>= num3){
System.out.println("三个数字从小到大排序结果为:"+num2+"、"+num3+"、"+num1);
}else{
System.out.println("三个数字从小到大排序结果为:"+num2+"、"+num1+"、"+num3);
}
}
}else{
if(num2 <= num3){
System.out.println("三个数字从小到大排序结果为:"+num1+"、"+num2+"、"+num3);
}else{
if(num1>=num3){
System.out.println("三个数字从小到大排序结果为:"+num3+"、"+num1+"、"+num2);
}else{
System.out.println("三个数字从小到大排序结果为:"+num1+"、"+num3+"、"+num2);
}
}
}
}
}
- 案例演示2
/*
利用嵌套循环在屏幕上打印出由“*”组成的菱形(如下所示):
*
* *
* * *
* * * *
* * * * *
* * * *
* * *
* *
*
说明:
1.内层循环结构遍历一次,只相当于外层循环执行了一次;
2.假设外层循环需要执行m次,内层循环需要执行n次,此时内层循环体一共执行了m*n次;
3.外层循环控制行数,内层循环控制列数;
*/
class Rhombus{
public static void main(String[] args){
//上半段
for(int i = 1;i<=5;i++){
for(int j =5-i;j>0;j--){
System.out.print(" ");
}
for(int k =1;k<=i;k++){
System.out.print("* ");
}
System.out.println();
}
//下半段
for(int i = 1;i<=4;i++){
System.out.print(" ");
for(int j =1;j<i;j++){
System.out.print(" ");
}
for(int k =1;k<=5-i;k++){
System.out.print("* ");
}
System.out.println();
}
}
}
- 案例演示3
class Test12NestIfElse{
public static void main(String[] args){
//从键盘输入年份,判断是闰年还是平年
java.util.Scanner input = new java.util.Scanner(System.in);
System.out.println("请连续年份:");
int year = input.nextInt();
if(year >= 0){
//在if{}中嵌套了一个双分支
if(year%4==0 && year%100!=0 || year%400==0){
System.out.println("闰年")
}else{
System.out.println("平年")
}
}else{
System.out.println("输入有误");
}
}
}
3.4 分支结构(switch-case)
3.4.1 调用格式
switch(表达式){
case 常量1:
执行语句1;
//break;
case 常量2:
执行语句2;
//break;
case 常量3:
执行语句3;
//break;
……
default:
执行语句n;
//break;
- 执行过程
-
入口.
- 当switch(表达式)的值与case后面的某个常量值匹配,就从这个case进入;
- 当switch(表达式)的值与case后面的所有常量值都不匹配,寻找default分支进入;不管default在哪里;
-
一旦从“入口”进入switch,就会顺序往下执行,直到遇到“出口”,即可能发生贯穿;
-
出口.
-
自然出口:遇到了switch的结束};
-
中断出口:遇到了break等。
-
3.4.2 说明
-
根据switch表达式中的值,依次匹配各个case中的常量,一旦匹配成功,则进入相应的case语句结构中,调用其执行语句。当调用完执行语句后,则继续向下执行其他的case结构中的语句,直到遇到break关键字或此switch-case结构末尾结束为止;
-
case后面必须是常量值,并且不能重复;
-
switch结构中的表达式,只能是如下六种数据类型之一:
byte、short、char、int、枚举类型(JDK5.0新增)、String类型(JDK7.0新增).
-
case之后只能声明常量,不能声明范围;
-
如果switch-case结构中的多个case的执行语句相同,则可以进行合并;
-
default:相当于if-else中的else,也是可选的,而且位置是灵活的。
3.4.3 案例演示
- 案例演示1
/*
case的穿透性:
根据指定的月份输出对应季节
*/
class Test12Exer8{
public static void main(String[] args){
java.util.Scanner input = new java.util.Scanner(System.in);
System.out.print("请输入月份:");
int month = input.nextInt();
switch(month) {
case 1:
case 2:
case 12:
System.out.println("冬季");
break;
case 3:
case 4:
case 5:
System.out.println("春季");
break;
case 6:
case 7:
case 8:
System.out.println("夏季");
break;
case 9:
case 10:
case 11:
System.out.println("秋季");
break;
default:
System.out.println("你输入的月份有误");
break;
}
}
}
- 案例演示2
/*
从键盘分别输入年、月、日,判断这一天是当年的第几天 。先不考虑非法值输入
注:判断一年是否是闰年的标准:
1)可以被4整除,但不可被100整除
2)可以被400整除
*/
import java.util.Scanner;
class Test05{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
//输入年月日的值
System.out.println("请输入年份:");
int year = scan.nextInt();
System.out.println("请输入该年中的月份:");
int month = scan.nextInt();
System.out.println("请输入该月份中的日期:");
int day = scan.nextInt();
int sumDay = 0;
switch(month){
case 12:
sumDay +=30;
case 11:
sumDay +=31;
case 10:
sumDay +=30;
case 9:
sumDay +=31;
case 8:
sumDay +=31;
case 7:
sumDay +=30;
case 6:
sumDay +=31;
case 5:
sumDay +=30;
case 4:
sumDay +=31;
case 3://需要判断闰年与平年
if(year % 4 ==0 && year%100!=0 || year%400==0){
sumDay +=28;
}else{
sumDay +=28;
}
case 2:
sumDay +=31;
case 1:
sumDay +=day;
}
System.out.println(year + "年"+month+"月"+day +"号是该年的第"+sumDay+"天");
}
}
;
int day = scan.nextInt();
int sumDay = 0;
switch(month){
case 12:
sumDay +=30;
case 11:
sumDay +=31;
case 10:
sumDay +=30;
case 9:
sumDay +=31;
case 8:
sumDay +=31;
case 7:
sumDay +=30;
case 6:
sumDay +=31;
case 5:
sumDay +=30;
case 4:
sumDay +=31;
case 3://需要判断闰年与平年
if(year % 4 ==0 && year%100!=0 || year%400==0){
sumDay +=28;
}else{
sumDay +=28;
}
case 2:
sumDay +=31;
case 1:
sumDay +=day;
}
System.out.println(year + "年"+month+"月"+day +"号是该年的第"+sumDay+"天");
}
}