四、 程序流程控制
4.1 分支结构
4.1.1 if-else结构
① 格式1:一种选择
if (条件表达式) {
执行代码块;
}
② 格式2:两种选择
if (条件表达式) {
执行代码块1;
}
else{
执行代码块2;
}
③ 格式3:多种选择
if (条件表达式1) {
执行代码块1;
}
else if (条件表达式2){
执行代码块2;
}
......
else{
执行代码块n;
}
④ 例子代码
public class IfTest {
public static void main(String[] args){
//例子1
int heartBeat = 150;
if (heartBeat < 60 || heartBeat > 110){
System.out.println("Your Heart is abnormal, please check out!");
}
System.out.println("Checking is over.");
//二选一例子2
int age = 11;
if (age < 18){
System.out.println("You are a minor.");
} else {
System.out.println("You are a adult.");
}
//多选一例子3
if (age < 0 || age > 150){
System.out.println("The data you input is illegal.");
}else if (age < 12){
System.out.println("You are a children.");
}else if (age < 30){
System.out.println("You are a youth.");
}else if (age < 60){
System.out.println("You are a middle-aged person.");
}else{
System.out.println("You are a old people.");
}
}
}
注意:在多选一的例子中,条件表达式不需要写成 (age > 12 && age < 30) 也可正确运行。
① 如果多个条件表达式之间没有交集,条件顺序无所谓。因为if-else结构式一旦条件符合执行了代码块之后就立马退出了;
② 如果多个条件表达式之间有交集关系,要根据实际情况,考虑清楚顺序和条件判断语句。
③如果多个条件表达式之间有包含关系,需要将范围小的声明放在范围大的上面,否则后者将无法执行导致判断错误。
④ if-else 结构是可以相互嵌套的,但是,没见过3层以上的。
⑤ 如果 if-else语句的执行语句中只有1行代码时,对应的一对{}可以省略,但是不建议省略。
4.1.2 switch-case结构
① 语句格式:
switch (表达式){
case 常量1:
语句1;
//break;
case 常量2:
语句2;
//break;
......
case 常量N:
语句B;
//break;
default:
语句;
//break;
}
( 1 ) (1) (1) switch-case 结构特点
① 遇到符合条件的 case ,执行完语句后,如果没有 break 语句,不会跳出结构,会继续匹配下面符合条件的 case 。直到遇到 break 或者 default 为止。
② 一旦遇到 break 就跳出switch-case 结构。
③ switch (表达式)不像 if-else 结构,不是 Boolean类型的数据。只能是如下的6种数据类型之一:
1 | 2 | 3 | 4 | 5 | 6 |
---|---|---|---|---|---|
byte | short | char | int | 枚举类型 | String |
④ case 之后只能声明常量。不能声明一个范围。
⑤ break 关键字是可选的,不是必须的,看实际情况而定。
⑥ default 中文意思是“默认的”,意思是当所有case 都不匹配时,就执行default中的语句块,但是,default 结构也是可选的,不是必须的,而且位置是灵活的。
⑦ 如果 switch-case 结构中的多个case的执行语句相同,则可以考虑进行合并:
未合并前的效果:
Scanner scan = new Scanner(System.in);
System.out.print("Please input the student's score: ");
int input = scan.nextInt();
//不合并的效果:
int score = input / 10;
switch (score){
case 0:
System.out.println("fail");
break;
case 1:
System.out.println("fail");
break;
case 2:
System.out.println("fail");
break;
case 3:
System.out.println("fail");
break;
case 4:
System.out.println("fail");
break;
case 5:
System.out.println("fail");
break;
case 6:
System.out.println("pass");
break;
case 7:
System.out.println("pass");
break;
case 8:
System.out.println("pass");
break;
case 9:
System.out.println("pass");
break;
case 10:
System.out.println("pass");
break;
default:
System.out.println("The score you input is invalid. ");
break;
}
合并完的效果:
//合并完的效果:
int score = input / 10;
switch (score){
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("fail");
break;
case 6:
case 7:
case 8:
case 9:
case 10:
System.out.println("pass");
break;
default:
System.out.println("The score you input is invalid. ");
}
最优写法:
//最优写法:
int score = input / 60;
switch (score){
case 0:
System.out.println("fail");
break;
case 1:
System.out.println("pass");
break;
default:
System.out.println("The score you input is invalid. ");
}
( 2 ) (2) (2) 一道例题说明switch-case 结构不写break+逆向思维的好处
4. 编写程序:从键盘上输入2021年的“month”和"day”,要求通过程序输出输入的日期为2021年的第几天 。
① 我一开始的写法:
import java.util.Scanner;
public class switchCaseTest {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
for (int i = 1; i<=1; i++){
System.out.print("Please input the month(1-12): ");
int month = scan.nextInt();
System.out.print("Please input the day(1-31): ");
int day = scan.nextInt();
int tolDay = 0;
switch (month){
case 1:
tolDay = day;
System.out.println("Today is the " + tolDay + "th days of 2021. ");
break;
case 2:
tolDay = 31 + day;
System.out.println("Today is the " + tolDay + "th days of 2021. ");
break;
case 3:
tolDay = 31+28 + day;
System.out.println("Today is the " + tolDay + "th days of 2021. ");
break;
case 4:
tolDay = 31+28+31 + day;
System.out.println("Today is the " + tolDay + "th days of 2021. ");
break;
case 5:
tolDay = 31+28+31+30 + day;
System.out.println("Today is the " + tolDay + "th days of 2021. ");
break;
case 6:
tolDay = 31+28+31+30+31 + day;
System.out.println("Today is the " + tolDay + "th days of 2021. ");
break;
case 7:
tolDay = 31+28+31+30+31+30 + day;
System.out.println("Today is the " + tolDay + "th days of 2021. ");
break;
case 8:
tolDay = 31+28+31+30+31+30+31 + day;
System.out.println("Today is the " + tolDay + "th days of 2021. ");
break;
case 9:
tolDay = 31+28+31+30+31+30+31+31 + day;
System.out.println("Today is the " + tolDay + "th days of 2021. ");
break;
case 10:
tolDay = 31+28+31+30+31+30+31+31+30 + day;
System.out.println("Today is the " + tolDay + "th days of 2021. ");
break;
case 11:
tolDay = 31+28+31+30+31+30+31+31+30+31 + day;
System.out.println("Today is the " + tolDay + "th days of 2021. ");
break;
case 12:
tolDay = 31+28+31+30+31+30+31+31+30+31+30 + day;
System.out.println("Today is the " + tolDay + "th days of 2021. ");
break;
default:
System.out.println("The data your input is invalid. ");
}
}
}
}
② 可以通过不写 break + 逆向思维,来减少代码的冗余量:
System.out.print("Please input the month(1-12): ");
int month = scan.nextInt();
System.out.print("Please input the day(1-31): ");
int day = scan.nextInt();
int tolDay = 0;
switch (month){
case 12:
tolDay += 30;
case 11:
tolDay += 31;
case 10:
tolDay += 30;
case 9:
tolDay += 31;
case 8:
tolDay += 31;
case 7:
tolDay += 30;
case 6:
tolDay += 31;
case 5:
tolDay += 30;
case 4:
tolDay += 31;
case 3:
tolDay += 28;
case 2:
tolDay += 31;
case 1:
tolDay += day;
break;
default:
System.out.println("The data your input is invalid. ");
}
System.out.println("Today is the " + tolDay + "th days of 2021.");
( 3 ) (3) (3) switch-case 结构和if-else结构可以相互嵌套
① 代码例子:
从键盘分别输入年、月、日,判断这一天是当年的第几天?
注:判断一年是否是闰年的标准:
1)可以被4整除,但不可被100整除;
或
2)可以被400整除;
System.out.print("Please input the year: ");
int year = scan.nextInt();
System.out.print("Please input the month: ");
int month = scan.nextInt();
System.out.print("Please input the day: ");
int day = scan.nextInt();
int tolDay = 0;
switch (month) {
case 12:
tolDay += 30;
case 11:
tolDay += 31;
case 10:
tolDay += 30;
case 9:
tolDay += 31;
case 8:
tolDay += 31;
case 7:
tolDay += 30;
case 6:
tolDay += 31;
case 5:
tolDay += 30;
case 4:
tolDay += 31;
case 3:
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
tolDay += 29;
} else {
tolDay += 28;
}
case 2:
tolDay += 31;
case 1:
tolDay += day;
break;
default:
System.out.println("The data your input is invalid. ");
}
System.out.println("Today is the " + tolDay + "th days of " + year + ". ");
( 4 ) (4) (4) switch-case 结构和if-else结构可以相互转换
① 凡是可以使用switch-case的结构,都可以转换为if-else。反之,不成立。
② 写分支结构时,当发现两个结构都可以时,且case数量不多时,优先使用switch-case结构。原因:switch-case 执行效率稍高。
编写程序:从键盘上读入一个学生成绩,存放在变量score中,根据score的
值输出其对应的成绩等级:
score>=90 等级 : A
70<=score<90 等级 : B
60<=score<70 等级 : C
score<60 等级 : D
方式一:使用if-else
方式二:使用switch-case: score / 10: 0-10
//方式一:使用if-else
System.out.print("Please input the student's score(0-100): ");
int score = scan.nextInt();
if (score<=100 && score>=90){
System.out.println("Your grade is A.");
}else if (score>=70 && score <90){
System.out.println("Your grade is B.");
}else if (score>=60 && score<70){
System.out.println("Your grade is C.");
}else if (score<60 && score>=0){
System.out.println("Your grade is D.");
}else {
System.out.println("The score your input is invalid.");
}
//方式二:使用switch-case
System.out.print("Please input the student's score(0-100): ");
int score = scan.nextInt();
int score2 = score/10;
switch (score2){
case 0:
if (score%10<0){
System.out.println("The score your input is invalid.");
break;
}
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("Your grade is D.");
break;
case 6:
System.out.println("Your grade is C.");
break;
case 7:
case 8:
System.out.println("Your grade is B.");
break;
case 9:
case 10:
if (score%10>0){
System.out.println("The score your input is invalid.");
break;
}
System.out.println("Your grade is A.");
break;
default:
System.out.println("The score your input is invalid.");
}
4.2 循环结构
( 1 ) (1) (1) 循环语句的四个组成部分:
① 初始化部分 (init_statement)
② 循环条件部分 (test_exp):是Boolean类型
③ 循环体部分 (body_statement)
④ 迭代部分 (alter_statement)
4.2.1 for循环
( 1 ) (1) (1) for循环语句的四个组成部分
for(①;②;④){
③
}
①初始化条件
②循环条件:必须是Boolean类型
③循环体
④迭代条件
( 2 ) (2) (2) 例子
编写程序: 从1循环到150,并在每行打印一个值,另外在每个3的倍数行
上打印出“foo"在每个5的倍数行上打印“biz”, 在每个7的倍数行上打印输出“baz"。
for(int i=1; i<=150; i++){
System.out.print(i);
if(i%3==0){
System.out.print(" foo");
}
if (i%5==0){
System.out.print(" biz");
}
if (i%7==0){
System.out.print(" baz");
}
System.out.println("");
}
( 3 ) (3) (3) For 循环中 break 关键字的使用
题目:输入两个正整数m和n,求其最大公约数和最小公倍数。
比如12和20的最大公约数是4,最小公倍数是60 。
说明:break关键字的使用
这道题的For循环时采用逆向思维,从大的数开始递减
System.out.print("Please input a positive integer m: ");
int m = scan.nextInt();
System.out.print("Please input a positive integer n: ");
int n = scan.nextInt();
int min = 0;
if (m<n){
min = m;
}else {
min = n;
}
for (int i = min; i>=1; i--){
if (m%i==0 && n%i==0){
System.out.println("The greatest common divisor is: " + i);
int m2 = m/i;
int n2 = n/i;
System.out.println("The least common multiple is: " + (i*m2*n2));
break;
}
}
4.2.2 while循环
( 1 ) (1) (1) while循环语句的四个组成部分
①
while(②){
③;
④;
}
①初始化条件
②循环条件:必须是Boolean类型
③循环体
④迭代条件
执行过程:①-②-③-④-②-③-④-②-③-④-…②-③-④-…
注意:
- 注意不要漏写④迭代条件 ,否则程序容易陷入死循环。
- for循环和while循环是等价的,可以相互转换。
- 两种循环的不同点在于,for中的i是局部变量,而while中的i是全局变量。
4.2.3 do-while循环
( 1 ) (1) (1) do-while循环语句的四个组成部分
①
do{
③;
④;
}while(②);
①初始化条件
②循环条件:必须是Boolean类型
③循环体
④迭代条件
执行过程:①-③-④-②-③-④-②-…③-④-②-…
注意:
- do-while循环至少会执行一次循环体。
- 开发中使用for和while循环的频率更高。
4.2.4 循环次数未知
可采用while(true) 或者 for(;😉 来应对循环次数未知的情况。
此时,通过在循环体中执行break; 来跳出循环。
( 1 ) (1) (1) 题目:
从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为0时结束程序 。
import java.util.Scanner;
public class loopExercise {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int positive = 0;
int negative = 0;
while (true){
System.out.print("Please input several integer: ");
int num = scan.nextInt();
if (num>0){
positive++;
}else if (num<0){
negative++;
}else if (num==0){
break;
}
}
System.out.println("The number of positive number is: " + positive);
System.out.println("The number of negative number is: " + negative);
}
}
4.2.5 嵌套循环
( 1 ) (1) (1) 说明:
① 外层循环 j j j 控制"行数",内层循环 i i i 控制"列数"。
( 2 ) (2) (2) 题目:
使用嵌套循环输出九九乘法表。
代码:
public class nestedLoop {
public static void main(String[] args){
/*
使用嵌套循环输出九九乘法表。
1*1=1
1*2=2 2*2=4
......
*/
for (int i=1; i<=9; i++){
for (int j=1; j<=i; j++){
System.out.print(j+"×"+i+"="+(i*j)+"\t");
}
System.out.println();
}
}
}