程序流程控制
此笔记参考黑马教程,仅学习使用,如有侵权,联系必删
文章目录
程序中最经典的三种执行顺序:
- 顺序结构:自上而下的执行代码
- 代码本身就是,默认的
- 分支结构:根据条件,选择对应代码执行
- if、switch
- 循环结构:控制某段代码重复执行
- for、while、do-while
1. 分支结构:if、switch、switch 穿透性
1.1 if 分支
- 根据条件(真或假)来决定执行某段代码
1.1.1 if 分支的三种形式
第一种:
if (条件表达式) {
代码;
}
执行流程:
- 首先判断条件表达式的结果,如果为 true 执行语句体,为 false 就不执行语句体
注意事项:
- if 语句种,**如果大括号控制的只有一行代码,则大括号可以省略不写
第二种:
if (条件表达式) {
代码1;
} else {
代码2;
}
执行流程:
- 首先判断条件表达式的结果,如果为 true 执行语句体1,为 false 就执行语句体2
第三种:
if (条件表达式1){
代码1;
} else if (条件表达式2){
代码2;
} else if (条件表达式3){
代码3;
}
...
else {
代码n;
}
执行流程:
- 先判断条件1的值,如果为 true 则执行语句体1,分支结束;如果为 false 则判断条件2的值
- 如果值为 true 就执行语句体2,分支结束;如果为 false 则判断条件3的值
- …
- 如果没有任何条件为 true,就执行 else 分支的语句体 n+1
总结
- if 分支是什么?
- 可以根据条件,选择执行某段程序
- if 分支的写法有几种,各有什么特点?
多学一招
- if(条件){},()后不能跟 “;” 否则{}中的代码将不受if的控制了
- 如果 if 语句的{}中只有一行代码的情况,{}可以省略不写(但是不推荐省略)
1.2 switch 分支
1.2.1 定义
- 是通过比较值来决定执行哪条分支
switch(表达式){
case 值1:
执行代码...;
break;
case 值2:
执行代码...;
break;
...
case 值n-1:
执行代码...;
break;
default:
执行代码n;
}
1.2.2 switch 分支的执行流程
- 先执行表达式的值,再拿着这个值去与 case 后的值进行匹配
- 与哪个 case 后的值匹配为 true 就执行哪个 case 块的代码,遇到 break 就跳出 switch 分支
- 如果全部 case 后的值与之匹配都是 false ,则执行 default 的代码
1.2.3 switch 分支的导学案例:电子备忘录
周一:埋头苦干,解决 bug
周二:请求大牛程序员帮忙
周三:今晚啤酒、龙虾、小烧烤
周四:主动帮助新来的女程序员解决 bug
周五:今晚吃鸡
周六:与王婆介绍的小芳相亲
周日:郁郁寡欢、准备上班
package c_流程控制;
public class b_SwitchDemo2 {
public static void main(String[] args) {
// 周一:埋头苦干,解决 bug
// 周二:请求大牛程序员帮忙
// 周三:今晚啤酒、龙虾、小烧烤
// 周四:主动帮助新来的女程序员解决 bug
// 周五:今晚吃鸡
// 周六:与王婆介绍的小芳相亲
// 周日:郁郁寡欢、准备上班
String week = "周三";
switch (week) {
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("您输入的星期信息肯定是不存在的~~~");
break;
}
}
}
1.2.4 if、switch 的比较,以及各自适合什么业务场景?
- if 在功能上远远强大于 switch
- 当前条件是区间的时候,应该使用 if 分支结构
- 当条件是与一个一个的值比较的时候,switch 分支更合适:格式良好,性能较好,代码优雅
总结
- switch 分支的格式、执行流程是怎么样的?
- if、switch 的比较,各自适合什么业务场景?
- if 其实在功能上远远强大于 switch
- if 适合做条件是区间判断的情况
- switch 适合做:条件是比较值的情况、代码优雅、性能较好
1.2.5 switch 使用时的注意事项
- 表达式类型只能是 byte、short、int、char、JDK5开始枚举,JDK7开始支持 String、不支持 double、float、long
- case 给出的值不允许重复,且只能是字面量,不能是变量
- 正常使用 switch 的时候,不要忘记写 break,否则会出现穿透现象
代码演示
package c_流程控制;
public class c_SwitchDemo3 {
public static void main(String[] args) {
// 目标:搞清楚switch使用时的几点注意事项
// 1. 表达式类型只能是 byte、short、int、char、JDK5开始枚举,JDK7开始支持 String、不支持 double、float、long
int a = 10;
double b = 0.1;
double b2 = 0.2;
double c = b + b2; // 0.30000000000000004 -> 在Java中浮点型运算有这种精度问题
System.out.println(c);
switch (a) {
}
// 2. case 给出的值不允许重复,且只能是字面量,不能是变量
int i = 20;
int d = 15;
switch (i) {
case 10:
break;
// case d:
// break;
case 20:
break;
}
// 3. 正常使用 switch 的时候,不要忘记写 break,否则会出现穿透现象
String week = "周三";
switch (week) {
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("您输入的星期信息肯定是不存在的~~~");
break;
} // 今晚啤酒、龙虾、小烧烤 主动帮助新来的女程序员解决 bug
}
}
多学一招
- 当存在多个 case 分支的代码相同时,可以把相同的代码放到一个 case 模块中,其他的 case 块都通过穿透性穿透到该case 块执行代码即可,这样可以简化代码
案例:
周一:埋头苦干,解决 bug
周二:请求大牛程序员帮忙
周三:请求大牛程序员帮忙
周四:请求大牛程序员帮忙
周五:自己整理代码
周六:打游戏
周日:打游戏
package c_流程控制;
public class d_SwitchDemo4 {
public static void main(String[] args) {
String week = "周日";
switch (week) {
case "周一":
System.out.println("埋头苦干,解决 bug");
break;
case "周二":
case "周三":
case "周四":
System.out.println("请求大牛程序员帮忙");
break;
case "周五":
System.out.println("自己整理代码");
break;
case "周六":
case "周日":
System.out.println("打游戏");
break;
default:
System.out.println("您输入的星期信息肯定是不存在的~~~");
break;
}
}
}
总结
- 使用 switch 时有哪些注意事项?
- 表达式类型只能是 byte、short、int、char、JDK5开始枚举,JDK7开始支持 String、不支持 double、float、long
- case 给出的值不允许重复,且只能是字面量,不能是变量
- 正常使用 switch 的时候,不要忘记写 break,否则会出现穿透现象
- switch 穿透性能解决什么问题?
- 存在多个 case 分支的代码相同时,可以把相同的代码放到一个 case 模块中,其他的 case 块都通过穿透性穿透到该case 块执行代码即可,这样可以简化代码
2. 循环结构:for 循环、for 循环案例
2.1 for 循环
2.1.1 定义
- 控制一段代码反复执行很多次
for 循环格式
for(初始化语句; 循环条件; 迭代语句) {
循环体语句(重复执行的代码);
}
代码演示
package c_流程控制;
public class e_ForDemo1 {
public static void main(String[] args) {
// 目标:需要掌握for循环的书写格式,并理解其运行流程
// 需求:打印多行Hello World
/**
* 流程: 首先会执行初始化语句:int i = 0; 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 (int i = 0; i < 3; i++) {
// i = 0 1 2
System.out.println("Hello World"); // 打印3行
}
System.out.println("---------------------------------------");
for (int i = 1; i <= 5; i++) {
System.out.println("Hello World2"); // 打印5行
}
System.out.println("----------------------------------------");
for (int i = 1; i <= 10; i += 2) {
// 1 3 5 7 9
System.out.println("Hello World3"); // 打印五行
}
}
}
2.1.2 for 循环在开发中的常见应用场景
减少代码的重复编写、灵活的控制程序的执行
总结
- for 循环格式和执行流程是什么样的?
- for 循环的常见应用场景?
- 减少代码的重复编写,灵活的控制程序的执行
2.1.3 for 循环的其他常见应用场景
- 案例1:求和
求1-5之间的数据和,并把求和结果在控制台输出
- 案例2:求奇数和
求1-10之间的奇数和,并把求和结果在控制台输出
package c_流程控制;
public class f_ForDemo2 {
public static void main(String[] args) {
// 目标:掌握使用for循环批量产生数据
for (int i = 1; i <= 100; i++) {
System.out.println(i); // 1~100
}
System.out.println("----------------------------");
// 目标:打印1~5的数据和
// 2. 定义一个变量用于求和
int sum = 0;
// 1. 定义一个循环,先产生1-5,这5个数
for (int i = 1; i <= 5; i++) {
sum += i; // sum = sum + i
}
System.out.println("1-5的数据和" + sum); // 15
System.out.println("----------------------------------");
// 目标:打印1~100的奇数和
// 2. 定义一个变量用于求和
int sum1 = 0;
// 1. 定义一个循环产生1-100之间的奇数
for (int i = 1; i <= 100; i += 2) {
// i = 1 3 5 7 9 ...
sum1 += i;
}
System.out.println("1-100之间的奇数和" + sum1); // 2500
System.out.println("----------------------------------");
// 2. 定义一个变量用于累加奇数求和
int sum2 = 0;
// 1. 定义循环产生的1-100之间的每个数据
for (int i = 1; i <= 100; i++) {
// i = 1 2 3 4 5 6 ... 99 100
// 2. 使用一个if分支,判断i此时记住的数据是否是奇数,是奇数我们才累加给一个变量
if (i % 2 == 1) {
// i = 1 3 5 7 9 ... 99
sum2 += i;
}
}
System.out.println("1-100之间的奇数和:" + sum2); // 2500
}
}
2.2 while 循环
2.2.1 定义
初始化语句;
while (循环条件) {
循环体语句(被重复执行的代码);
迭代语句;
}
2.2.2 示例
package c_流程控制;
public class g_WhileDemo1 {
public static void main(String[] args) {
// 目标:掌握while循环的书写格式,以及理解其执行流程
// 需求:打印多行Hello World
int i = 0;
while (i < 3) {
// i = 0 1 2
System.out.println("Hello World");
i++;
}
}
}
执行流程:
- 循环一开始,执行 int i = 0 一次
- 此时 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,循环立即结束!
总结
- while 循环的格式,执行流程是怎么样的?
- while 和 for 有什么区别?什么时候用 for,什么时候用 while?
- 功能上是完全一样的,for 能解决的 while 也能解决,反之亦然
- 使用规范:知道循环几次:使用 for;不知道循环几次建议使用:while
案例:珠穆朗玛峰
需求:世界最高峰珠穆朗玛峰高度是:8848.86米=8848860毫米,假如我有一张足够大的纸,它的厚度是0.1毫米。请问:该纸张折叠多少次,可以折成珠穆朗玛峰的高度?
-
分析:一开始不知道要循环多少次则使用 while
-
- 定义变量存储珠穆朗玛峰的高度、纸张的高度
-
- 使用 while 循环来控制纸张折叠,循环条件是(纸张厚度 < 山峰高度),循环每执行一次,就表示纸张折叠一次,并把纸张厚度变为原来的两倍
-
- 循坏外定义计数变量 count,循环每折叠一次纸张,让 count 变量+1
-
-
解
package c_流程控制;
public class h_WhileTest4 {
public static void main(String[] args) {
// 目标:使用while循环解决问题,并理解什么情况下使用while、for
// 1. 定义变量记住珠穆朗玛峰的高度和纸张的高度
double peakHeight = 8848860;
double paperThickness = 0.1;
// 3. 定义一个变量count用于记住纸张折叠了多少次
int count = 0;
// 2. 定义while循环控制纸张开始折叠
while (paperThickness < peakHeight) {
// 把纸张进行折叠,把纸张的厚度变成原来的2倍
paperThickness = paperThickness * 2;
count++;
}
System.out.println("需要折叠多少次:" + count); // 27
System.out.println("最终纸张的厚度是:" + paperThickness); // 1.34217728E7
}
}
2.3 do-while 循环
2.3.1 定义
初始化语句;
do {
循环体语句;
迭代语句;
} while (循环条件);
2.3.2 特点
do-while 循环特点:
- 先执行后判断
三种循环的区别小结
- for 循环和 while 循环(先判断后执行);do … while(先执行后判断)
- for 循环和 while 循环的执行流程是一模一样的,功能上无区别,for 能做的 while 也能做,反之亦然
- 使用规范:如果已知循环次数建议使用 for 循环,如果不清楚要循环多少次建议使用 while 循环
- 其他区别:for 循环中,控制循环的变量只能在循环中使用(临时变量)。while 循环中,控制循环的变量在循环后还可以继续使用
package c_流程控制;
public class j_DorWhileDemo1 {
public static void main(String[] args) {
for (int i = 0; i < 3; i++) {
System.out.println("Hello World");
}
// System.out.println(i); // 报错
for (int i = 0; i < 3; i++) {
System.out.println("Hello World");
}
int m = 0;
while (m < 3) {
System.out.println("Hello World1");
m++;
}
System.out.println(m); // 3
}
}
2.4 死循环
2.4.1 定义
- 可以一直执行下去的一种循环,如果没有干预不会停下来
2.4.2 死循环的写法
- 第一种
for ( ; ; ) {
System.out.println("Hello World");
}
- 第二种(经典写法)
while (true) {
System.out.println("Hello World");
}
- 第三种
do {
System.out.println("Hello World");
} while (true);
2.4.3 应用场景
- 做服务器程序
代码实现
package c_流程控制;
public class k_EndLessLoopDemo6 {
public static void main(String[] args) {
// 目标:掌握死循环的写法
// for (;;) {
// System.out.println("Hello World1");
// }
while (true) {
System.out.println("Hello World2");
}
// do {
// System.out.println("Hello World");
// } while (true);
}
}
2.5 循环嵌套
2.5.1 定义
- 循环中又包含循环
2.5.2 循环嵌套的特点
- 外部循环每循环一次,内部循环会全部执行完一轮
代码实现
package c_流程控制;
public class l_LoopNestedDemo7 {
public static void main(String[] args) {
// 目标:循环嵌套的执行流程
// 场景:假如你有老婆,你犯错了,你老婆罚你说3天,每天5句我爱你
for (int i = 1; i <= 3; i++) {
// i = 1 2 3
for (int j = 1; j <= 5; j++) {
System.out.println("我爱你:" + i);
}
System.out.println("-------------------------");
}
/**
****
****
****
*/
for (int i = 1; i <= 3; i++) {
// i = 1 2 3
// 定义一个循环控制每行打印多少列星星
for (int j = 1; j <= 4; j++) {
System.out.print("*");
}
System.out.println(); // 换行
}
}
}
3. 跳转关键字:break、continue
3.1 定义
- break:跳出并结束当前所在的循环的执行
- continue:用于跳出当前循环的当次执行,直接进入循环的下一次执行
注意事项:
- break 只能用于结束所在循环,或者结束所在 switch 分支的执行
- continue 只能在循环中进行使用
代码演示
package c_流程控制;
public class m_BreakAndContinueDemo8 {
public static void main(String[] args) {
// 目标:掌握break和continue的作用
// 1. break:跳出并结束当前所在循环中的执行
// 场景:假如你又有老婆了,你犯错了,你老婆罚你说5句我爱你
// 说到第三句的时候心软了,让你别再说了
for (int i = 1; i <= 5; i++) {
System.out.println("我爱你:" + i);
if (i == 3) {
// 说明已经说完了第三句了,心软了
break; // 跳出并结束当前所在循环的执行
}
}
// 2. continue:跳出当前循环的当次执行,直接进入循环的下一次执行
// 场景:假如你有老婆,你犯错了,你老婆罚你洗碗5天
// 第三天的时候,你表现很好,第三天不用洗碗,但是不解恨,第四天还是要继续的
for (int i = 1; i <= 5; i++) {
if (i == 3) {
// 已经到了第三天,第三天不用洗碗
continue;
}
System.out.println("洗碗:" + i);
}
}
}
4. 随机数 Random、Random 案例
4.1 Random
- 作用:生成随机数
4.1.1 得到0-9的随机数的实现步骤
- 导包:告诉程序去 JDK 的哪个包中找 Random
- 写一行代码拿到随机数对象
- 调用随机数的功能获取0-9之间的随机数(包前不包后)
注意:
- nextInt(n) 功能只能生成:0 至 n-1 之间的随机数,不包含 n
4.1.2 Random 生成指定区域随机数
- 技巧:减加法
- java 自带功能
nextInt(下限, 上限+1);
代码演示
package d_random;
import java.util.Random;
public class a_RandomDemo1 {
public static void main(String[] args) {
// 目标:掌握使用Random生成随机数的步骤
// 1. 导包
// 2. 创建一个Random对象,用于生成随机数
Random r = new Random();
// 3. 调用Random提供的功能:nextInt得到的随机数
for (int i = 1; i <= 20; i++) {
int data = r.nextInt(10); // 0-9
System.out.println(data);
}
System.out.println("-------------------------");
for (int i = 1; i <= 20; i++) {
// 生成:1-10之间的随机数
// 1-10 => -1 => (0 - 9) + 1
int data2 = r.nextInt(10) + 1;
System.out.println(data2);
}
System.out.println("------------------------------");
for (int i = 1; i <= 20; i++) {
// 生成:3-17之间的随机数
// 3 - 17 => -3 => (0 - 14)
int data2 = r.nextInt(15) + 3;
System.out.println(data2);
}
}
}
总结
- Random 生成随机数需要几步?
- 导包:
import java.util.Random;
Random r = new Random();
int number = r.nextInt(10);
- 如何生成 65 - 91 之间的随机数?
- 65 - 91 => -65 => ( 0 - 26 ) + 65
案例:猜数字游戏
需求:
- 随机生成一个1-100之间的数据,提示用户猜测,猜大提示过大,猜小提示过小,直到猜中结束游戏
分析:
- 先随机生成一个1-100之间的数据
- 定义一个死循环让用户可以一直猜测
- 在死循环里,每次都提示用户输入一个猜测的数字,猜大提示过大,猜小提示过小,猜中则结束游戏
代码实现
package d_random;
import java.util.Random;
import java.util.Scanner;
public class b_RandomTest2 {
public static void main(String[] args) {
// 1. 随机产生一个1-100之间的数据,做为中奖号码
Random r = new Random();
int luckNumber = r.nextInt(100) + 1;
// 2. 定义一个死循环,让用户不断的猜测数据
Scanner sc = new Scanner(System.in);
while (true) {
// 提示用户猜测
System.out.println("请您输入您猜测的数据:");
int guessNumber = sc.nextInt();
// 3. 判断用户猜测的数字与幸运号码的大小情况
if (guessNumber > luckNumber) {
System.out.println("您猜测的数字过大~~~");
} else if (guessNumber < luckNumber) {
System.out.println("您猜测的数字过小~~~");
} else {
System.out.println("恭喜您,猜测成功了,可以买单了");
break; // 结束游戏
}
}
}
}