程序流程控制(Java)
文章目录
程序执行的几种常见形式
分支结构
if
if 分支
- 根据判定的结果(真或假)决定执行某个分支的代码
if 分支的作用
- 判断心跳是否正常
- 判断是否有足够的余额转红包
if 分支有三种格式
if 第一种格式
执行流程
- 首先判断条件表达式的结果,如果为 true 执行语句体,为 false 就不执行语句体。
注意事项
- if 语句中,如果大括号控制的只有一行代码,则大括号可以省略不写。
if 第二种格式
执行流程
- 首先判断条件表达式的结果,如果为 true 执行语句体1,为 false 就执行语句体2。
if 第三种格式
执行流程
- 先判断条件1的值,如果为 true 则执行语句体1,分支结束;如果为 false 则判断条件2的值
- 如果值为 true 就执行语句体2,分支结束;如果为 false 则判断条件3的值
- …
- 如果没有任何条件为 true,就执行 else 分支的语句体 n+1。
switch 分支
switch 分支
- 也是匹配条件去执行分支,==适合做值匹配的分支选择,结构清晰,格式良好**
执行流程
- 先执行表达式的值,拿着这个值去与 case 后的值进行匹配。
- 匹配哪个 case 的值为 true 就执行哪个 case,遇到break就跳出 switch 分支。
- 如果 case 后的值都不匹配则执行 default 代码。
switch 案例
- 周一:埋头苦干,解决bug
- 周二:请求大牛程序员帮忙
- 周三:今晚啤酒、龙虾、小烧烤
- 周四:主动帮助新来的女程序员解决 bug
- 周五:今晚吃鸡
- 周六:与王婆介绍的小芳相亲
- 周天:郁郁寡欢、准备上班。
// 周一:埋头苦干,解决bug
// 周二:请求大牛程序员帮忙
// 周三:今晚啤酒、龙虾、小烧烤
// 周四:主动帮助新来的女程序员解决 bug
// 周五:今晚吃鸡
// 周六:与王婆介绍的小芳相亲
// 周天:郁郁寡欢、准备上班。
String weekday = "周三";
switch (weekday){
case "周一":
System.out.println("埋头苦干,解决 bug");
break;
case "周二":
System.out.println("请求大牛程序员帮忙");
break;
case "周三":
System.out.println("今晚啤酒、龙虾、小烧烤");
break;
case "周四":
System.out.println("主动帮助新来的女程序员解决 bug");
break;
case "周五":
System.out.println("今晚吃鸡");
break;
case "周六":
System.out.println("与王婆介绍的小芳相亲");
break;
case "周天":
System.out.println("郁郁寡欢、准备上班");
break;
default:
System.out.println("数据有误!");
}
- if、switch 分支各自适合做什么业务场景?
- if 其实在功能上远远强大与 switch。
- if 适合做:区间匹配。
- switch 适合做:值匹配的分支选择、代码优雅。
switch 的注意事项
switch 分支注意事项:
- 表达式类型只能是 byte、short、int、char,JDK5 开始支持枚举,JDK7 开始支持 String、不支持 double、float、long。
- case 给出的值不允许重复,且只能是字面量,不能是变量。
- 不要忘记写 break,否则会出现穿透现象。
switch 的穿透性
switch 的穿透性
- 如果代码执行到没有写 break 的 case 块,执行完后将直接进入下一个 case 块执行代码(而且不会进行任何匹配),直到遇到 break 才跳出分支,这就是 switch 的穿透性。
switch 穿透性案例(月份天数查看器)
// 需求:用户输入月份可以展示该月份的天数。
// 1、3、5、7、8、10、12月份是31天
// 2月份闰年是29天、非闰年是28天。
// 4、6、9、11月分是30天
int month = 7;
switch (month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
System.out.println(month + "月是31天!");
break;
case 2:
System.out.println(month + "月闰年为29天、非闰年为28天!");
break;
case 4:
case 6:
case 9:
case 11:
System.out.println(month + "月是30天!");
break;
default:
System.out.println("数据有误!");
}
- 什么情况下会出现 switch 穿透现象?
- case 中没有写 break。
- switch 穿透性能解决什么问题?
- 存在多个 case 分支的功能代码是一样时,可以用穿透性把流程集中到同一处处理,这样可以简化代码。
循环结构
for 循环
for 循环
- 控制一段代码反复执行很多次。
for 循环案例详细流程说明
// 输出3次 HelloWorld
for (int i = 0; i < 3; i++){
System.out.println("Hello World");
}
执行的流程:
- 循环一开始,执行 int i = 0 一次
- 然后判断循环条件:0 < 3 返回 true,进入到循环体中执行输出:Hello World,然后执行迭代语句 i++,此时 i=1 了。
- 然后判断循环条件:1 < 3 返回 true,进入到循环体中执行输出:Hello World,然后执行迭代语句 i++,此时 i=2 了。
- 然后判断循环语句:2 < 3 返回 true,进入到循环体中执行输出:Hello World,然后执行迭代语句 i++,此时 i=3 了。
- 然后判断循环条件:3 < 3 返回 false,循环立即结束!
// 目标:学会使用 for 循环,并理解它的执行流程。
// 需求:输出3次 HelloWorld
for (int i = 0; i < 3; i++){
System.out.println("Hello World");
}
System.out.println("-------------------");
for (int i = 0; i < 5; i++){
System.out.println("Hello World");
}
System.out.println("-------------------");
for (int i = 1; i < 5; i++){
System.out.println("Hello World");
}
System.out.println("-------------------");
for (int i = 1; i <= 5; i++){
System.out.println("Hello World");
}
System.out.println("-------------------");
for (int i = 1; i <= 5; i+=2){
System.out.println("Hello World");
}
for 循环案例1
案例:求和
需求:求 1-5 之间的数据和,并把求和结果在控制台输出。
分析
- 定义 for 循环,使其能够产生:1、2、3、4、5。
- 在循环外定义一个整数变量 sum 用于求和,循环每产生一个数,就累加到 sum 中去
- 循环结束后,输出求和变量即是结果。
// 需求:计算1-5的和
// 1. 定义一个整数变量用于累加数据求和
int sum = 0;
// 2. 定义一个 for 循环找到 1 2 3 4 5
for (int i = 1; i <= 5; i++){
// i = 1 2 3 4 5
// 3. 把循环的数据累加给 sum 变量
/**
等价于:sum = sum + i
i == 1 sum = 0 + 1
i == 2 sum = 1 + 2
i == 3 sum = 3 + 3
i == 4 sum = 6 + 4
i == 5 sum = 10 + 5
*/
sum += i;
}
System.out.println("1-5的和是:" + sum);
如何实现元素求 1-5 的和?
- 使用循环控制输出 1-5
for (int i = 1; i <= 5; i++) { }
- 在循坏外定义变量 sum 累加数据。
sum += i;
for 循环案例2
案例:奇数求和
**需求:**求1-10之间的奇数和,并把求和结果在控制台输出。
方式一:
- 定义 for 循环,使其能够一次产生:1、2、3、4、5、… 10。
- 循环每产生一个数据,都通过 if 判断其是否是奇数
- 在循坏外定义一个整数 sum,在 if 分支内来累加产生的奇数数据。
// 需求:求1-10的奇数和
// 3. 定义一个求和的变量 累加奇数和
int sum = 0;
// 1. 定义一个循环找到 1 2 3 4 ... 10
for (int i = 1; i <= 10; i++){
// i 1 2 3 4 5 6 7 8 9 10
// 2。 筛选出奇数
if (i % 2 == 1){
// i = 1 3 5 7 9
sum += i;
}
}
// 4. 输出求和变量即可
System.out.println("1-10的奇数和是:" + sum);
方式二:
- 定义 for 循环,使其能够依次产生:1、3、5、7、9。
- 在循环外定义一个整数变量 sum,循环每产生一个奇数就累加到 sum
// 2. 定义一个求和的变量 累加奇数和
int sum1 = 0;
// 1. 定义循环找到 1 3 5 7 9
for (int i = 1; i <= 10; i+=2){
// i = 1 3 5 7 9
sum1 += i;
}
// 3. 输出求和变量即可
System.out.println("1-10的奇数和是:" + sum1);
- 如何实现求奇数和?
方式一: 在 for 循环中,通过 if 筛选出奇数
for (int i = 1; i <= 10; i++){ if (i % 2 == 1){ // i = 1 3 5 7..., } }
方式2:直接使用 for 循环找出奇数。
for (int i = 1; i <= 10; i+=2){ }
for 循环案例3
案例:水仙花数
需求:在控制台输出所有的“水仙花数”,水仙花必须满足如下2个要求 :
- 水仙花数是一个三位数
- 水仙花数的各位、十位、百位的数字立方和等于原数
分析:
- 定义一个 for 循环从 “100一直到999”。
- 每次访问到数据后,提取该数据的:个位、十位、百位数字。
- 使用 if 判断:个位、十位、百位的数字立方和是否等于原数,等于则输出该数据。
- 并计算水仙花数。
// 需求:找出水仙花数并输出
// 在循环外定义一个变量用于记录水仙花的个数
int count = 0;
// 1. 定义一个 for 循环找出全部三位数
for (int i = 100; i <= 999; i++){
// 2. 判断这个三维数是否满足要求
// i = 157
// 个位
int ge = i % 10;
// 十位
int shi = i / 10 % 10;
// 百位
int bai = i / 100;
// 判断个位、十位、百位的平方和是否等于原数
// if (ge * ge * ge + shi * shi * shi + bai * bai * bai == i){
// // System.out.println() 输出方式会自动在语句后添加换行
// System.out.println(i);
if (ge * ge * ge + shi * shi * shi + bai * bai * bai == i){
// System.out.print() 输出方式不在语句后添加换行
System.out.print(i + "\t");
count++;
}
System.out.println();
System.out.println("水仙花个数是:" + count);
- 如何找出水仙花数?
- 定义一个 for 循环 “从100-999”
- 每次访问到数据后,提取该数据的:个位、十位、百位数字。
- 看各个位数的立方和是否等于原数,等于则输出原数据 。
- 如何计算出水仙花的个数?
- 在循环外定义一个变量 count 用于记录水仙花数。
每输出水仙花数时,让 count++。
while 循环
while 循环格式与执行流程
// 目标:学会使用 while 循环,并理解它的流程
int i = 0;
while (i < 3){
System.out.println("Hello World");
i++;
}
System.out.println("-------------");
int j = 0;
while (j < 3){
System.out.println("Hello World");
// 此处少了 j++,将不断循环下去,一直打印 Hello World
}
- while 循环的格式,执行流程是怎么样的?
- 什么时候用 for 循环,什么时候用 while 循环?
- 功能上是完全一样的,for 能解决的 while 也能解决,反之亦然。
- 使用规范是:知道循环几次:使用 for;不知道循环几次建议使用:while。
while 循环案例
案例:珠穆朗玛峰(世界最高峰8848.86米)
需求:
世界最高山峰是珠穆朗玛峰(8848.86米=8848860毫米),假如我有一张足够大的纸,它的厚度是0.1毫米。请问,折叠多少次,可以折成珠穆朗玛峰的高度。
思路:
- 这种不清楚要循环多少次的情况可以选择用 while 实现。
分析步骤
-
定义变量存储珠穆朗玛峰的高度、纸张的厚度。
-
使用 while 循环,循环条件是(纸张厚度 < 山峰高度),内部控制纸张折叠,每折一次,纸张厚度为原来的两倍,循环外定义计数变量,每折叠一次让该变量+1。
// 需求:珠穆朗玛峰高度是 8848860 纸张厚度 0.1 折叠纸张直到不低于珠穆朗玛峰高度,求折叠几次
// 1. 定义变量记录山峰的高度 滞涨的厚度
double peakHeight = 8848860;
double paperThickness = 0.1;
// 3. 定义一个变量用于记录纸张折叠的次数
int count = 0;
// 2. 定义一个while 循环控制纸张进行折叠
while (paperThickness < peakHeight){
// 让纸张的厚度多一倍
paperThickness *= 2;
count++;
}
System.out.println("折叠的次数:" + count);
System.out.println("纸张的最终厚度:" + paperThickness);
- 怎么解决此案例?
- 定义变量存储珠穆朗玛峰的高度、纸张的高度。
- 使用 while 循环,循环条件是(纸张厚度<山峰高度),内部控制纸张折叠,没折叠一次,纸张厚度为原来两倍,循环外定义计数变量,每折叠一次让该变量+1.
- for 和 while 使用总结
- 其实 while 能做的 for 都能实现
- 但是如果一开始不知道循环次数的情况下,建议使用 while 循环解决更专业。
- for 循环示例如下:
// for 循环中没有初始化语句则直接进入循环条件 for (; paperThickness < peakHeight;){ // 让纸张的厚度多一倍 paperThickness *= 2; count++; }
do-while 循环、三种循环小节
do-while 循环
- 先执行再判断循环条件。
do-while 循环的特点:一定会先执行一次循环体。
// 目标:学会使用 dowhile 循环,并理解其执行流程
int i = 0;
do {
System.out.println("Hello World");
i++;
}while(i < 3);
System.out.println("----------------------");
for (int j=0; j < 3; j++){
System.out.println("Hello World");
}
三种循环的区别小结
- for 循环和 while 循环(先判断后执行)
- do…while(第一次先执行后判断)
- for 循环和 while 循环的执行流程是一模一样的。
- 如果已知循环次数建议使用 for 循环,如果不清楚要循环多少次建议使用 while 循环。
- for 循环中,控制循环的变量只在循环中可以使用。While 循环中,控制循环变量再循环后可以继续使用。
int i = 0;
while (i < 3){
System.out.println("Hello World");
i++;
}
System.out.prnit(i);
for (int i=0; i < 3; i++){
System.out.println("Hello World");
}
System.out.println(i);
死循环
死循环
- 一直循环的执行下去,如果没有干预不会停止下来。
写法
// 目标:学会定义死循环
for (;;){
System.out.println("Hello World");
}
// 经典做法
while(true){
System.out.println("Hello World");
}
do {
System.out.println("Hello World");
}while(true);
案例:密码验证
需求:系统密码是 520,请用户不断的输入密码验证,验证不对则输出:密码错误,验证成功则输出:欢迎进入系统,并停止程序。
分析:
- 定义一个整型变量记录正确的密码:520
- 使用 while 死循环,让用户不断输入数据,与正确密码比对:验证不成功输出:密码错误;验证成功输出:欢迎进入系统,并使用break 结束当前循环的执行。
// 1. 定义正确的密码
int okPassword = 520;
// 2. 定义一个死循环让用户不断地输入密码认证
Scanner sc = new Scanner(System.in);
while(true){
System.out.println("请您输入正确的密码:");
int password = sc.nextInt();
// 3. 使用 if 判断密码是否正确
if (password == okPassword){
System.out.println("登陆成功了~~~");
break; // 可以理解结束当前所在循环的执行语句
}else{
System.out.println("密码错误!");
}
}
- 死循环可以怎么写?
for (;;){} // 经典写法 while (true){ } do { }while(true);
循环嵌套
循环嵌套
- 循环中又包含循环
// 目标:理解嵌套循环的执行流程
// 场景:加入你有老婆,然后你犯错了,你老婆发你说5天,每天3句我爱你。
for (int i=0; i < 5; i++){
for (int j=0; j < 3; j++){
System.out.println("我爱你");
}
System.out.println("---------------");
}
嵌套循环的特点
- 外部循环每循环一次,内部循环全部执行完一次。
案例:嵌套循环
需求:在控制台使用 * 打印出4行5列的矩形
for (int i=0; i < 4; i++){
for (int j=0; j<5; j++){
System.out.print("*");
}
System.out.println();
}
跳转关键字:break、continue
跳转控制语句介绍
- break:跳出并结束当前所在循环的执行。
- continue:用于跳出当前循环的当次执行,进入下一循环。
注意事项
break:只能用于结束所在循环,或者结束所在 switch 分支的执行。不能结束 if(true){} 分支。
continue:只能在循环中进行使用。
Random 的使用
Random 随机数技术
- 作用:用于在程序中获取随机数的技术。
使用步骤:
package random;
import java.util.Random; // 导包:告诉程序去 JDK 的哪个包中找随机数技术
public class RandomDemo1 {
public static void main(String[] args) {
// 目标:学会使用 Java 提供的随机数类 Random
// 1. 导包
// 2. 创建随机数对象
Random r = new Random(); // 写一行代码得到随机数对象
// 3. 调用 nextInt 功能(方法)可以返回一个整型的随机数给你
for (int i = 0; i < 20; i++) {
int data = r.nextInt(10); // 调用随机数的功能获取 0 - 9 的随机数
System.out.println(data);
}
}
}
注意:
- nextInt(n) 功能只能生成:0 至 n-1 之间的随机数,不包含 n。
Random 生成随机数的特点
- nextInt(n) 功能只能生成:0 - (n-1) 之间的随机数。
Random 生成区间随机数的技巧:减加法
- 例如:要生成 1 - 10 之间的随机数,程序怎么实现?
- 1 - 10 ==> -1 ==> (0 - 9) + 1
package random;
import java.util.Random; // 导包:告诉程序去 JDK 的哪个包中找随机数技术
public class RandomDemo1 {
public static void main(String[] args) {
// 目标:学会使用 Java 提供的随机数类 Random
// 1. 导包
// 2. 创建随机数对象
Random r = new Random(); // 写一行代码得到随机数对象
// 3. 调用 nextInt 功能(方法)可以返回一个整型的随机数给你
// 1 - 10 ==> -1 ==> (0 - 9) + 1
int data = r.nextInt(10) + 1;
System.out.println(data);
// 3 - 17 ==> -3 ==> (0 - 14) + 3
int data1 = r.nextInt(15) + 3;
System.out.println(data1);
}
}
- Random 随机数类生成需要几步,具体是什么样的?
- 导包:import java.util.Random;
- Random r = new Random();
- int number = r.nextInt(10);
- Random 随机数如何生成 65 - 91 之间的随机数?
- 65 - 91 => (0 - 26) + 65
- int number = r.nextInt(27) + 65;
案例:猜数字游戏
需求:
- 随机生成一个 1 - 100 之间的数据,提示用户猜测,猜大提示过大,猜小提示过小,直到猜中结束游戏。
分析:
- 随机生成一个 1-100 之间的数据
- 使用死循环不断提示用户猜测,猜大提示过大,猜小提示过小,猜中结束游戏。
package random;
import java.util.Random;
import java.util.Scanner;
public class RandomTest2 {
public static void main(String[] args) {
// 1. 随机一个幸运号码 1-100 之间,(0-99) + 1
Random r = new Random();
int luckNumber = r.nextInt(100) + 1;
// 2. 使用一个死循环让用户不断地去猜测,并给出提示
Scanner sc = new Scanner(System.in);
while(true){
// 让用户输入数据猜测
System.out.println("请您输入猜测的数据(1-100):");
int guessNumber = sc.nextInt();
// 3. 判断这个猜测的号码与幸运号码的大小情况
if (guessNumber > luckNumber){
System.out.println("您猜测的数据过大~");
}else if(guessNumber < luckNumber){
System.out.println("您猜测的数据过小~");
}else{
System.out.println("恭喜您,猜中了,可以去买单了~");
break; // 直接跳出并结束当前死循环!!
}
}
}
}