Skip to content

第3课:控制流

🎯 学习目标

  • 掌握 if-else、switch 条件语句
  • 掌握 for、while、do-while 循环
  • 理解 break、continue、return 的使用
  • 理解嵌套循环和循环优化

📖 一、if-else 条件语句

1. 基本语法

java
// 单分支
if (条件) {
    // 条件为 true 时执行
}

// 双分支
if (条件) {
    // 条件为 true
} else {
    // 条件为 false
}

// 多分支
if (条件1) {
    // 条件1 为 true
} else if (条件2) {
    // 条件2 为 true
} else {
    // 所有条件都为 false
}

2. 实例

java
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("不及格");
}

3. 注意事项

⚠️ 陷阱1:悬空 else

java
int x = 5;
if (x > 0)
    if (x > 10)
        System.out.println("大于10");
else  // else 属于内层 if,不是外层!
    System.out.println("小于等于10");

// 正确写法:使用花括号
if (x > 0) {
    if (x > 10) {
        System.out.println("大于10");
    }
} else {
    System.out.println("小于等于0");
}

⚠️ 陷阱2:赋值 vs 比较

java
int x = 5;
if (x = 10) {  // ❌ 编译错误!Java 不允许
    // ...
}

// C 语言允许这样写,Java 不允许(更安全)

💡 最佳实践

java
// ✅ 推荐:常量写在左边(防止误写成赋值)
if (10 == x) { }

// ✅ 推荐:始终使用花括号
if (x > 0) {
    System.out.println(x);
}

// ❌ 不推荐:单行不加花括号
if (x > 0) System.out.println(x);

📖 二、switch 语句

1. 基本语法

java
switch (表达式) {
    case 值1:
        // 语句
        break;
    case 值2:
        // 语句
        break;
    default:
        // 默认语句
}

2. 实例

java
int day = 3;
String dayName;

switch (day) {
    case 1:
        dayName = "星期一";
        break;
    case 2:
        dayName = "星期二";
        break;
    case 3:
        dayName = "星期三";
        break;
    case 4:
        dayName = "星期四";
        break;
    case 5:
        dayName = "星期五";
        break;
    case 6:
    case 7:  // 多个 case 共享代码
        dayName = "周末";
        break;
    default:
        dayName = "无效日期";
}

3. switch 支持的类型

java
// ✅ 支持的类型:
// - 整数类型:byte, short, int
// - 包装类:Byte, Short, Integer
// - 枚举类型:enum
// - 字符串:String(Java 7+)

// 示例:字符串 switch
String fruit = "apple";
switch (fruit) {
    case "apple":
        System.out.println("苹果");
        break;
    case "banana":
        System.out.println("香蕉");
        break;
    default:
        System.out.println("其他水果");
}

// ❌ 不支持:long, float, double, boolean

4. switch 表达式(Java 12+)

java
// 传统写法
int day = 3;
String dayType;
switch (day) {
    case 1, 2, 3, 4, 5:
        dayType = "工作日";
        break;
    case 6, 7:
        dayType = "周末";
        break;
    default:
        dayType = "无效";
}

// 新写法(Java 12+)
String dayType = switch (day) {
    case 1, 2, 3, 4, 5 -> "工作日";
    case 6, 7 -> "周末";
    default -> "无效";
};

⚠️ case 穿透陷阱

java
int x = 1;
switch (x) {
    case 1:
        System.out.println("1");
        // 缺少 break,会继续执行下一个 case
    case 2:
        System.out.println("2");
        break;
}
// 输出:1 和 2(穿透)

📖 三、for 循环

1. 基本语法

java
for (初始化; 条件; 更新) {
    // 循环体
}

// 执行顺序:
// 1. 初始化(只执行一次)
// 2. 判断条件
// 3. 执行循环体
// 4. 执行更新
// 5. 回到步骤2

2. 实例

java
// 打印 1 到 10
for (int i = 1; i <= 10; i++) {
    System.out.println(i);
}

// 倒序打印
for (int i = 10; i >= 1; i--) {
    System.out.println(i);
}

// 步长为2
for (int i = 0; i < 10; i += 2) {
    System.out.println(i);  // 0, 2, 4, 6, 8
}

// 多变量
for (int i = 0, j = 10; i < j; i++, j--) {
    System.out.println("i=" + i + ", j=" + j);
}

// 无限循环
for (;;) {
    System.out.println("无限循环");
    break;  // 需要 break 退出
}

3. 增强 for 循环(for-each)

java
int[] numbers = {1, 2, 3, 4, 5};

// 传统 for
for (int i = 0; i < numbers.length; i++) {
    System.out.println(numbers[i]);
}

// 增强 for(更简洁)
for (int num : numbers) {
    System.out.println(num);
}

// 字符串数组
String[] names = {"Alice", "Bob", "Charlie"};
for (String name : names) {
    System.out.println(name);
}

⚠️ 增强 for 的限制

java
// ❌ 无法修改数组元素
for (int num : numbers) {
    num = 0;  // 只修改了副本,不影响原数组
}

// ❌ 无法获取索引
for (int num : numbers) {
    // 不知道当前是第几个元素
}

