<Java> 4 程序控制结构

本文最后更新于:2023年11月24日 上午

程序运行的流程控制决定程序是如何执行的,是我们必须掌握的。主要分为:顺序控制、分支控制、循环控制。

4.1 顺序控制

程序从上到下逐行执行,中间没有任何判断和跳转(默认的控制顺序)

比如:Java 定义变量时采用合法的前向引用。

语句:Java 中最小的执行单位。语句分为 单语句 和 复合语句。

  • 单语句:通常意义的一条语句。语句间以分号 ; 分隔。

  • 复合语句:一对大括号括起来的语句组。也称为 “块”

    1
    2
    3
    4
    5
    {
    语句1;
    语句2;
    ...
    }

    块中可以有多条语句。块后没有分号 ;

4.2 分支控制 if-else

让程序有选择的执行。主要分为:单分支控制、双分支控制

4.2.1 单分支控制

1
if (条件表达式) 语句;

特别地,把代码块(复合语句)作为语句的场合也能这样写:

1
2
3
if (条件表达式) {
执行代码块;
}

当条件表达式为 ture,就会执行 {执行代码块;};如果为 false 则不执行。特别地:如果 {执行代码块;} 中只有一条代码,也可以不写 { }(但还是建议写上)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Scanner;//导入
public class If01 {
//编写一个 main 方法
public static void main(String[] args) {
//编写一个程序,可以输入人的年龄,如果该同志的年龄大于 18 岁, 则输出 "你年龄大于 18,要对自己的行为负责,送入监狱"
//思路分析
//1. 接收输入的年龄, 应该定义一个 Scanner 对象
//2. 把年龄保存到一个变量 int age
//3. 使用 if 判断,输出对应信息
//应该定义一个 Scanner 对象

Scanner myScanner = new Scanner(System.in);
System.out.println("请输入年龄:");
//把年龄保存到一个变量 int age
int age = myScanner.nextInt();
//使用 if 判断,输出对应信息
if(age > 18) {
System.out.println("你年龄大于 18,要对自己的行为负责,送入监狱");
}

System.out.println("程序继续...");
}
}

4.2.2 双分支控制

1
2
3
4
5
6
if (条件表达式) {
执行代码块;
}
else {
执行代码块2;
}

当条件表达式为 ture,就会执行 {执行代码块1;};如果为 false 则执行 {执行代码块2;}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Scanner;//导入
public class test {
//编写一个 main 方法
public static void main(String[] args) {
//判断一个年份是否是闰年,闰年的条件是符合下面二者之一:
//(1)年份能被 4 整除,但不能被 100 整除;(2)能被 400 整除
//思路分析
//1. 定义 int year 保存年
//2. 年份能被 4 整除,但不能被 100 整除, // => year % 4 == 0 && year % 100 != 0
//3. 能被 400 整除 => year % 400 == 0
//4. 上面的 2 和 3 是 或的关系
//代码实现
Scanner myScanner = new Scanner(System.in);
System.out.println("请输入年份:");
int year = myScanner.nextInt();
if( (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 ) {
System.out.println(year + " 是 闰年");
} else {
System.out.println(year + " 不是 闰年");
}
}
}

4.2.3 多分支控制

1
2
3
4
5
6
7
8
9
10
11
if (条件表达式) {
执行代码块;
} else if (条件表达式2) {
执行代码块2;
} else if (条件表达式3) {
执行代码块3;
}
...
else {
执行代码块n;
}

特别地:多分支可以没有 else。此时如果条件都不成立,则无执行入口

4.2.4 嵌套分支

在一个分支结构中又完整嵌套了另一个完整的分支结构。里面的分支称为内层分支,外面的分支称为外层分支。

Java 规定,else 子句属于逻辑上距其最近,且没有匹配 else 的 if 语句

规范:嵌套尽量不超过 3 层(可读性不好)

4.3 switch 分支结构

1
2
3
4
5
6
7
8
9
10
11
12
switch(表达式){
case 常量1:
语句块1;
break; //break 语句可选
case 常量2:
语句块2;
break; //break 语句可选
...
default: //default 语句可选
default语句块;
break; //break 语句可选
}
  1. switch 关键字,表示 switch 分支。
  2. 表达式 对应一个值。该值必须是 int 或 char(char 可以转化为 int)。是 byte 或 short 的场合,要提升为 int。不允许 long、double 或 float
  3. case 常量1; 表示:当 表达式 的值等于 常量1 ,则执行 语句块1
  4. break; 表示退出 switch 分支。
  5. 表达式 的值匹配 常量1 ,则执行 语句块1,如果不匹配,则继续匹配 常量2 ,以此类推。
  6. 如果全都不匹配,则执行 default
  7. 如果不写 break; ,则会发生穿透,即不进行判断而继续执行下一语句块。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.util.Scanner;//导入
public class test {

public static void main(String[] args) {
/*
请编写一个程序,该程序可以接收一个字符,比如:a,b,c,d,e,f,g
a 表示星期一,b 表示星期二 …
根据用户的输入显示相应的信息.要求使用 switch 语句完成
思路分析
1. 接收一个字符 , 创建 Scanner 对象
2. 使用 switch 来完成匹配,并输出对应信息
代码
*/
Scanner myScanner = new Scanner(System.in);
System.out.println("请输入一个字符(a-c)");
char c1 = myScanner.next().charAt(0);//
//在 java 中,只要是有值返回,就是一个表达式
switch(c1) {
case 'a' :
System.out.println("今天星期一,猴子穿新衣");
break;
case 'b' :
System.out.println("今天星期二,猴子当小二");
break;
case 'c' :
System.out.println("今天星期三,猴子爬雪山..");
break;
default:
System.out.println("你输入的字符不正确,没有匹配的");
}
System.out.println("退出了 switch ,继续执行程序");
}
}

4.3.1 使用细节

