三、流程控制语句
流程控制对于任何一门编程语言来说都是至关重要的,它提供了控制程序步骤的基本手段。如果没有流程控制语句,整个程序将按照线性的顺序来执行,不能根据用户的输入决定执行的序列。
1.顺序结构
Java程序是从上到下逐行执行语句,中间没有任何判断和跳转。
2.分支结构(选择语句)
- 根据条件,选择性地执行某段代码。
- 有
if…else
和switch-case
两种分支语句。
2.1 if……else
2.1.1 基本语法
-
单分支条件判断:if
-
格式:
if(条件表达式){ 代码块; //如果条件表达式的值为true,将执行这部分语句 }
-
说明: 条件表达式必须是布尔表达式(关系表达式或逻辑表达式)或布尔变量。
-
执行流程:
-
首先判断条件表达式的结果是true还是false;
-
如果是true就执行代码块;
-
如果是false就不执行代码块;
-
-
-
双分支条件判断:if……else
-
格式:
if(布尔表达式){ 代码块1; //如果布尔表达式的值为true,执行代码块1 }else{ 代码块2; //如果布尔表达式的值为false,执行代码块2 }
-
执行流程:
- 首先判断条件表达式看其结果是true还是false
- 如果是true就执行代码块1
- 如果是false就执行代码块2
-
-
多分支条件判断:**if……else if……else if **
-
格式:
if(布尔表达式 1){ //如果布尔表达式 1的值为true执行代码 }else if(布尔表达式 2){ //如果布尔表达式 2的值为true执行代码 }else if(布尔表达式 3){ //如果布尔表达式 3的值为true执行代码 } …… else { //如果以上布尔表达式都不为true执行代码 }
-
说明:
- if 语句至多有 1 个 else 语句,else 语句在所有的 else if 语句之后。
- if 语句可以有若干个 else if 语句,它们必须在 else 语句之前。
- 一旦其中一个 else if 语句检测为 true,其他的 else if 以及 else 语句都将跳过执行。
- 如果没有任何关系表达式为true,就执行else中的语句块,然后结束当前多分支。
-
2.1.2 应用举例
案例1:成年人心率的正常范围是每分钟60-100次。体检时,如果心率不在此范围内,则提示需要做进一步的检查。
int heartRate = 120; //声明心跳次数变量并赋值
//单分支条件判断:if的练习使用
if(heartRate >= 60 || heartRate <= 100) {
System.out.println("心率不正常,需要做进一步的检查");
}
System.out.println("检测结束");
案例2:定义一个整数,判定是偶数还是奇数
public class IfElseExer02 {
public static void main(String[] args) {
int a = 2;//定义一个整数变量a,并赋值为2
//使用if……else,判断一个整数的奇偶
if(a % 2 == 0) {
System.out.println("a是偶数");
}else {
System.out.println("a是奇数");
}
}
}
案例3:
岳小鹏参加Java考试,他和父亲岳不群达成承诺。如果:成绩为100分时,奖励一辆跑车;成绩为(80,99]时,奖励一辆山地自行车;当成绩为[60,80]时,奖励环球影城一日游;其它时,胖揍一顿。
说明:默认成绩是在[0,100]范围内
public class IfElseExer03 {
public static void main(String[] args) {
int grade = 66; //声明成绩变量,并赋值为66
//使用多分支条件判断:if……else if……else来完成案例3
if(grade == 100) {
System.out.println("奖励一辆跑车");
}else if(grade >80 && grade <= 99) {
System.out.println("奖励一辆山地自行车");
}else if(grade >= 60 && grade <= 80) {
System.out.println("奖励环球影城一日游");
}else {
System.out.println("胖揍一顿");
}
}
}
2.1.3 if……else嵌套
在 if 的语句块中,或者是在else语句块中,又包含了另外一个条件判断(可以是单分支、双分支、多分支),就构成了嵌套结构
。
执行的特点:
(1)如果是嵌套在if语句块中的,只有当外部的if条件满足,才会去判断内部的条件
(2)如果是嵌套在else语句块中的,只有当外部的if条件不满足,进入else后,才会去判断内部的条件
if(布尔表达式 1){
//如果布尔表达式 1的值为true执行代码
if(布尔表达式 2){
//如果布尔表达式 2的值为true执行代码
}
}
//if……else嵌套的小练习
public class IfElseExer04 {
public static void main(String[] args) {
int x = 30;
int y = 10;
if(x == 30) {
if(y == 10) {
System.out.println("X = 30 "+"Y = 10");
}
}
}
}
if……else嵌套语句的案例小练习:
/*
由键盘输入三个整数分别存入变量num1、num2、num3,对它们进行排序(使用 if-else if-else),并且从小到大输出。
*/
public class IfElseExer05 {
public static void main(String[] args) {
//使用Scanner类接收三个整数并分别赋值给变量num1、num2、num3
System.out.println("请输入3个整数:");
Scanner sc = new Scanner(System.in);
int num1 = sc.nextInt();
int num2 = sc.nextInt();
int num3 = sc.nextInt();
//使用if……else嵌套语句实现判断输入的三个整数大小,并按从小到大的排序打印
if(num2 >= num1) {
if(num3 >= num2) {
System.out.println(num1+"<"+num2+"<"+num3);
}else if(num3 <= num1) {
System.out.println(num3+"<"+num1+"<"+num2);
}else {
System.out.println(num2+"<"+num3+"<"+num1);
}
}else { //num2 <= num1
if(num3 >= num1) {
System.out.println(num2+"<"+num1+"<"+num3);
}else if(num3 <= num2) {
System.out.println(num3+"<"+num2+"<"+num1);
}else {
System.out.println(num2+"<"+num3+"<"+num1);
}
}
sc.close();
}
}
2.2 switch-case分支(选择)结构
2.2.1 基本语法
-
语法格式
switch(expression) { case value : //执行语句1 break; //可选 case value : //执行语句2 break; //可选 …… //你可以有任意数量的case语句 default : //可选 //语句 }
-
执行流程图:
-
执行过程:
-
根据switch中表达式的值,依次匹配各个case。如果表达式的值等于某个case中的常量值,则执行对应case中的执行语句。
-
执行完此case的执行语句以后,
-如果遇到break,则执行break并跳出当前的switch-case结构
-如果没有遇到break,则会继续执行当前case之后的其它case中的执行语句。--->case穿透...
-直到遇到break关键字或执行完所有的case及default的执行语句,跳出当前的switch-case结构。
-
-
switch-case语句的使用有如下规则:
- switch 语句中的变量类型是: byte、short、int 、char。从 Java SE 7 开始,switch 支持字符串 String 类型了,同时 case 标签必须为字符串常量或字面量。
- switch 语句可以拥有多个 case 语句。每个 case 后面跟一个要比较的值和冒号。
- case 语句中的值的数据类型必须与变量的数据类型相同,而且只能是常量或者字面常量。
- 当变量的值与 case 语句的值相等时,那么 case 语句之后的语句开始执行,直到 break 语句出现才会跳出 switch 语句。
- 当遇到 break 语句时,switch 语句终止。程序跳转到 switch 语句后面的语句执行。case 语句不必须要包含 break 语句。如果没有 break 语句出现,程序会继续执行下一条 case 语句,直到出现 break 语句。
- switch 语句可以包含一个 default 分支,该分支一般是 switch 语句的最后一个分支(可以在任何位置,但建议在最后一个)。default 在没有 case 语句的值和变量值相等的时候执行。default 分支不需要 break 语句。
2.2.2 应用举例
public class Test {
public static void main(String args[]){
char grade = 'C';
switch(grade) {
case 'A' :
System.out.println("优秀");
break;
case 'B' :
case 'C' :
System.out.println("良好");
break;
case 'D' :
System.out.println("及格");
break;
case 'F' :
System.out.println("差");
break;
default :
System.out.println("成绩等级错误");
}
System.out.println("你的等级是 " + grade);
}
}
案例:
使用switch-case实现对学生成绩大于60分的,输出“合格”。低于60分的,输出“不合格”。
public class SwitchCaseExer03 {
public static void main(String[] args) {
int grade = 61; //声明成绩变量,并赋值为61
//使用switch-case分支语句实现案例3
switch (grade / 60) {
case 0:
System.out.println("成绩不合格");
break;
case 1:
System.out.println("及格");
break;
default:
System.out.println("成绩格式错误");
}
}
}
2.2.3 switch-case中的case穿透特性
在switch语句中,如果case的后面不写break,将出现穿透现象,也就是一旦匹配成功,不会在判断下一个case的值,直接向后运行,直到遇到break或者default或者运行完所有case才终止,执行终止。
我们可以利用这个特性实现某些功能,或者解决某些问题。
案例:编写程序:从键盘上输入2023年的“month”和“day”,要求通过程序输出输入的日期为2023年的第几天。
public class SwitchCaseExer04 {
public static void main(String[] args) {
//使用Scanner,从键盘接收2023年的月、日
Scanner scan = new Scanner(System.in);
System.out.println("请输入当前月份:");
int month = scan.nextInt(); //阻塞式方法
System.out.println("请输入日期:");
int day = scan.nextInt();
int sumDays = 0; //记录总天数
//使用switch-case分支语句实现,通过程序输出输入的日期为2023年的第几天
switch(month) {
case 1:
sumDays = day;
break;
case 2:
sumDays = day +30;
break;
case 3:
sumDays = day + 30+ 28;
break;
case 4:
sumDays = day + 30 + 28 + 31;
break;
case 5:
sumDays = day + 30 + 28 + 31 + 30;
break;
case 6:
sumDays = day + 30 + 28 + 31 + 30 + 31;
break;
case 7:
sumDays = day + 30 + 28 + 31 + 30 + 31 + 30;
break;
case 8:
sumDays = day + 30 + 28 + 31 + 30 + 31 + 30 + 31;
break;
case 9:
sumDays = day + 30 + 28 + 31 + 30 + 31 + 30 + 31 + 31;
break;
case 10:
sumDays = day + 30 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30;
break;
case 11:
sumDays = day + 30 + 28 + 31 + 30 + 31 + 30 + 31 + 31+ 30 + 31;
break;
case 12:
sumDays = day + 30 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30;
break;
}
System.out.println("当前日期为:2023年"+month+"月"+day+"日"+",日期为2023年的第"+sumDays+"天");
scan.close();
}
}
上面例子我们可知代码中重复写了很多边遍相同的数据,数据冗余。我们可以利用case的穿透性解决这个问题如下:
public class SwitchCaseExer05 {
public static void main(String[] args) {
//使用Scanner,从键盘接收2023年的月、日
Scanner scan = new Scanner(System.in);
System.out.println("请输入当前月份:");
int month = scan.nextInt(); //阻塞式方法
System.out.println("请输入日期:");
int day = scan.nextInt();
int sumDays = 0; //记录总天数
//使用switch-case分支语句实现,通过程序输出输入的日期为2023年的第几天,利用了case穿透性
switch(month) {
case 12:
sumDays += 30;//这个30是代表11月份的满月天数
case 11:
sumDays += 31;//这个31是代表10月份的满月天数
case 10:
sumDays += 30;//这个30是代表9月份的满月天数
case 9:
sumDays += 31;//这个31是代表8月份的满月天数
case 8:
sumDays += 31;//这个31是代表7月份的满月天数
case 7:
sumDays += 30;//这个30是代表6月份的满月天数
case 6:
sumDays += 31;//这个31是代表5月份的满月天数
case 5:
sumDays += 30;//这个30是代表4月份的满月天数
case 4:
sumDays += 31;//这个31是代表3月份的满月天数
case 3:
sumDays += 28;//这个28是代表2月份的满月天数
case 2:
sumDays += 31;//这个31是代表1月份的满月天数
case 1:
sumDays += day;//这个day是代表当月的第几天
}
System.out.println("当前日期为:2023年"+month+"月"+day+"日"+",日期为2023年的第"+sumDays+"天");
scan.close();
}
}
3.循环结构(循环语句)
- 根据循环条件,重复性的执行某段代码。
- 有
for
、while
、do-while
三种循环语句。 - 根据循环条件,重复性的执行某段代码。
- 有
for
、while
、do-while
三种循环语句。 - 补充:JDK5.0 提供了
foreach
循环,方便的遍历集合、数组元素。 - 循环结构的四个要素:
- 初始化条件
- 循环条件
- 循环体
- 迭代部分
3.1 while循环
3.1.1 基本语法
语法格式:
初始化部分
while(条件表达式) {
循环体;
迭代语句;
}
说明:
- while(循环条件)中循环条件必须是boolean类型;
- 注意不要忘记声明迭代部分。否则,循环将不能结束,变成死循环。
- for循环与while循环的区别:初始化条件部分的作用域不同。
3.1.2 应用举例
案例1:计算1~1000的相加结果
public class WhileExer02 {
public static void main(String[] args) {
//使用while循环计算1到1000的相加结果
int i = 1;
int sum = 0;
while(i <= 1000) {
sum += i;
i++;
}
System.out.println("1~1000的相加结果为:"+sum);
}
}
案例2:遍历1-100的偶数,并计算所有偶数的和、偶数的个数(累加的思想)
public class WhileExer03 {
public static void main(String[] args) {
int i = 1;
int sum = 0; //声明变量sum,用于存储所有的偶数和,并初始化值为0
int count = 0; //声明变量count,用于存储偶数的个数,并初始化为0
//使用while循环,实现1~100的偶数遍历,并计算所有偶数的和以及偶数的个数
while(i <= 100) {
if(i % 2 == 0){
System.out.println(i);
sum += i;
count++;
}
i++;
}
System.out.println("所有偶数的和为:"+sum+'\n'+"偶数的个数为:"+count);
}
}
3.3 do……while循环
3.3.1 基本语法
语法格式:
do {
循环体语句;
迭代语句;
}while(条件表达式);
说明:
- 结尾while(循环条件)中循环条件必须是boolean类型;
- do{}while();最后有一个分号;
- do-while结构的循环体语句是至少会执行一次,这个和for和while是不一样的;
- do……while语句和while语句的区别:
- while循环语句是先判断条件是否成立再执行循环体;
- do……while是先执行一次循环体后,再判断条件是否成立,也就是说do……while语句”{}“中的程序段至少要执行一次。
3.3.2 应用举例
案例1:遍历1-100的偶数,并计算所有偶数的和、偶数的个数(累加的思想)
public class DoWhileExer {
public static void main(String[] args) {
int i = 1;
int sum = 0; //存偶数的和
int count = 0; //存偶数的个数
//使用do……while循环语句实现遍历1-100的偶数,并计算所有偶数的和、偶数的个数(累加的思想)
do {
if(i % 2 == 0){
System.out.println(i);
sum += i;
count++;
}
i++;
}while(i <= 100);
System.out.println("sum = "+sum);
System.out.println("count = "+count);
}
}
3.4 for循环
3.4.1 基本语法
for(表达式1;表达式2;表达式3) {
循环体;
}
表达式1:初始化表达式,负责完成变量的初始化;
表达式2:循环条件表达式,值为boolean型表达式,指定循环条件。等同于while循环()里的表达式;
表达式3:每次循环结束后执行的语句,通常用来改变循环条件,迭代部分;
3.4.2 应用举例
案例1:使用for循环重复执行某些语句
题目:输出5行HelloWorld
public class ForExer01 {
public static void main(String[] args) {
int i; //声明变量i,用于存储for循环中的初始化表达式的值
//使用for循环语句打印五次HelloWorld!
for(i = 1 ; i <= 5;i++) {
System.out.println("HelloWorld!");
}
}
}
案例2:利用输出语句学习for循环语句的执行过程
public class ForExer02 {
public static void main(String[] args) {
int num = 1;
for(System.out.print("a"); num < 4; System.out.println("b"),num++) {
System.out.print("c");
}
System.out.println(); //换行
System.out.println("num = "+num);
}
}
总结:从运行结果我们可知这个例子中的for循环执行过程是:表达式1-->>表达式2(值为true)-->>循环体-->>表达式3-->>表达式2(true)-->>循环体-->>表达式3-->>表达式2(true)-->>循环体-->>表达式3-->>表达式2(false)-->>for循环结束。
案例3:使用for循环计算2~100以内所有的偶数的和
public class ForExer06 {
public static void main(String[] args) {
int sum = 0; //存偶数相加的和
for(int i = 2; i <= 100; i += 2){
sum += i;
}
System.out.println("所有偶数的和为:"+sum);
}
}
3.5 循环控制
循环控制包含两方面的内容,一方面是控制循环变量的变化方式,另一方面是控制循环的跳转。
控制循环的跳转需要用到break和continue两个关键字,这两条跳转语句的跳转效果不同,break语句是中断循环,continue语句是跳过此次循环执行下一次循环。
3.5.1 break
使用break语句可以跳出switch……case结构。在循环结构中,同样可以用break语句跳出当前循环体,从而中断当前循环。
//输出1~20出现的第一个偶数
//for循环使用break语句跳出循环
public class BreakExer01 {
public static void main(String[] args) {
for(int i = 1; i <=20; i++) {
if(i % 2 == 0) {
System.out.println("1~20出现的第一个偶数:"+i);
break;
}
}
}
}
3.5.2 continue
continue语句是针对break语句的补充。continue不是立即跳出循环体,而是跳过本次循环,回到循环的条件判断部分,重新开始执行循环。在for循环中遇到continue后,首先执行循环的增量部分。然后进行条件判断。在while和do……while循环中,continue语句使控制直接回到条件判断部分。
// 编写一个for循环从1循环至20,如果当前循环的次数为偶数,则使用continue语句跳过循环
public class Continue01 {
public static void main(String[] args) {
for(int i = 1; i <= 20; i++) {
if(i % 2 == 0) {
continue;
}
System.out.println(i);
}
}
}