第1章:流程控制(一)—— 顺序结构、选择结构与键盘输入

各位同学,欢迎来到流程控制的第一课。

说实话,编程这件事,如果只是从上到下写代码,那跟列购物清单没啥区别。真正让程序“活”起来的,是流程控制。它让代码能判断、能选择、能走不同的路。今天我们就来聊聊最基础的那几种。

1.1 顺序结构——最老实的一种写法

顺序结构,说白了就是代码从上往下,一行一行执行。

你写的第一行代码先跑,第二行再跑,第三行接着跑。没有跳转,没有分支,没有循环。就像你早上起床:先睁眼,再坐起来,然后穿鞋。顺序不能乱。

核心要点:顺序结构是程序默认的执行方式。你不需要写任何特殊关键字,代码自然就是顺序执行的。

public class SequenceDemo {
    public static void main(String[] args) {
        System.out.println("第一步:打开冰箱");
        System.out.println("第二步:把大象放进去");
        System.out.println("第三步:关上冰箱");
    }
}

输出结果就是三行文字,按顺序打印。嗯,就这么简单。

小提示:顺序结构虽然简单,但它是所有复杂逻辑的基石。你想想看,if语句里、循环里,最终执行的还是顺序结构。

1.2 选择结构——让代码学会“思考”

现实世界不是线性的。你会遇到岔路口,程序也一样。选择结构就是让程序在某个节点做出判断,然后走不同的路。

1.2.1 if 语句——最简单的判断

if 语句,就是“如果……就……”。条件成立,执行代码;不成立,跳过。

int score = 85;
if (score >= 60) {
    System.out.println("恭喜,及格了!");
}

这里 score 是 85,大于等于 60,所以会打印那句话。如果 score 是 58,那就什么都不打印。

注意:if 后面跟的是布尔表达式。也就是说,结果只能是 true 或 false。我曾经见过新手写成 if (score = 60),这在 Java 里是编译错误,因为赋值操作返回的是值本身,不是布尔值。

1.2.2 if-else 语句——两条路选一条

if-else 就是“如果……否则……”。条件成立走 if,不成立走 else。两条路,必选其一。

int age = 17;
if (age >= 18) {
    System.out.println("你已经成年了");
} else {
    System.out.println("你还未成年");
}

age 是 17,所以走 else 分支,打印“你还未成年”。

我个人习惯在 if 和 else 的代码块里都加上花括号,哪怕只有一行代码。为什么?因为后期维护时,你很可能想再加一行,有花括号就不容易出错。

1.2.3 if-else if-else 结构——多岔路口

当判断条件不止两个时,就需要 if-else if-else 了。它像是一个多岔路口,从上往下依次判断,遇到第一个 true 的条件就执行对应的代码块,然后跳出整个结构。

int score = 85;
if (score >= 90) {
    System.out.println("优秀");
} else if (score >= 80) {
    System.out.println("良好");
} else if (score >= 70) {
    System.out.println("中等");
} else if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格");
}

score 是 85,第一个条件 85 >= 90 不成立,继续往下。第二个条件 85 >= 80 成立,打印“良好”,然后直接跳出整个 if-else if-else 结构。后面的条件不会再判断了。

关键点:if-else if-else 结构是“互斥”的。一旦某个条件满足,后面的所有条件都会被忽略。所以条件的顺序很重要。我曾经在项目中遇到过把范围写反的情况,导致永远走不到正确的分支,调试了半天才发现是顺序问题。

1.3 switch 语句——另一种选择方式

switch 语句,说白了就是“多路开关”。它根据一个变量的值,跳转到对应的 case 分支去执行。

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;
    default:
        System.out.println("周末");
        break;
}

day 是 3,所以匹配到 case 3,打印“星期三”。

重要提醒:每个 case 后面都要加 break;,否则会发生“穿透”现象。什么叫穿透?就是匹配到 case 3 后,它会继续执行 case 4、case 5 的代码,直到遇到 break 或 switch 结束。我刚开始学的时候吃过这个亏,输出结果完全不对。

switch 支持的数据类型有:byte、short、int、char、String(Java 7 开始支持)、枚举类型。float 和 double 不行,因为浮点数有精度问题,不适合做精确匹配。

小技巧:如果你有多个 case 执行相同的代码,可以故意利用穿透来简化代码。比如判断星期几是工作日还是休息日:

int day = 6;
switch (day) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
        System.out.println("工作日");
        break;
    case 6:
    case 7:
        System.out.println("休息日");
        break;
    default:
        System.out.println("非法输入");
        break;
}

你看,case 1 到 case 5 都没有 break,它们会一直穿透到 case 5 后面的 break 才停止。这样写代码更简洁。

1.4 Scanner 键盘输入——让程序跟用户对话

到目前为止,我们的程序都是“自说自话”。数据写死在代码里,用户没法参与。Scanner 就是用来解决这个问题的。它让程序能读取用户在键盘上输入的内容。

import java.util.Scanner;

public class ScannerDemo {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("请输入你的名字:");
        String name = scanner.nextLine();
        
        System.out.print("请输入你的年龄:");
        int age = scanner.nextInt();
        
        System.out.println("你好," + name + ",你今年" + age + "岁了。");
        
        scanner.close();
    }
}

运行这段代码,程序会停下来等你输入。你输入完按回车,程序继续往下走。

使用步骤:

  1. 导入 java.util.Scanner
  2. 创建 Scanner 对象:Scanner scanner = new Scanner(System.in);
  3. 调用方法读取输入:nextLine() 读字符串,nextInt() 读整数,nextDouble() 读小数
  4. 使用完后关闭:scanner.close();

避坑指南:我曾经在项目中遇到过一个问题——用 nextInt() 读取整数后,紧接着用 nextLine() 读取字符串,结果发现字符串直接跳过了。为什么?因为 nextInt() 只读取了数字,但把换行符留在了缓冲区。紧接着的 nextLine() 读到这个换行符,以为输入结束了。解决办法是在 nextInt() 后面加一个 scanner.nextLine() 来消耗掉这个换行符。

1.5 综合案例——成绩等级判断器

我们把今天学的东西串起来,写一个完整的程序:用户输入成绩,程序输出等级。

import java.util.Scanner;

public class GradeJudge {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        System.out.print("请输入你的成绩(0-100):");
        int score = scanner.nextInt();
        
        if (score < 0 || score > 100) {
            System.out.println("成绩必须在0到100之间");
        } else if (score >= 90) {
            System.out.println("等级:A");
        } else if (score >= 80) {
            System.out.println("等级:B");
        } else if (score >= 70) {
            System.out.println("等级:C");
        } else if (score >= 60) {
            System.out.println("等级:D");
        } else {
            System.out.println("等级:F");
        }
        
        scanner.close();
    }
}

这个程序用到了 Scanner 读取输入,用 if-else if-else 做多分支判断,还加了一个边界检查(成绩必须在 0 到 100 之间)。

扩展思考:如果让你用 switch 来实现同样的功能,你会怎么做?提示:可以把成绩除以 10,然后对整数部分做 switch。试试看。

本章小结

今天我们学了四样东西:

  • 顺序结构——代码从上往下执行,最基础
  • if 系列——if、if-else、if-else if-else,用于条件判断
  • switch 语句——根据值做多路分支,注意 break 防止穿透
  • Scanner 键盘输入——让程序能跟用户交互

这些是流程控制的入门内容。下一章我们会讲循环结构,到时候代码就能重复执行了,那才是真正解放生产力的开始。

好了,今天的课就到这里。记得多敲代码,光看是学不会的。有什么问题,我们下节课见。


公众号:蓝海资料掘金营,微信deep3321