  1. 表达式数据类型,应和 case 后的常量类型一致,或者是可以自动转换成可以比较的类型。如:输入的是 char 而 常量是 int
  2. switch 中 表达式 的返回值必须是:(byte, short, int, char,enum[枚举] ,String)
  3. case 语句中的值必须是常量或常量表达式,不能是变量。
  4. default 是可选的。没有就不执行。
  5. break; 用来跳出 switch 分支。如果不写,会持续执行语句,直到分支结束或遇到下一个 break;

4.3.2 与 if-else 分支结构的取舍

  • 如果判断的具体数值不多,而且符合 byte、 short 、int、 char, enum[枚举], String 这 6 种类型。虽然两个语句都可以使用,建议使用 swtich 语句。
  • 其他情况:对区间判断,对结果为 boolean 类型判断,使用 if,if 的使用范围更广

4.4 for 循环控制

1
2
3
for(循环变量初始化;循环条件;循环变量迭代){
循环操作(代码块);
}
  • for 关键字,表示循环控制

  • 四个要素:1. 循环变量初始化 2. 循环的条件 3. 循环的操作 4. 循环变量迭代

  • 循环操作可以有多条语句

  • 如果循环操作只有一条语句,可以省略 {},但建议不省略

4.4.1 使用细节

  1. 循环条件是返回一个 boolean 值(turefalse)的公式。
  2. for(;循环条件;){ } 其中的初始化和变量迭代可以写在别处,但 ; 不能省略。如果不写在别处,那个循环变量初始化中声明的变量只能在该 for 循环中使用。
  3. 控制台用 ctrl + c 强制结束一个流程
  4. 循环初始值可以有多条初始化语句,但要求类型一样,并用 , 隔开。变量迭代也可以有多条代码,用 , 隔开。
1
2
3
4
int count = 3;
for(int i = 0,j = 0; i < count; i++, j+=2){
System.out.println("i = " + i + " j = " + j);
}

4.4.2 化繁为简 先死后活

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//练习
import java.util.Scanner;//导入
public class test {

public static void main(String[] args) {
//打印 1~100 之间所有是 9 的倍数的整数,统计个数 及 总和.[化繁为简,先死后活]
//老韩的两个编程思想(技巧)
//1. 化繁为简 : 即将复杂的需求,拆解成简单的需求,逐步完成
//2. 先死后活 : 先考虑固定的值,然后转成可以灵活变化的值
//思路分析
//打印 1~100 之间所有是 9 的倍数的整数,统计个数 及 总和
//化繁为简
//(1) 完成 输出 1-100 的值
//(2) 在输出的过程中,进行过滤,只输出 9 的倍数 i % 9 ==0
//(3) 统计个数 定义一个变量 int count = 0; 当 条件满足时 count++;
//(4) 总和 , 定义一个变量 int sum = 0; 当条件满足时累积 sum += i;
//先死后活
//(1) 为了适应更好的需求,把范围的开始的值和结束的值,做出变量
//(2) 还可以更进一步 9 倍数也做成变量 int t = 9;
int count = 0; //统计 9 的倍数个数 变量
int sum = 0; //总和
int start = 10;
int end = 200;
int t = 5; // 倍数
for(int i = start; i <= end; i++) {
if( i % t == 0) {
System.out.println("i=" + i);
count++;
sum += i;//累积
}
}
System.out.println("count=" + count);
System.out.println("sum=" + sum);

}
}


4.5 while 循环控制

1
2
3
4
while(循环条件){
循环体(代码块);
循环变量迭代;
}

while 也有四要素,只是位置和 for 不同

4.5.1 使用细节

