在一个程序执行的过程中,各条语句的执行顺序对程序的结果是有直接影响的。所以,我们必须清楚每条语句的执行流程。而且,很多时候要通过控制语句的执行顺序来实现我们想要的功能。 java中流程控制语句分类:顺序结构丶分支结构(if, switch)丶循环结构(for, while, do…while)。
顺序结构
任何编程语言中最常见的程序结构就是顺序结构。顺序结构就是程序从上到下逐行地执行,中间没有任何判断和跳转。如果main方法的多行代码之间没有任何流程控制,则程序总是从上向下依次执行,排在前面的代码先执行,排在后面的代码后执行。
代码示例
public class Demo01Sequence {
public static void main(String[] args) {
//顺序执行,根据编写的顺序,从上到下运行
System.out.println(1);
System.out.println(2);
System.out.println(3);
}
}
if分支语句
if语句第一种格式: if
执行流程:
- 首先计算关系表达式的值
- 如果关系表达式的值为true就执行语句体
- 如果关系表达式的值为false就不执行语句体
- 继续执行后面的语句内容
代码示例
import java.util.Scanner;
/*
案例:从键盘输入年份,请输出该年的2月份的总天数。闰年2月份29天,平年28天。
闰年:
(1)能被4整除,不能被100整除
(2)能被400整除
*/
public class Demo02If {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入年份:");
int year = input.nextInt();
int days = 28;
//条件表达式
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
// 条件表达式是true执行
days++;
}
//if 之后的代码
System.out.println(year + "年的2月份共" + days + "天");
input.close();
}
}
if语句第二种格式: if...else
执行流程
- 首先判断关系表达式看其结果是true还是false
- 如果是true就执行语句体1
- 如果是false就执行语句体2
- 继续执行后面的语句内容
代码示例
public class Demo03If {
//求2个数的最大值
public static void main(String[] args) {
int a = 10;
int b = 20;
//定义变量,保存a和b的较大值
int max;
if (a > b) {
max = a;
} else {
max = b;
}
System.out.println("最大值:" + max); //最大值:20
//可以上述功能改写为三元运算符形式
max = a > b ? a : b;
System.out.println("最大值:" + max); //最大值:20
}
}
if语句第三种格式: if...else if ...else
执行流程
- 首先判断关系表达式1看其结果是true还是false
- 如果是true就执行语句体1,然后结束当前多分支
- 如果是false就继续判断关系表达式2看其结果是true还是false
- 如果是true就执行语句体2,然后结束当前多分支
- 如果是false就继续判断关系表达式…看其结果是true还是false
- …
- 如果没有任何关系表达式为true,就执行语句体n+1,然后结束当前多分支。
代码示例
/*
通过指定考试成绩,判断学生等级
- 90-100 优秀
- 80-89 好
- 70-79 良
- 60-69 及格
- 60以下 不及格
*/
public class Demo04If {
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("你的成绩属于不及格");
}
}
}
注意事项:
- 如果if语句所控制的语句体, 是一条语句, 大括可以省略不写但是不建议!
分支结构:if..else嵌套
在if的语句块中,或者是在else语句块中, 又包含了另外一个条件判断(可以是单分支、双分支、多分支)
执行的特点:
- 如果是嵌套在if语句块中的 只有当外部的if条件满足,才会去判断内部的条件
- 如果是嵌套在else语句块中的 只有当外部的if条件不满足,进入else后,才会去判断内部的条件
代码示例
/*
从键盘输入一个年份,和月份,输出该年份该月的总天数
要求:年份为正数,月份1-12
*/
public class Demo05Test {
public static void main(String[] args) {
//从键盘输入一个年份,和月份
java.util.Scanner input = new java.util.Scanner(System.in);
System.out.print("年份:");
int year = input.nextInt();
System.out.print("月份:");
int month = input.nextInt();
if (year > 0) {
if (month >= 1 && month <= 12) {
//合法的情况
int days;
if (month == 2) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
days = 29;
} else {
days = 28;
}
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
days = 30;
} else {
days = 31;
}
System.out.println(year + "年" + month + "月有" + days + "天");
} else {
System.out.println("月份输入不合法");
}
} else {
System.out.println("年份输入不合法");
}
}
}
switch分支语句
执行过程:
- 首先计算出表达式的值
- 其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结 束。
- 最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉。
代码示例
/*
需求:键盘录入星期数,显示今天的减肥活动。
周一:跑步
周二:游泳
周三:慢走
周四:动感单车
周五:拳击
周六:爬山
周日:好好吃一顿
分析:
1. 键盘录入星期数据,使用变量接收
2. 多情况判断,采用switch语句实现
3. 在不同的case中,输出对应的减肥计划
*/
import java.util.Scanner;
public class Demo06Switch {
public static void main(String[] args) {
// 1. 键盘录入星期数据,使用变量接收
Scanner sc = new Scanner(System.in);
System.out.println("请输入");
int week = sc.nextInt();
// 2. 多情况判断,采用switch语句实现
switch (week) {
// 3. 在不同的case中,输出对应的减肥计划
case 1:
System.out.println("跑步");
break;
case 2:
System.out.println("游泳");
break;
case 3:
System.out.println("慢走");
break;
case 4:
System.out.println("动感单车");
break;
case 5:
System.out.println("拳击");
break;
case 6:
System.out.println("爬山");
break;
case 7:
System.out.println("好好吃一顿");
break;
default:
System.out.println("您的输入有误");
break;
}
}
}
注意事项:
- switch(表达式)的值的类型,只能是:4种基本数据类型(byte,short,int,char),两种引用数据类型(JDK1.5之后枚举、JDK1.7之后String)
- case后面必须是常量值,而且不能重复
case的穿透性:在switch语句中,如果case的后面不写break,将出现穿透现象,也就是一旦匹配成功,不会在判断下一个case的值,直接向后运行,直到遇到break或者整个switch语句结束,switch语句执行终止。
代码示例
import java.util.Scanner;
/*
需求: 键盘录入星期数,输出工作日、休息日
(1-5)工作日,(6-7)休息日
case穿透是如何产生的?
如果switch语句中,case省略了break语句, 就会开始case穿透.
现象:
当开始case穿透,后续的case就不会具有匹配效果,内部的语句都会执行
直到看见break,或者将整体switch语句执行完毕,才会结束。
*/
public class Demo07Switch {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入星期数:");
int week = sc.nextInt();
switch (week) {
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("工作日");
break;
case 6:
case 7:
System.out.println("休息日");
break;
default:
System.out.println("您的输入有误");
break;
}
}
}
循环概述
循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句,当反复 执行这个循环体时,需要在合适的时候把循环判断条件修改为false,从而结束循环,否则循环将一直执行下去,形成死循环。循环的一般情况下由下面四部分组成:
- 初始化语句: 用于表示循环开启时的起始状态,简单说就是循环开始的时候什么样
- 条件判断语句:用于表示循环反复执行的条件,简单说就是判断循环是否能一直执行下去
- 循环体语句: 用于表示循环反复执行的内容,简单说就是循环反复执行的事情
- 条件控制语句:用于表示循环执行中每次变化的内容,简单说就是控制循环是否能执行下去
for循环
执行流程:
- 执行初始化语句
- 执行条件判断语句,看其结果是true还是false。如果是false,循环结束。如果是true,继续执行
- 执行循环体语句
- 执行条件控制语句
- 回到②继续
代码示例
//需求:在控制台输出所有的“水仙花数”,要求每行打印2个
public class Demo08For {
public static void main(String[] args) {
// 1. 定义变量count,用于保存“打印过”的数量,初始值为0
int count = 0;
for (int i = 100; i <= 999; i++) {
int ge = i % 10;
int shi = i / 10 % 10;
int bai = i / 10 / 10 % 10;
if ((ge * ge * ge + shi * shi * shi + bai * bai * bai) == i) {
// 2. 在判定和打印水仙花数的过程中,拼接空格, 但不换行,并在打印后让count变量+1,记录打印过的数量
System.out.print(i + " ");
count++;
// 3. 在每一次count变量+1后,判断是否到达了2的倍数,是的话,换行
if (count % 2 == 0) {
System.out.println();
}
}
}
}
}
while循环
执行流程:
- 执行初始化语句①,完成循环变量的初始化;
- 执行循环条件语句②,看循环条件语句的值是true,还是false。如果是true,执行第三步。如果是false,循环语句中止,循环不再执行。
- 执行循环体语句③
- 执行迭代语句④,针对循环变量重新赋值
- 根据循环变量的新值,重新从第二步开始再执行一遍
代码示例
/*
需求:世界最高山峰是珠穆朗玛峰(8844.43米=8844430毫米),
假如我有一张足够大的纸,它的厚度是0.1毫米。请问,我折叠多少次,可以折成珠穆朗玛峰的高度?
*/
public class Demo09While {
public static void main(String[] args) {
//定义一个计数器,初始值为0
int count = 0;
//定义纸张厚度
double paper = 0.1;
//定义珠穆朗玛峰的高度
int zf = 8844430;
//因为要反复折叠,所以要使用循环,但是不知道折叠多少次,这种情况下更适合使用while循环
//折叠的过程中当纸张厚度大于珠峰就停止了,因此继续执行的要求是纸张厚度小于珠峰高度
while (paper <= zf) {
//循环的执行过程中每次纸张折叠,纸张的厚度要加倍
paper *= 2;
//在循环中执行累加,对应折叠了多少次
count++;
}
//打印计数器的值
System.out.println("需要折叠:" + count + "次");
}
}
do...while循环
执行流程:
- 执行初始化语句①,完成循环变量的初始化;
- 执行循环体语句②;
- 执行迭代语句③,针对循环变量重新赋值;
- 执行循环条件语句④,看循环条件语句的值是true,还是false。如果是true,根据循环变量的新值,重新从第二步开始再执行一遍。如果是false,循环语句中止,循环不再执行。
代码示例
import java.util.Scanner;
public class Demo10DoWhile {
public static void main(String[] args) {
/*
输入密码和确认密码,如果两次密码一致则显示注册成功,两次密码不一致则提示重新输入
*/
Scanner input = new Scanner(System.in);
String pwdOne = "";
String pwdTwo = "";
do {
System.out.println("请输入密码");
pwdOne = input.next();
System.out.println("请输入确认密码");
pwdTwo = input.next();
if (!pwdOne.equals(pwdTwo)) {
System.out.println("两次密码不一致,请重新输入");
}
} while (!pwdOne.equals(pwdTwo));
System.out.println("注册成功");
}
}
三种循环语句的区别
从循环次数角度分析
- do...while循环至少执行一次循环体语句
- for和while循环先循环条件语句是否成立,然后决定是否执行循环体,至少执行零次循环体语句
从循环变量的生命周期角度分析
- for循环的循环变量在for()中声明的,在循环语句结束后,不可以被访问;
- while和do...while循环的循环变量因为在外面声明的,所以while和do...while结束后可以被继续使用的;
如何选择
- 遍历有明显的循环次数(范围)的需求,选择for循环
- 遍历没有明显的循环次数(范围)的需求,循环while循环
- 如果循环体语句块至少执行一次,可以考虑使用do...while循环
- 本质上:三种循环之间是可以互相转换的,都能实现循环的功能
死循环(无限循环)的三种格式
注意:永远无法访问的语句是不能编写的
循环嵌套
所谓嵌套循环,是指一个循环的循环体是另一个循环。比如for循环里面还有一个for循环,就是嵌套循环。总共的循环次数=外循环次数*内循环次数。当然可以是三种循环任意互相嵌套。一般情况我们使用下面这种嵌套循环格式:
执行顺序
- 执行最外层初始化语句
- 判断最外层循环条件,若满足条件则进入第一层循环体
- 进入第一层循环体后再次遇到循环语句。先执行内存初始化语句,进行第二层循环条件判断,若符合判断条件,进入第二层循环体
- 若有更多层的循环体嵌套,依照上述方法依次判断是否进入循环体
- 执行完第一次内循环体操作后,进行内循环体变量累加,再次执行内循环体操作,直到不满足进入内循环体条件
- 执行外循迭代语句
- 在第一次外循环体操作完成后,回到步骤2,判断是否满足进入外循环体条件,若符合,再次依次执行上述步骤,直到不满足进入外循环体条件
- 彻底退出嵌套循环操作
代码示例
public class Demo14Test {
//打印九九乘法表
public static void main(String[] args) {
// 循环9次
for (int a = 1; a <= 9; a++) {
for (int b = 1; b <= a; b++) {
System.out.print(a + "*" + b + "=" + (a * b) + "\t"); // t相当于空格
}
// 换行
System.out.println();
}
}
}
跳出控制语句(break丶continue )
break:只能在switch或者循环中使用,作用:跳出循环,结束循环
代码示例
public class Demo11Break {
//从键盘输入不断输入整数,输入0表示结束,统计一共有几个正数、负数。
public static void main(String[] args) {
java.util.Scanner input = new java.util.Scanner(System.in);
int positive = 0;
int negative = 0;
while (true) {
System.out.print("请输入整数(0)结束:");
int num = input.nextInt();
if (num == 0) {
break;
} else if (num > 0) {
positive++;
} else {
negative++;
}
}
System.out.println("正数:" + positive + ",负数:" + negative);
}
}
continue:continue只能在循环中进行使用!作用:跳过本次循环,继续下次循环
代码示例
public class Demo12Continue {
public static void main(String[] args) {
//打印1-100之间的整数,跳过7的倍数和7结尾的数
for (int i = 1; i <= 100; i++) {
if (i % 7 == 0 || i % 10 == 7) {
continue;
}
System.out.println(i);
}
}
}
我们可以使用标号跳出指定的循环
import java.util.Scanner;
public class Demo13Test {
/*
需求:程序运行后,用户可多次查询星期对应的减肥计划,直到输入0,程序结束
*/
public static void main(String[] args) {
lo:while (true) {
System.out.println("请输入您要查看的星期数:");
System.out.println("(如无需继续查看,请输入0退出程序)");
// 1. 键盘录入星期数据,使用变量接收
Scanner sc = new Scanner(System.in);
int week = sc.nextInt();
// 2. 多情况判断,采用switch语句实现
switch (week) {
// 3. 在不同的case中,输出对应的减肥计划
case 0:
System.out.println("感谢您的使用");
break lo;//跳出标号lo指定的循环
case 1:
System.out.println("跑步");
break;
case 2:
System.out.println("游泳");
break;
case 3:
System.out.println("慢走");
break;
case 4:
System.out.println("动感单车");
break;
case 5:
System.out.println("拳击");
break;
case 6:
System.out.println("爬山");
break;
case 7:
System.out.println("好好吃一顿");
break;
default:
System.out.println("您的输入有误");
break;
}
}
}
}