你好,欢迎回到 Java 零基础学习系列!
在前几篇中,我们学习了变量、数据类型、运算符以及计算机底层的进制与位运算。现在我们已经能够定义数据并进行基本运算,但程序只能从上到下顺序执行,这远远不够。为了让程序具备“思考”和“重复劳动”的能力,我们需要 程序控制结构。
今天我们将深入 选择结构(if、switch)、循环结构(for、while、do-while)以及 跳转语句(break、continue、return)。掌握了它们,你就能写出真正有逻辑、可复用的程序。
1. 程序流程控制概述
程序的执行流程分为三种基本结构:
- 顺序结构:程序自上而下逐行执行,这是默认方式。
- 选择结构:根据条件决定执行哪些代码(如岔路口)。
- 循环结构:重复执行某段代码(如跑步绕圈)。
2. 选择结构
2.1 if 语句
2.1.1 单分支 if
语法:
if (条件表达式) {
// 条件为 true 时执行的代码块
}
示例:
int age = 18;
if (age >= 18) {
System.out.println("你已经成年了!");
}
2.1.2 双分支 if-else
语法:
if (条件表达式) {
// 条件为 true 时执行
} else {
// 条件为 false 时执行
}
示例:
int score = 85;
if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
2.1.3 多分支 if-else if
语法:
if (条件1) {
// 条件1为 true
} else if (条件2) {
// 条件1为 false 且条件2为 true
} else if (条件3) {
// 条件1、2为 false 且条件3为 true
} else {
// 所有条件均为 false
}
示例:根据分数评级
int score = 85;
if (score >= 90) {
System.out.println("优秀");
} else if (score >= 80) {
System.out.println("良好");
} else if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}
注意:条件判断是自上而下的,一旦某个条件满足,后续的 else if 将不再判断。
2.1.4 嵌套 if
if 内部可以再嵌套 if,用于处理更复杂的条件。
int age = 20;
boolean hasTicket = true;
if (age >= 18) {
if (hasTicket) {
System.out.println("请入场");
} else {
System.out.println("请先购票");
}
} else {
System.out.println("未成年禁止入内");
}
2.2 switch 语句
当需要根据一个变量的多个可能值进行分支时,switch 比 if-else if 更清晰。
语法:
switch (表达式) {
case 值1:
// 代码块
break;
case 值2:
// 代码块
break;
...
default:
// 所有 case 都不匹配时执行
break;
}
注意:
- 表达式类型可以是 byte、short、int、char、String(JDK 7+)、枚举。
- case 后的值必须是常量或字面量,不能是变量。
- 每个 case 后通常要加
break,否则会“穿透”执行下一个 case(直到遇到 break 或 switch 结束)。 default可选,放在最后(位置可调,但建议放最后)。
示例:根据星期数输出中文
int day = 3;
switch (day) {
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,程序会继续向下执行直到遇到 break 或结束。利用穿透可以简化代码:
int month = 3;
switch (month) {
case 3:
case 4:
case 5:
System.out.println("春季");
break;
case 6:
case 7:
case 8:
System.out.println("夏季");
break;
// ... 其他季节
}
2.3 if 与 switch 的选择
- if:适合范围判断(如
score >= 60)或复杂逻辑组合。 - switch:适合等值判断(如
day == 1),且分支较多时更清晰。
3. 循环结构
循环用于重复执行一段代码,直到条件不满足。
3.1 while 循环
语法:
while (条件表达式) {
// 循环体
}
先判断条件,如果为 true,执行循环体;然后再次判断,直到条件为 false 退出。
示例:计算 1 到 10 的和
int i = 1;
int sum = 0;
while (i <= 10) {
sum += i; // sum = sum + i
i++;
}
System.out.println("1~10 的和:" + sum);
3.2 do-while 循环
语法:
do {
// 循环体
} while (条件表达式);
先执行一次循环体,再判断条件,条件为 true 则继续循环。至少执行一次。
示例:猜数字游戏(先玩一次,再问是否继续)
int secret = 42;
int guess;
Scanner scanner = new Scanner(System.in);
do {
System.out.print("猜一个数字:");
guess = scanner.nextInt();
if (guess > secret) {
System.out.println("太大了");
} else if (guess < secret) {
System.out.println("太小了");
}
} while (guess != secret);
System.out.println("恭喜猜对了!");
3.3 for 循环
for 循环将初始化、条件判断、迭代更新集中在一起,语法清晰。
语法:
for (初始化语句; 条件表达式; 迭代语句) {
// 循环体
}
执行顺序:
- 执行初始化语句(仅一次)。
- 判断条件,若为 true 执行循环体;否则退出。
- 执行迭代语句,回到第 2 步。
示例:同样计算 1~10 的和
int sum = 0;
for (int i = 1; i <= 10; i++) {
sum += i;
}
System.out.println("1~10 的和:" + sum);
for 循环的多种写法
- 初始化部分可以定义多个变量:
for (int i = 0, j = 0; ...)。 - 迭代部分可以有多个操作:
for (int i = 0; i < 10; i++, j--)。 - 三个部分都可以为空,但分号不能少:
for (;;)是死循环。
3.4 增强 for 循环(foreach)
用于遍历数组或集合,语法简洁,但不能修改索引。
语法:
for (元素类型 变量名 : 数组或集合) {
// 循环体
}
示例:
int[] numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
System.out.println(num);
}
后面学到数组和集合时会深入,这里先了解。
3.5 循环嵌套
循环内部可以嵌套其他循环,常用于打印图形、处理二维数组等。
示例:打印九九乘法表
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(); // 换行
}
4. 跳转语句
跳转语句可以改变程序的执行流程,包括 break、continue 和 return。
4.1 break
- 在 switch 中用于跳出 switch。
- 在循环中用于立即终止当前循环,执行循环后的代码。
示例:找到第一个能被 7 整除的数
for (int i = 1; i <= 100; i++) {
if (i % 7 == 0) {
System.out.println("第一个能被7整除的数:" + i);
break; // 找到后立即结束循环
}
}
带标签的 break
可以跳出外层循环(嵌套循环时很有用)。
语法:在循环前定义标签(标签名:),然后 break 标签名;。
示例:跳出双层循环
outer: // 标签
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (i * j > 6) {
System.out.println("i=" + i + ", j=" + j);
break outer; // 直接跳出外层循环
}
}
}
// 执行到这里时,内外循环都结束了
4.2 continue
- 只能在循环中使用。
- 跳过本次循环剩余部分,直接进入下一次迭代。
示例:打印 1~10 中所有奇数
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
continue; // 偶数跳过,不打印
}
System.out.println(i);
}
continue 也可以带标签,用于跳过外层循环的当前迭代(较少用)。
4.3 return
- 用于从当前方法退出,返回调用者。
- 如果方法有返回值,return 后必须带返回值;如果方法为 void,可以只写
return;(也可省略,方法末尾自动 return)。
示例:
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
if (i == 3) {
return; // 直接结束 main 方法,后面不再执行
}
System.out.println(i);
}
System.out.println("循环结束"); // 这一行不会执行,因为 return 了
}
5. 综合示例:猜数字游戏
下面我们综合运用今天所学,实现一个简单的猜数字游戏(1~100),并加入限制次数、提示范围等功能。
import java.util.Scanner;
/**
* 猜数字游戏:程序随机生成1~100之间的整数,用户猜测,提示“太大”“太小”,直到猜对或达到最大次数。
*/
public class GuessNumber {
public static void main(String[] args) {
// 生成随机数(1~100)
int secret = (int) (Math.random() * 100) + 1;
Scanner scanner = new Scanner(System.in);
int guess;
int attempts = 0;
int maxAttempts = 7; // 最多猜7次
System.out.println("欢迎来到猜数字游戏!");
System.out.println("我已经想好了一个1~100之间的整数,你有" + maxAttempts + "次机会。");
while (attempts < maxAttempts) {
System.out.print("请输入你的猜测(剩余次数 " + (maxAttempts - attempts) + "):");
guess = scanner.nextInt();
attempts++;
if (guess < secret) {
System.out.println("太小了!");
} else if (guess > secret) {
System.out.println("太大了!");
} else {
System.out.println("恭喜你,猜对了!数字就是 " + secret + ",你用了 " + attempts + " 次。");
break; // 猜对退出循环
}
// 如果最后一次还没猜对,提示失败
if (attempts == maxAttempts) {
System.out.println("很遗憾,机会用完了。正确的数字是 " + secret);
}
}
scanner.close();
System.out.println("游戏结束。");
}
}
6. 常见错误与注意事项
- if 条件忘记括号:if 后面必须跟布尔表达式,不能是赋值语句(如
if (a = 5)会编译错误)。 - switch 缺少 break:导致穿透,可能执行多个 case,需根据需求是否利用穿透。
- 死循环:循环条件永远为 true,且没有 break 跳出。例如
while (true) { ... }要有退出机制。 - 循环变量更新遗漏:比如 while 中忘记写
i++,导致死循环。 - 作用域问题:在 for 初始化中定义的变量,只能在循环内使用。
- 分号位置:如
for (int i=0; i<10; i++);多了一个分号,循环体为空,后面的代码块只执行一次。
7. 总结与下期预告
今天我们学习了程序的“大脑”——控制结构:
- 选择结构:if 和 switch,让程序能根据条件做决策。
- 循环结构:while、do-while、for,让程序能重复执行。
- 跳转语句:break、continue、return,灵活控制流程。
通过这些语句,我们已经可以编写出有一定复杂度的程序了,比如猜数字游戏。
下一篇我们将学习 数组——用来存储多个相同类型数据的容器。数组结合循环,能发挥巨大威力,比如处理大量数据、排序、查找等。
动手实践:
- 用 if-else 编写一个程序,根据月份输出季节(3-5 春季,6-8 夏季,9-11 秋季,12-2 冬季)。
- 用 for 循环打印一个直角三角形(星号组成)。
- 用 while 循环实现一个简单的计算器,让用户反复输入两个数和运算符,直到输入“quit”退出。
- 尝试修改猜数字游戏,加入“继续玩”的功能(do-while 控制是否再来一局)。
如果遇到问题,欢迎在评论区留言。我们下期见! 🚀