  1. 循环条件是返回一个 boolean 值(turefalse)的公式。while 循环中,循环条件不能为空。
  2. while 循环是先判断再执行语句。

4.6 do..while 循环控制

1
2
3
4
do{
循环体;
循环变量迭代;
}while(循环条件);
  1. do..while 是关键字
  2. 也有四要素,位置不同
  3. 先执行,再判断。也就是说,一定会至少执行一次
  4. 最后有一个 ;
  5. whiledo..while 区别:“要账”do..while先打一顿

4.6.1 使用细节

  1. 循环条件是返回一个 boolean 值(turefalse)的公式。
  2. do..while 循环是先执行再判断的语句。因此至少执行一次。

4.7 多重循环控制

  1. 将一个循环放在另一个循环体内,就形成了嵌套循环。建议一般使用两层,最多不超过三层。
  2. 嵌套循环是把内层循环当成外层循环的循环体。只有内层 false 时才结束当层循环。
  3. 若内层执行 n 次,外层 m 次,则合计会循环 n*m 次

4.7.1 空心金字塔问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class test {

public static void main(String[] args) {

int totalLevel = 10;
for(int i = 1; i <= totalLevel; i++){

for(int m = totalLevel; m > i; m--){
System.out.print(" ");
}

for( int j = 1; j <= 2*i-1; j++){
if (j == 1 || j == 2*i-1 || i == totalLevel) {
System.out.print("*");
} else
System.out.print(" ");
}
System.out.println("");

}

}
}

image-20231124173638347

4.7.2 九九乘法表问题

1
2
3
4
5
6
7
8
9
10
11
public class test {

public static void main(String[] args) {
for(int i = 1; i <= 9; i++){
for(int j = 1; j<=i; j++){
System.out.print(j + "*" + i + "=" + i*j + "\t");
}
System.out.println();
}
}
}
image-20231124181958866

4.8 跳转控制语句

跳转控制语句用于分支或循环中,以便程序员更好控制程序执行方向

4.8.1 break

用于中止一个语句块的执行

语法:break;

break 可以被用在三种场合中

  • switch 语句中,以跳出判断(结束穿透)

  • for、while、do…while 循环语句中,以跳出循环

  • 语句块中,以跳过本块中所有剩余语句

    break 语句出现在多层嵌套的语句块中时,可以通过 标签 指明要终止的时哪一层语句块。

    1
    2
    3
    4
    5
    6
    7
    8
    a:{
    b: {
    c: {
    ...
    berak b;
    }
    }
    }JAVA
    1. a: b: c: 是标签,名字由程序员指定
    2. break 后指定哪个标签就退出到哪里
    3. 实际开发中,尽量不要使用标签

4.8.3 continue

在循环中出现。用于结束本次循环,继续下一次循环

语法:continue;

进行下次循环前,仍会判断循环条件是否满足

在多层嵌套循环中,可以通过标签指出跳出哪次循环(同 break

4.8.4 return

用于方法。表示跳出所在的方法

语法:return;

方法有返回值的场合,将返回值写在 return 后:return 值;

后面会再讲~


<Java> 4 程序控制结构
http://viper2383.github.io/2023/11/15/Java 4 程序控制结构/
作者
w1per3
发布于
2023年11月15日
许可协议