概述
顺序结构
顺序结构是程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。
实例
public class Demo0 {
public static void main(String[] args) {
//如果你没有写其他的结构,按照代码的先后顺序,依次执行程序中大多数的代码都是这样执行的。
System.out.println("A");
System.out.println("B");
System.out.println("C");
}
}
选择语句
选择语句又称为分支语句,它通过对给定的条件进行判断,从而决定执行两个或多个分支中的哪一支。因此,在编写选择语句之前,应该首先明确判断条件是什么,并确定当判断结果为“真”或“假”时应分别执行什么样的操作/算法。在 Java 语言中选择语句主要提供了两个,一个是 if 语句,另一个则是 switch 语句。
If分支
根据判定的结果(真或假)决定执行某个分支的代码。对于一个if语句来说,在任何情况下只能有1个分支执行,不可能存在2个或者更多个分支执行。if语句中只要有1个分支执行了,整个if语句就结束了。当 if分支结束后 会继续向下执行。
第一个格式
执行流程:
- 首先计算关系表达式的值
- 如果关系表达式的值为true就执行语句体
- 如果关系表达式的值为false就不执行语句体
- 继续执行后面的语句内容
执行流程图
实例
public class Demo0 {
public static void main(String[] args) {
// 如果年龄大于18岁, 就可以上网吧
int age = 20;
if (age >= 18) {
// age >= 18 结果为true,执行语句体中的代码
System.out.println("可以上网吧");
}
}
}
注意事项:
- if 语句中,如果大括号控制的只有一行代码,则大括号可以省略不写。不建议省略,可读性不好
第二种格式
执行流程:
- 首先计算关系表达式的值
- 如果关系表达式的值为true就执行语句体1
- 如果关系表达式的值为false就执行语句体2
- 继续执行后面的语句内容
执行流程图
实例
// 任意给出一个整数,请用程序实现判断该整数是奇数还是偶数,并在控制台输出该整数是奇数还是偶数
public class Demo {
public static void main(String[] args) {
// 程序判断一个数, 是奇数还是偶数
int num = 9;
if (num % 2 == 0) {
System.out.println("偶数");
} else {
System.out.println("奇数");
}
}
}
小技巧:
- 在某些简单的应用中,if语句是可以和三元运算符互换使用的
- 当语句块只有一个语句时,可以省略{},但是不建议省略{}
实例
public class Demo04Test {
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
}
}
第三种格式
执行流程:
- 首先计算关系表达式1的值
- 如果值为true就执行语句体1;如果值为false就计算关系表达式2的值
- 如果值为true就执行语句体2;如果值为false就计算关系表达式3的值
- …
- 如果没有任何关系表达式为true,就执行语句体n+1。然后结束当前多分支。
执行流程图
实例
/*
需求:
根据学生成绩, 程序给出对应评价
90~100 优秀
80~89 良好
70~79 中等
60~69 及格
0~59 请努力加油!
*/
public class Demo02Test {
public static void main(String[] args) {
int score = 88;
if (score >= 90 && score <= 100) {
System.out.println("优秀");
} else if (score >= 80 && score <= 89) {
System.out.println("良好");
} else if (score >= 70 && score <= 79) {
System.out.println("中等");
} else if (score >= 60 && score <= 69) {
System.out.println("及格");
} else if (score >= 0 && score <= 59) {
System.out.println("请努力加油");
} else {
System.out.println("成绩有误!");
}
}
}
注意事项:
- else分支是可选的,凡是带有else分支的,一定可以保证会有 一个分支执行。
if语句的嵌套
在if的语句块中,或者是在else语句块中,又包含了另外一个条件判断(可以是单分支、双分支、多分支)这就是if语句嵌套
执行的特点:
- 如果是嵌套在if语句块中的 只有当外部的if条件满足,才会去判断内部的条件
- 如果是嵌套在else语句块中的 只有当外部的if条件不满足,进入else后,才会去判断内部的条件
实例
public class Demo {
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("你的成绩属于不及格");
}
}
}
}
- 如果使用单段 校验 一定要注意数学特性,不能改变位置。
分支语句之switch
格式:
执行流程:
- 首先,计算出表达式的值
- 其次,和case依次比较,一旦有对应的值,就会执行相应的语句,在执行的过程中,遇到break就会结束。
- 最后,如果所有的case都和表达式的值不匹配,就会执行default语句体部分,然后程序结束掉。
实例
public class Demo {
public static void main(String[] args) {
//定义指定的星期
int weekday = 5;
//switch语句实现选择
switch (weekday) {
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语句case穿透
在switch语句中,如果case的后面不写break,将出现穿透现象,也就是一旦匹配成功,不会在判断下一个case的值,直接向后运行,直到遇到break或者整个switch语句结束,switch语句执行终止。
应用场景
存在多个case分支的功能代码是一样时,可以用穿透性把流程集中到同一处处理,这样可以简化代码。
/*
case穿透是如何产生的?
如果switch语句中,case省略了break语句, 就会开始case穿透现象:
当开始case穿透,后续的case就不会具有匹配效果,内部的语句都会执行
直到看见break,或者将整体switch语句执行完毕,才会结束。
需求:指定一个月份,输出该月份对应的季节。
3,4,5 春季
6,7,8 夏季
9,10,11秋季
12,1,2 冬季
*/
public class Demo05Test {
public static void main(String[] args) {
//指定一个月份
int month = 5;
switch (month) {
case 1:
case 2:
case 12:
System.out.println("冬季");
break;
case 3:
case 4:
case 5:
System.out.println("春季");
break;
case 6:
case 7:
case 8:
System.out.println("夏季");
break;
case 9:
case 10:
case 11:
System.out.println("秋季");
break;
default:
System.out.println("你输入的月份有误");
break;
}
}
}
注意事项:
- 表达式类型只能是byte、short、int、char,JDK5开始支持枚举,JDK7开始支持String、不支持double、float、long
- case给出的值不允许重复,且只能是字面量,不能是变量
- 不要忘记写break,否则会出现穿透现象
- case 后面值的类型要与表达式的类型保持一致或者兼容
循环语句
循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句, 当反复 执行这个循环体时,需要在合适的时候把循环判断条件修改为false,从而结束循环,否则循环将一直执行下去,形成死循环。一个标准的循环语句有由下面几个部分组成
- 初始化语句: 用于表示循环开启时的起始状态,简单说就是循环开始的时候什么样,有且只执行一次
- 条件判断语句:用于表示循环反复执行的条件,简单说就是判断循环是否能一直执行下去
- 循环体语句: 用于表示循环反复执行的内容,简单说就是循环反复执行的事情
- 条件控制语句:用于表示循环执行中每次变化的内容,简单说就是控制循环是否能执行下去
循环语句之for循环
格式:
注意:
- for(;;)中的两个;是不能多也不能少
- 循环条件必须是boolean类型
- 如果循环条件语句②省略的话,就默认为循环条件成
执行流程:
-
第一步:执行初始化语句①,完成循环变量的初始化;
-
第二步:执行循环条件语句②,看循环条件语句的值是true,还是false;
-
如果是true,执行第三步;
-
如果是false,循环语句中止,循环不再执行。
-
-
第三步:执行循环体语句③
-
第四步:执行迭代语句④,针对循环变量重新赋值
-
第五步:根据循环变量的新值,重新从第二步开始再执行一遍
执行顺序
实例
//需求:在控制台输出所有的“水仙花数”,要求每行打印2个
public class Demo06Test {
public static void main(String[] args) {
// 定义变量count,用于保存“打印过”的数量,初始值为0
int count = 0;
//输出所有的水仙花数必然要使用到循环,遍历所有的三位数,三位数从100开始,到999结束
for (int i = 100; i < 1000; 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) {
count++;
//输出满足条件的数字就是水仙花数
System.out.print(i+"\t");
// 在每一次count变量+1后,判断是否到达了2的倍数,是的话,换行
if (count % 2 == 0) {
System.out.println();
}
}
}
}
}
循环语句之while循环
格式:
执行流程:
-
第一步:执行初始化语句①,完成循环变量的初始化;
-
第二步:执行循环条件语句②,看循环条件语句的值是true,还是false;
-
如果是true,执行第三步;
-
如果是false,循环语句中止,循环不再执行。
-
-
第三步:执行循环体语句③
-
第四步:执行迭代语句④,针对循环变量重新赋值
-
第五步:根据循环变量的新值,重新从第二步开始再执行一遍
执行流程图
实例
/*
需求:世界最高山峰是珠穆朗玛峰(8844.43米=8844430毫米),假如我有一张足够大的纸,它的厚度是0.1毫米。
请问,我折叠多少次,可以折成珠穆朗玛峰的高度?
*/
public class Demo {
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.Random;
import java.util.Scanner;
/*
随机生成一个100以内的数,猜数字游戏
从键盘输入数,如果大了提示,大了,如果小了,提示小了,如果对了,就不再猜了,并统计一共猜了多少次
*/
public class Demo {
public static void main(String[] args) {
//随机生成一个100以内的整数
Random random = new Random();
int num = random.nextInt(100) + 1;
//声明一个变量,用来存储猜的次数
int count = 0;
Scanner input = new Scanner(System.in);
int guess;//提升作用域
do {
System.out.print("请输入100以内的整数:");
guess = input.nextInt();
//输入一次,就表示猜了一次
count++;
if (guess > num) {
System.out.println("大了");
} else if (guess < num) {
System.out.println("小了");
}
} while (num != guess);
System.out.println("一共猜了:" + count + "次");
}
}
死循环
一直循环的执行下去,如果没有干预不会停止下来。 三种循环语句如下所示
for死循环的格式
public class Demo {
public static void main(String[] args) {
for (; ; ) {
// 循环体
System.out.println("Hello World");
}
}
}
while死循环的格式
public class Demo {
public static void main(String[] args) {
while (true) {
//循环体
System.out.println("hello world !!");
}
}
}
public class Demo {
public static void main(String[] args) {
do {
//循环体
System.out.println("hello world !!!");
} while (true);
}
}
循环语句的区别
-
从循环次数角度分析
-
do...while循环至少执行一次循环体语句
-
for和while循环先循环条件语句是否成立,然后决定是否执行循环体,至少执行零次循环体语句
-
-
从循环变量的生命周期角度分析
-
for循环的循环变量在for()中声明的,在循环语句结束后,不可以被访问;
-
while和do...while循环的循环变量因为在外面声明的,所以while和do...while结束后可以被继续使用的;
-
-
如何选择
-
遍历有明显的循环次数(范围)的需求,选择for循环
-
遍历没有明显的循环次数(范围)的需求,循环while循环,死循环推荐使用while
-
如果循环体语句块至少执行一次,可以考虑使用do...while循环
-
本质上:三种循环之间是可以互相转换的,都能实现循环的功能
-
-
三种循环结构都具有四要素:
-
(1)循环变量的初始化表达式
-
(2)循环条件
-
(3)循环变量的修改的迭代表达式
-
(4)循环体语句块
-
循环嵌套
-
所谓嵌套循环,是指一个循环的循环体是另一个循环。比如for循环里面还有一个for循环,就是嵌套循环。总共的循环次数=外循环次数*内循环次数。当然可以是三种循环任意互相嵌套。
常用的嵌套循环格式:
嵌套循环的特点
- 外部循环每循环一次,内部循环全部执行完一次。
实例
public class Test {
/*
打印如下图形到控制台
1
12
123
1234
12345
*/
public static void main(String[] args) {
//外循环控制行数
for (int i = 1; i <= 5; i++) {
//内循环控制每一行打印的数字
for (int j = 1; j <= i; j++) {
System.out.print(j);
}
System.out.println();
}
}
}
跳转关键字
在特殊的流程控制语句下 不能存在其他内容 ,也就是break和continue下面不能写其他代码
break
使用场景:终止switch或者当前循环。只能使用在选择结构switch语句中或者在循环语句中
实例
//从键盘输入不断输入整数,输入0表示结束,统计一共有几个正数、负数。
public class Demo {
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;
//System.out.println("后续代码"); 错误: 无法访问的语句
} else if (num > 0) {
positive++;
} else {
negative++;
}
}
System.out.println("正数:" + positive+"个" + ",负数:" + negative+"个");
}
}
一旦存在lable(标签) 那么结束的是 label所在层的循环,continue同理
class Demo {
public static void main(String[] args) {
l:
for (int i = 1; i <= 10; i++) {
for (int j = 1; j <= 15; j++) {
if (j == 10) {
break l;
}
System.out.print(j + " ");
}
System.out.println();
}
System.out.println("Game Over!!!");
}
}
continue
使用场景:结束本次循环,继续下一次的循环。
实例
public class Demo {
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("后续代码"); 错误: 无法访问的语句
}
System.out.println(i);
}
}
}