3.1 分支结构:if 与 switch
选择结构的考点集中在:写法、配对、switch 穿透。
// ① 单分支 / 双分支 / 多分支
if (score >= 60) {
System.out.println("及格");
} else if (score >= 40) {
System.out.println("补考");
} else {
System.out.println("重修");
}
// ② switch(JDK 7+ 支持 String)
switch (day) {
case 1:
System.out.println("周一");
break; // ← 没有 break 会「穿透」到下一个 case
case 2:
System.out.println("周二");
break;
default:
System.out.println("其他");
}
三条铁律
- else 与最近的未配对 if 配对(悬空 else 问题)——所以哪怕只有一行也建议写花括号。
- switch 的 case 后面通常要 break,否则继续执行下一个 case(穿透);故意利用穿透可以合并多个分支。
- switch 的表达式类型:byte/short/char/int、enum、String(JDK 7+);不支持 long、boolean、浮点。
易错
- 把
==写成=:if (a = 1)编译报错(Java 要求条件必须是 boolean,这点比 C++ 安全)。 - 判断相等用
==,判断字符串内容相等要用equals(第 5 章详讲)。 default可以放在任意位置,但建议放最后;没有匹配且无 default 时什么都不做。
课堂练习(3 题)
- switch 后面忘记写 break 会怎样? 答:发生"穿透",继续执行后续 case 的语句,直到遇到 break 或 switch 结束。
- 下列哪个能作为 switch 的表达式:A. long B. String C. double D. boolean 答:B(String,JDK 7+ 支持)。long、double、boolean 都不行。
- 把成绩转成等级(≥90 A,≥80 B,其余 C),用 else if 怎么写?
答:
if (s >= 90) g = 'A'; else if (s >= 80) g = 'B'; else g = 'C';
3.2 三种循环:for / while / do-while
先记住各自适用场景,再看 break/continue。
// ① for:次数已知(最常用)
for (int i = 0; i < 10; i++) { // 初始化; 条件; 更新
System.out.println(i); // i 的作用域只在循环内
}
// ② while:次数未知、先判断后执行
int n = 0;
while (n < 5) {
n++;
}
// ③ do-while:先执行一次再判断(至少执行一次)
int k = 0;
do {
k++;
} while (k < 3);
// ④ 增强 for(foreach):遍历数组/集合,不能改下标
int[] arr = {1, 2, 3};
for (int v : arr) {
System.out.println(v);
}
| 循环 | 适用场景 | 执行顺序 |
|---|---|---|
for | 次数确定、需要下标 | 初始化 → 判断 → 执行 → 更新 → 判断… |
while | 次数不确定(读到某值停止) | 先判断,条件为真才执行(可能一次都不执行) |
do-while | 至少要执行一次(如菜单交互) | 先执行一次,再判断(至少执行一次) |
for-each | 只读遍历,不需要下标 | 依次取出每个元素 |
易错
- while 后面别加多余分号:
while (n < 5);会变成死循环(分号就是空语句体)。 for里定义的i出了循环就不能用;循环外要用就先在外部声明。- 用
double做循环变量或判断相等会有精度误差:for (double x = 0; x != 1; x += 0.1)可能死循环。
课堂练习(3 题)
- while 与 do-while 最本质的区别是什么? 答:while 先判断后执行(可能零次),do-while 先执行一次再判断(至少一次)。
- 求 1+2+…+100,用 for 循环怎么写?
答:
int s = 0; for (int i = 1; i <= 100; i++) s += i;(结果 5050)。 for (int i = 0; i < 3; i++); System.out.println(i);有问题吗? 答:有两处问题——for 后多了分号(循环体变空);且 i 在循环外不可见,打印 i 会编译报错。
3.3 break / continue / 标签
跳出循环的三种手段,标签是 Java 比 C++ 多的一个东西。
for (int i = 1; i <= 10; i++) {
if (i == 3) continue; // 跳过本次,进入下一轮
if (i == 6) break; // 直接结束整个循环
System.out.print(i + " ");
}
// 输出:1 2 4 5
// 带标签的 break:一次跳出多层嵌套循环
outer:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i * j > 1) {
break outer; // 跳出 outer 标记的那一层
}
System.out.println(i + "," + j);
}
}
区别一句话
- break:结束整个循环;continue:跳过本次循环体剩余部分,直接下一轮。
- continue 只跳过当前循环(在 for 里会先执行"更新"语句再判断)。
- 标签写法是
标签名:放在循环前,配合break 标签名/continue 标签名用。
课堂练习(2 题)
- 循环 1~10,遇到 5 就跳过、遇到 8 就停止,输出序列是什么? 答:1 2 3 4 6 7(5 被 continue 跳过,8 处 break 结束)。
- 想在嵌套循环中直接跳出最外层,Java 提供什么机制?
答:标签(label)——在外层循环前写
outer:,内层用break outer;。
3.4 综合示例:判断素数(把前面串起来)
一个例子练完分支+循环+break,建议自己在沙盒里敲一遍。
import java.util.Scanner;
public class Prime {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("请输入一个大于 1 的整数:");
int n = sc.nextInt();
boolean isPrime = true;
for (int i = 2; i * i <= n; i++) { // 只需试除到 sqrt(n)
if (n % i == 0) {
isPrime = false;
break; // 找到因子即可停止
}
}
if (isPrime) {
System.out.println(n + " 是素数");
} else {
System.out.println(n + " 不是素数");
}
sc.close();
}
}
这段代码里值得记住的三点
- 循环条件写
i * i <= n而不是i <= Math.sqrt(n)——避免浮点运算,也更快。 - 用 boolean 标志位记录结果,比在循环里直接打印更清晰。
- 找到因子立刻
break,不要傻傻除到底。
易错
- 边界:1 不是素数、2 是素数;负数和非整数输入要先判断。
- 循环从
i = 2开始,别从 1 开始(任何数都能被 1 整除)。
直接在 Java 在线运行环境 里跑一遍,改改数字试试。
课堂练习(3 题)
- 为什么试除只要到 √n 就够了? 答:若 n = a × b 且 a ≤ b,则 a ≤ √n;大于 √n 的因子必然有对应小因子已被检查到。
- 把上面程序改成"输出 100 以内所有素数",大致思路是什么? 答:外层循环 2~100,内层用同样的试除判断,是素数就打印(或抽成 isPrime 方法)。
- 输入 1 时程序会输出什么?是否符合预期?
答:循环不执行,isPrime 保持 true,输出"1 是素数"——这是错误的,需在开头加判断
if (n < 2) isPrime = false;。