外观
第 3 章 程序控制结构:指挥你的机器人
阅读目标
- 理解“顺序、分支、循环”三大基本程序结构。
- 熟练掌握
if-else、switch、for、while语句的用法。- 掌握比较运算符和逻辑运算符,用于构建复杂的判断条件。
- 理解循环控制语句
break和continue的区别。- 能综合运用本章知识,编写出能做出决策和重复执行任务的程序。
到目前为止,我们的程序就像一条直线,从头到尾按顺序执行。但现实世界充满了选择和重复。饿了要吃饭,红灯要停,要沿着跑道跑 hết 多圈... 为了让机器人能应对这些复杂的场景,我们必须学习程序的三大“控制结构”:顺序、分支和循环。它们是构建所有复杂逻辑的基石。
3.1 顺序结构:一步接一步
这是最简单的结构,代码会严格按照你书写的顺序,从上到下一行一行地执行,不跳过也不回头。就像机器人执行一个预设动作序列:前进 -> 抬升手臂 -> 张开爪子。
java
/**
* 顺序结构示例:机器人执行一系列固定动作。
* 每一行代码都会被严格执行,且顺序不会改变。
*/
public class SequenceTest {
public static void main(String[] args) {
System.out.println("指令1:马达正转,前进");
System.out.println("指令2:抬升手臂");
System.out.println("指令3:张开机械爪");
System.out.println("任务完成");
}
}1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
⚡提醒
顺序结构中,每条语句都会被执行,且执行顺序严格按照代码顺序!
3.2 分支结构:在岔路口做选择
分支结构,也叫选择结构,允许程序根据一个条件的真假来决定执行哪一段代码。这赋予了程序“思考”和“决策”的能力。
3.2.1 比较运算符
它们用于比较两个值,结果总是一个布尔值 (true 或 false)。
| 运算符 | 含义 | 示例 |
|---|---|---|
== | 等于 | distance == 100 |
!= | 不等于 | mode != "AUTO" |
> | 大于 | battery > 25 |
< | 小于 | value < 50 |
>= | 大于等于 | speed >= 0 |
<= | 小于等于 | power <= 1.0 |
⚠️ 易错提醒
比较相等用 ==,不是 =!= 是赋值符号!
3.2.2 逻辑运算符
它们用于连接多个布尔表达式,形成更复杂的判断逻辑。
| 运算符 | 含义 | 生活例子 | 代码示例 |
|---|---|---|---|
&& | 与 (AND) | “分数大于60 并且 小于100” | (score > 60) && (score < 100) |
|| | 或 (OR) | “年龄小于18 或者 大于65” | (age < 18) || (age > 65) |
! | 非 (NOT) | “不是 正数” | !(number > 0) |
运算优先级
! (非) 的优先级最高,其次是 && (与),最后是 || (或)。如果不确定,用括号 () 明确指定运算顺序是最好的习惯! (conditionA && conditionB) || conditionC
3.2.3 if - else 语句
这是实现分支最核心的语句。
if: 如果条件为真,就执行这里的代码。else if: 如果上面的if条件不满足,就检查这里的条件。else: 如果以上所有条件都不满足,就执行这里的代码。
if 结构
if-else 结构
if-else if-else 结构
java
/**
* if-else 语句示例:根据电池电量决定机器人状态。
*/
public class IfElseTest {
public static void main(String[] args) {
int battery = 55; // 假设当前电量为 55%
if (battery > 70) {
System.out.println("电量充足,状态:绿色");
} else if (battery > 20) {
System.out.println("电量较低,请准备充电,状态:黄色");
} else {
System.out.println("电量严重不足!即将自动关机,状态:红色");
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
字符串比较的陷阱
比较字符串的内容是否相等时,必须使用 .equals() 方法,绝对不能用 ==!
==比较的是两个引用变量是否指向内存中的同一个对象(比较地址)。.equals()比较的是两个字符串对象的内容是否完全一样。
java
String cmd1 = "stop";
String cmd2 = new String("stop");
System.out.println(cmd1 == cmd2); // false! 因为它们是两个不同的对象
System.out.println(cmd1.equals(cmd2)); // true! 因为它们的内容相同1
2
3
4
5
2
3
4
5
3.2.4 switch 语句
当你需要根据一个变量的多个不同取值来执行不同操作时,switch 语句通常比一长串的 if-else if 更清晰、更高效。
java
/**
* switch 语句示例:根据收到的指令执行不同动作。
*/
public class SwitchTest {
public static void main(String[] args) {
String command = "LEFT";
switch (command) {
case "FORWARD":
System.out.println("执行动作:前进");
break; // 如果没有 break,程序会继续执行下一个 case!
case "LEFT":
System.out.println("执行动作:左转");
break;
case "RIGHT":
System.out.println("执行动作:右转");
break;
case "STOP":
System.out.println("执行动作:停止");
break;
default: // 如果 command 的值不匹配任何一个 case
System.out.println("收到未知指令,保持原地");
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
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
`switch` 的关键点
break:break的作用是跳出整个switch结构。如果你忘记写break,程序会发生“穿透”,即执行完当前case后,会继续执行下面的case,直到遇到break或switch结束。- 支持的类型:
switch支持的变量类型包括int,byte,short,char,String, 和enum。 default:default是可选的,用于处理所有case都不匹配的情况,类似于if-else结构中的最后一个else。
🔥 官方推荐
Java 14+ 支持新式 switch 表达式,语法更简洁:
java
String action = switch (signal) {
case "green" -> "加速前进";
case "red" -> "立即停止";
case "yellow" -> "准备停止";
default -> "谨慎行驶";
};1
2
3
4
5
6
2
3
4
5
6
3.3 循环结构:重复执行任务
循环结构让代码可以重复执行,直到满足某个退出条件。这对于处理重复性任务至关重要,比如读取传感器数据、驱动马达转动一定圈数等。
一个标准的循环通常包含三个要素:
- 初始化:一个计数器变量的初始值。
- 循环条件:一个布尔表达式,决定循环是否继续。
- 更新:每次循环结束后,对计数器变量进行更新。
3.3.1 for 循环
当循环次数是已知的、固定的情况下,for 循环是最佳选择。它的结构非常紧凑,将初始化、条件和更新都写在了一起。
java
/**
* for 循环示例:检查传感器的每个读数。
*/
public class ForLoopTest {
public static void main(String[] args) {
// 假设有一个存储了 5 个传感器读数的数组
int[] readings = {25, 30, 150, 45, 28};
System.out.println("开始检查所有传感器...");
// for (初始化; 循环条件; 更新)
for (int i = 0; i < readings.length; i++) {
int value = readings[i];
System.out.print("传感器 " + (i + 1) + " 读数: " + value);
if (value > 100) {
System.out.println(" -> 警告!读数超限!");
} else {
System.out.println(" -> 正常");
}
}
System.out.println("所有传感器检查完毕。");
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
3.3.2 while 循环
当循环次数不确定,只知道一个持续循环的条件时,while 循环更合适。它会“先判断,后执行”。
java
/**
* while 循环示例:驱动机器人前进,直到距离传感器检测到障碍物。
*/
public class WhileTest {
public static void main(String[] args) {
int distance = 100; // 假设初始距离为 100cm
// 当距离大于 20cm 时,一直循环
while (distance > 20) {
System.out.println("当前距离: " + distance + "cm,继续前进...");
// 模拟机器人前进,距离每次减少 10cm
distance = distance - 10;
}
System.out.println("检测到障碍物!当前距离: " + distance + "cm,停止前进。");
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
警惕死循环!
使用 while 循环时,必须确保循环内部有代码能最终改变循环条件,使其变为 false。否则,程序将陷入“死循环”,永远无法结束,这会耗尽 CPU 资源!
3.3.3 do-while 循环
这种循环与 while 类似,但它是“先执行,后判断”。这意味着,无论条件是否为真,do-while 循环体内的代码至少会执行一次。
java
import java.util.Scanner;
/**
* do-while 循环示例:处理用户菜单输入。
* 至少要先显示一次菜单,再等待用户输入。
*/
public class DoWhileTest {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int choice;
do {
System.out.println("\n--- 机器人控制菜单 ---");
System.out.println("1. 前进");
System.out.println("2. 后退");
System.out.println("3. 停止");
System.out.println("0. 退出程序");
System.out.print("请输入你的选择: ");
choice = scanner.nextInt();
} while (choice != 0); // 只要用户输入的不是 0,就一直循环
System.out.println("程序已退出。");
}
}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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
3.3.4 循环控制:break 和 continue
break: 中断并完全跳出当前所在的整个循环。continue: 停止当前这一次循环,立即跳到下一次循环的开始。
java
/**
* break 和 continue 示例:在循环中寻找特定目标。
*/
public class BreakContinueTest {
public static void main(String[] args) {
int[] data = {10, 20, -5, 30, 99, 40, -8};
System.out.println("开始扫描数据...");
for (int value : data) {
if (value < 0) {
System.out.println("检测到无效数据(" + value + "),跳过。");
continue; // 跳过负数,继续下一次循环
}
if (value == 99) {
System.out.println("找到目标 99!停止扫描。");
break; // 找到目标,完全退出循环
}
System.out.println("处理数据: " + value);
}
System.out.println("扫描结束。");
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
3.4 课堂练习
练习 1:机器人自动避障
任务: 编写一个程序模拟机器人前进。
- 使用
for循环,模拟机器人从 1 米走到 10 米,每次前进 1 米。 - 在循环中,打印出“机器人前进到 X 米”。
- 当走到 7 米时,模拟检测到一个障碍物。使用
if语句判断,如果位置是 7,则打印“检测到障碍物!停止前进!”并使用break提前终止循环。
参考答案:
java
/**
* 练习1:机器人自动避障的参考答案
*/
public class Practice1 {
public static void main(String[] args) {
// 使用 for 循环,让变量 i 从 1 增加到 10
for (int i = 1; i <= 10; i++) {
// 打印出机器人当前的位置
System.out.println("机器人前进到 " + i + " 米");
// 使用 if 语句判断是否到达了 7 米的位置
if (i == 7) {
// 如果到达 7 米,就打印警告信息
System.out.println("检测到障碍物!停止前进!");
// 使用 break 关键字立即跳出整个 for 循环
break;
}
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
练习 2:计分器
任务: 编写一个计分程序。
- 创建一个
while(true)无限循环。 - 在循环内,使用
Scanner提示用户输入一个分数。 - 使用
if判断:如果用户输入-1,则打印“计分结束”并使用break退出循环。 - 使用
if判断:如果用户输入的分数小于 0 或大于 100,则打印“无效分数,请重新输入”并使用continue跳过本次加分。 - 如果分数有效,则将其累加到一个
totalScore变量中,并打印“分数已记录”。 - 循环结束后,打印出总分。
参考答案:
java
import java.util.Scanner;
/**
* 练习2:计分器的参考答案
*/
public class Practice2 {
public static void main(String[] args) {
// 创建一个 Scanner 对象来读取用户的键盘输入
Scanner scanner = new Scanner(System.in);
// 初始化总分变量为 0
int totalScore = 0;
// 使用 while(true) 创建一个无限循环
while (true) {
// 提示用户输入分数
System.out.print("请输入一个分数 (输入 -1 结束): ");
// 读取用户输入的整数
int score = scanner.nextInt();
// 判断用户是否输入了 -1,这是我们约定的退出信号
if (score == -1) {
// 如果是 -1,打印结束信息并使用 break 退出循环
System.out.println("计分结束。");
break;
}
// 判断输入的分数是否在 0 到 100 的有效范围内
// "||" 表示 "或者",所以 score < 0 或者 score > 100 都会进入这个 if
if (score < 0 || score > 100) {
// 如果分数无效,打印提示信息
System.out.println("无效分数,请重新输入。");
// 使用 continue 跳过本次循环的剩余部分,直接开始下一次循环
continue;
}
// 如果代码能执行到这里,说明分数是有效的
// 将有效分数累加到总分上
totalScore = totalScore + score;
// 打印确认信息
System.out.println("分数已记录。");
}
// 当循环结束后,打印出最终的总分
System.out.println("最终总分是: " + totalScore);
}
}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
39
40
41
42
43
44
45
46
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
39
40
41
42
43
44
45
46