// ✅ 需要索引时用传统 for
for (int i = 0; i < numbers.length; i++) {
    numbers[i] = 0;  // 可以修改
}

📖 四、while 循环

1. 基本语法

java
while (条件) {
    // 循环体
}

// 先判断条件,再执行
// 条件为 false 时,可能一次都不执行

2. 实例

java
// 打印 1 到 10
int i = 1;
while (i <= 10) {
    System.out.println(i);
    i++;
}

// 计算阶乘
int n = 5;
int factorial = 1;
int j = 1;
while (j <= n) {
    factorial *= j;
    j++;
}
System.out.println(n + "! = " + factorial);  // 120

// 读取输入直到输入 0
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
while (num != 0) {
    System.out.println("你输入了: " + num);
    num = scanner.nextInt();
}

📖 五、do-while 循环

1. 基本语法

java
do {
    // 循环体
} while (条件);

// 先执行,再判断条件
// 至少执行一次

2. while vs do-while

java
// while:可能一次都不执行
int x = 10;
while (x < 5) {
    System.out.println("while: " + x);  // 不会执行
}

// do-while:至少执行一次
int y = 10;
do {
    System.out.println("do-while: " + y);  // 执行一次
} while (y < 5);

3. 典型应用:菜单程序

java
Scanner scanner = new Scanner(System.in);
int choice;
do {
    System.out.println("=== 菜单 ===");
    System.out.println("1. 选项1");
    System.out.println("2. 选项2");
    System.out.println("0. 退出");
    System.out.print("请选择: ");
    choice = scanner.nextInt();
    
    switch (choice) {
        case 1:
            System.out.println("执行选项1");
            break;
        case 2:
            System.out.println("执行选项2");
            break;
        case 0:
            System.out.println("退出程序");
            break;
        default:
            System.out.println("无效选择");
    }
} while (choice != 0);

📖 六、break、continue、return

1. break - 跳出循环

java
// 跳出最近的循环
for (int i = 1; i <= 10; i++) {
    if (i == 5) {
        break;  // 跳出循环
    }
    System.out.println(i);  // 输出 1, 2, 3, 4
}

// 带标签的 break(跳出外层循环)
outer:
for (int i = 1; i <= 3; i++) {
    for (int j = 1; j <= 3; j++) {
        if (i == 2 && j == 2) {
            break outer;  // 跳出外层循环
        }
        System.out.println("i=" + i + ", j=" + j);
    }
}

2. continue - 跳过当前迭代

java
// 跳过偶数
for (int i = 1; i <= 10; i++) {
    if (i % 2 == 0) {
        continue;  // 跳过本次迭代
    }
    System.out.println(i);  // 输出奇数:1, 3, 5, 7, 9
}

// 带标签的 continue
outer:
for (int i = 1; i <= 3; i++) {
    for (int j = 1; j <= 3; j++) {
        if (j == 2) {
            continue outer;  // 跳到外层循环的下一次迭代
        }
        System.out.println("i=" + i + ", j=" + j);
    }
}

3. return - 退出方法

java
public static int findIndex(int[] arr, int target) {
    for (int i = 0; i < arr.length; i++) {
        if (arr[i] == target) {
            return i;  // 找到后立即返回
        }
    }
    return -1;  // 未找到
}

📖 七、嵌套循环

1. 二重循环

java
// 打印九九乘法表
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();
}

// 打印图形
for (int i = 1; i <= 5; i++) {
    for (int j = 1; j <= i; j++) {
        System.out.print("*");
    }
    System.out.println();
}
/*
输出:
*
**
***
****
*****
*/

2. 性能考虑

java
// ❌ 低效:重复计算
for (int i = 0; i < arr.length; i++) {
    for (int j = 0; j < arr.length; j++) {
        // arr.length 每次都计算
    }
}

// ✅ 高效:提前计算
int len = arr.length;
for (int i = 0; i < len; i++) {
    for (int j = 0; j < len; j++) {
        // ...
    }
}

💡 实用技巧

1. 提前退出

java
// ❌ 低效:检查所有元素
boolean found = false;
for (int i = 0; i < arr.length; i++) {
    if (arr[i] == target) {
        found = true;
    }
}

// ✅ 高效:找到后立即退出
boolean found = false;
for (int i = 0; i < arr.length; i++) {
    if (arr[i] == target) {
        found = true;
        break;
    }
}

2. 避免无限循环

java
// ⚠️ 死循环
int i = 0;
while (i < 10) {
    System.out.println(i);
    // 忘记 i++,永远不会结束
}

// ✅ 正确
int i = 0;
while (i < 10) {
    System.out.println(i);
    i++;
}

🆚 for vs while 选择指南

场景推荐理由
已知循环次数for更清晰
未知循环次数while更自然
遍历数组/集合for/for-each简洁
读取输入while灵活
至少执行一次do-while保证执行

📝 练习预告

完成 练习/Ex03_ControlFlow.java

  1. if-else 多分支判断
  2. switch 多选择
  3. for 循环打印图形
  4. while 循环应用
  5. break/continue 控制
  6. 综合:素数判断、阶乘计算

🎓 下一步

  • 第4课:数组 - 一维数组、多维数组、Arrays工具类