教材对应:耿祥义《Java面向对象程序设计(第4版·微课版)》第3章
核心内容:运算符优先级、逻辑短路、switch穿透、循环结构、素数判断、阶乘累加、完数、最大公约数等
实验环境:VS Code + JDK 17

如果本篇博客对你有帮助,欢迎点赞、收藏、关注,支持我产出更多优质内容! ❤️


一、本章知识点速览(考试重点)

知识点 关键点
逻辑运算符 短路 &&|| 与非短路 &|
switch 语句 穿透(fall-through)、支持 char/int/枚举/String
循环结构 forwhiledo-while 的区别与适用场景
算法 素数判断(优化到平方根)、完数、数字逆序、阶乘递推、最大公约数(辗转相除法)
类型转换 字符与整数互转、浮点除法必须用 1.0
控制语句 break 与 continue 的区别

二、第4题:阅读程序题(4个小题)

题4.1 —— 逻辑或短路(||

代码Quiz4_1_LogicOrShortCircuit.java

/**
 * 第4题(1) - 逻辑或短路
 * 考察 || 左边为 true 时右边不计算
 * 预期输出: truehello10
 */
public class Quiz4_1_LogicOrShortCircuit {
    public static void main(String[] args) {
        boolean boo = false;
        int x = -1;
        // 左边 (x=10)>9 为 true,右边不再执行,x 保持 10
        boo = ((x = 10) > 9) || ((x = 100) > 99);
        System.out.println(boo + "hello" + x); // truehello10
    }
}

运行结果

truehello10

📸 截图1:在 VS Code 中运行 Quiz4_1_LogicOrShortCircuit.java 的终端输出截图。


题4.2 —— 非短路或(|

代码Quiz4_2_NonShortCircuitOr.java

/**
 * 第4题(2) - 非短路或(单个|)
 * 考察 | 左右两边都执行,右边会覆盖 x 的值
 * 预期输出: truehello100
 */
public class Quiz4_2_NonShortCircuitOr {
    public static void main(String[] args) {
        boolean boo = false;
        int x = -1;
        // 单个 | 不短路,左右都执行,最终 x=100
        boo = ((x = 10) > 9) | ((x = 100) > 99);
        System.out.println(boo + "hello" + x);
    }
}

运行结果

truehello100

📸 截图2:运行 Quiz4_2_NonShortCircuitOr.java 的终端输出截图。


题4.3 —— 循环逆序数字(123 → 321)

代码Quiz4_3_ReverseNumber.java

/**
 * 第4题(3) - 逆序数字
 * 利用 %10 取个位,/10 去掉个位,位权累加
 * 预期输出: 321
 */
public class Quiz4_3_ReverseNumber {
    public static void main(String[] args) {
        int m = 123;      // 原数字
        int sum = 0;      // 逆序结果
        int t = 100;      // 初始位权(百位)
        while (t > 0) {
            sum = sum + (m % 10) * t;   // 个位 * 位权
            m = m / 10;                 // 去掉个位
            t = t / 10;                 // 位权降级
        }
        System.out.printf("%d", sum);
    }
}

运行结果

321

📸 截图3:运行 Quiz4_3_ReverseNumber.java 的终端输出截图。


题4.4 —— switch 穿透

代码Quiz4_4_SwitchPenetration.java

/**
 * 第4题(4) - switch 穿透
 * 考察无 break 时的穿透现象
 * 预期输出: 5
 */
public class Quiz4_4_SwitchPenetration {
    public static void main(String[] args) {
        int m = 0;
        char ch = 'A';          // 'A' 的码点为 65
        switch (ch) {
            case 9:
            case 'a':
                m = m + 1;
            case 'A':           // 匹配
                m = m + 1;      // m=1,无 break,穿透
            case 66:            // 继续执行
                m = m + 1;      // m=2,穿透
            default:
                m = m + 3;      // m=5
        }
        System.out.println(m);
    }
}

运行结果

5

📸 截图4:运行 Quiz4_4_SwitchPenetration.java 的终端输出截图。


三、第5题:编程题(7个小题)

题5.1 —— 输出俄文字母表(а 到 я)

代码Quiz5_1_RussianAlphabet.java

/**
 * 第5题(1) - 输出俄文字母表(а ~ я)
 * 利用 Unicode 连续性,每10个换行
 * 需要 UTF-8 编码保存,控制台支持俄文字体
 */
public class Quiz5_1_RussianAlphabet {
    public static void main(String[] args) {
        char cStart = 'а';      // 俄文字母 а (Unicode 1072)
        char cEnd = 'я';        // 俄文字母 я (Unicode 1103)
        int startPos = (int) cStart;
        int endPos = (int) cEnd;
        System.out.println("俄文字母表:");
        for (int i = startPos; i <= endPos; i++) {
            char c = (char) i;
            System.out.print(" " + c);
            if ((i - startPos + 1) % 10 == 0) {
                System.out.println();
            }
        }
    }
}

运行结果

俄文字母表:
 а б в г д е ж з и й
 к л м н о п р с т у
 ф х ц ч ш щ ъ ы ь э ю я

📸 截图5:运行 Quiz5_1_RussianAlphabet.java 的控制台输出截图(可能需支持俄文显示)。


题5.2 —— 求 1! + 2! + ... + 20!

代码Quiz5_2_FactorialSum.java

/**
 * 第5题(2) - 计算 1! + 2! + ... + 20!
 * 使用 while 循环递推阶乘,结果用 double 存储(避免溢出)
 * 预期输出: 2.5613274941118203E18
 */
public class Quiz5_2_FactorialSum {
    public static void main(String[] args) {
        double sum = 0;
        double fact = 1;
        int i = 1;
        while (i <= 20) {
            sum = sum + fact;   // 累加当前阶乘
            i++;
            fact = fact * i;    // 更新为下一个阶乘
        }
        System.out.println("sum=" + sum);
    }
}

运行结果

sum=2.5613274941118203E18

📸 截图6:运行 Quiz5_2_FactorialSum.java 的终端输出截图。


题5.3 —— 100以内素数(j/2边界版)

代码Quiz5_3_PrimeNumbers.java

/**
 * 第5题(3) - 输出100以内的素数(使用 j/2 边界)
 * 利用循环后 i 的值判断是否提前 break
 * 预期输出: 2 3 5 7 11 ... 97
 */
public class Quiz5_3_PrimeNumbers {
    public static void main(String[] args) {
        int i, j;
        for (j = 2; j <= 100; j++) {
            for (i = 2; i <= j / 2; i++) {
                if (j % i == 0) {
                    break;
                }
            }
            if (i > j / 2) {
                System.out.print(" " + j);
            }
        }
    }
}

运行结果

 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

📸 截图7:运行 Quiz5_3_PrimeNumbers.java 的终端输出截图。


题5.4 —— 1 + 1/2! + 1/3! + ... 前20项和

代码Quiz5_4_ReciprocalFactorialSum.java

/**
 * 第5题(4) - 计算 1 + 1/2! + 1/3! + ... + 1/20!
 * 分别用 while 和 for 实现,递推公式 term = term / i
 * 预期输出: 约 1.718281828459045
 */
public class Quiz5_4_ReciprocalFactorialSum {
    public static void main(String[] args) {
        // while 循环
        double sum = 0;
        double term = 1;
        int i = 1;
        while (i <= 20) {
            sum += term;
            i++;
            term = term / i;
        }
        System.out.println("while sum = " + sum);

        // for 循环
        sum = 0;
        term = 1;
        for (i = 1; i <= 20; i++) {
            term = term * (1.0 / i);
            sum += term;
        }
        System.out.println("for sum = " + sum);
    }
}

运行结果

while sum = 1.718281828459045
for sum = 1.718281828459045

📸 截图8:运行 Quiz5_4_ReciprocalFactorialSum.java 的终端输出截图。


题5.5 —— 1000以内的完数

代码Quiz5_5_PerfectNumbers.java

/**
 * 第5题(5) - 求1000以内的完数
 * 完数 = 所有真因子之和(因子不包括自身)
 * 预期输出: 6 28 496
 */
public class Quiz5_5_PerfectNumbers {
    public static void main(String[] args) {
        for (int num = 2; num <= 1000; num++) {
            int sum = 0;
            for (int i = 1; i <= num / 2; i++) {
                if (num % i == 0) {
                    sum += i;
                }
            }
            if (sum == num) {
                System.out.print(num + " ");
            }
        }
    }
}

运行结果

6 28 496

📸 截图9:运行 Quiz5_5_PerfectNumbers.java 的终端输出截图。


题5.6 —— 最大公约数和最小公倍数(键盘输入)

代码Quiz5_6_GCD_LCM.java

import java.util.Scanner;

/**
 * 第5题(6) - 最大公约数和最小公倍数
 * 辗转相除法求 GCD,LCM = a * b / GCD
 * 示例输入: 12 18 → 输出: 最大公约数=6,最小公倍数=36
 */
public class Quiz5_6_GCD_LCM {
    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);
        System.out.print("请输入第一个正整数: ");
        int a = reader.nextInt();
        System.out.print("请输入第二个正整数: ");
        int b = reader.nextInt();

        int m = a, n = b;
        while (n != 0) {
            int r = m % n;
            m = n;
            n = r;
        }
        int gcd = m;
        int lcm = a * b / gcd;
        System.out.println("最大公约数: " + gcd);
        System.out.println("最小公倍数: " + lcm);
        reader.close();
    }
}

运行示例

请输入第一个正整数: 12
请输入第二个正整数: 18
最大公约数: 6
最小公倍数: 36

📸 截图10:运行 Quiz5_6_GCD_LCM.java 并输入 12 18 后的终端输出截图。


题5.7 —— 满足 1! + 2! + ... + n! ≤ 9999 的最大整数 n

代码Quiz5_7_MaxNFactorialSum.java

/**
 * 第5题(7) - 求最大 n 使 1!+2!+...+n! ≤ 9999
 * 依次累加,超过则 break,输出 n-1
 * 预期输出: 7
 */
public class Quiz5_7_MaxNFactorialSum {
    public static void main(String[] args) {
        long sum = 0;
        long fact = 1;
        int n = 1;
        while (true) {
            fact = fact * n;          // n!
            if (sum + fact > 9999) {
                break;
            }
            sum += fact;
            n++;
        }
        System.out.println("满足条件的最大整数 n = " + (n - 1));
    }
}

运行结果

满足条件的最大整数 n = 7

📸 截图11:运行 Quiz5_7_MaxNFactorialSum.java 的终端输出截图

更多推荐