Mr.Mou @ ShiShi AP Center

AP CSA 2.5:复合布尔表达式

In earlier lessons, one Boolean expression controlled each decision. In this lesson, you will combine or reverse conditions to describe more precise situations.

在前面的课程中,每个判断通常只使用一个布尔表达式。本节课将学习如何组合或取反多个条件,从而表达更准确的判断逻辑。

&& requires both conditions, || requires at least one, and ! reverses a Boolean value. && 要求两个条件都为真,|| 要求至少一个为真,而 ! 会把布尔值取反。

Core Concepts:
核心知识点

1. Evaluate the Smaller Conditions First
先计算较小的条件

What is printed?

下面的代码会输出什么?

int x = 10;
int y = 5;

if (x % 2 == 0 && y % 2 == 0 || x > y)
{
    System.out.print("First ");

    if (y * 2 == x || y > 5 && x <= 10)
    {
        System.out.print("Second");
    }
    else
    {
        System.out.print("Third");
    }
}

Answer:

First Second

Start with the outer condition:

先计算外层条件:

x % 2 == 0 → true
y % 2 == 0 → false
x > y      → true

Because && is evaluated before ||, Java reads the condition as:

因为 && 的优先级高于 ||,Java 会按照下面的方式理解:

(true && false) || true
false || true → true

Therefore, "First " is printed.

所以会输出 "First "

Now evaluate the inner condition:

接着计算内层条件:

y * 2 == x → true
y > 5      → false
x <= 10    → true

Java reads it as:

Java 会按照下面的方式理解:

true || (false && true)

The result is true, so "Second" is printed.

结果为 true,因此输出 "Second"

2. Logical AND: &&
逻辑与:&&

A && B is true only when both expressions are true.

只有当两个表达式都为真时,A && B 的结果才为真。

boolean roomClean = true;
boolean homeworkDone = false;

if (roomClean && homeworkDone)
{
    System.out.println("You can go out.");
}
else
{
    System.out.println("Stay home.");
}
Stay home.

Although roomClean is true, homeworkDone is false. Because both conditions are required, the complete expression is false.

虽然 roomClean 为真,但 homeworkDone 为假。由于两个条件必须同时满足,因此整个表达式为假。

AND truth table
AND 真值表

A B A && B
true true true
true false false
false true false
false false false

A useful memory rule:

一个实用的记忆方法:

&& is strict: both sides must be true.

&& 的要求很严格:左右两边都必须为真。

3. Logical OR: ||
逻辑或:||

A || B is true when one or both expressions are true.

只要一个或两个表达式为真,A || B 的结果就为真。

boolean canWalk = true;
boolean carAvailable = false;

if (canWalk || carAvailable)
{
    System.out.println("You can go.");
}
You can go.

Only one true condition is required.

只需要一个条件为真即可。

OR truth table
OR 真值表

A B A || B
true true true
true false true
false true true
false false false

Java uses inclusive OR.

Java 中的 ||包含性或

That means this expression is still true when both sides are true:

这表示即使左右两边都为真,整个表达式仍然为真:

true || true
true

Do not assume that || means “exactly one side is true.”

不要把 || 理解为“只能有一边为真”。

4. Logical NOT: !
逻辑非:!

The logical NOT operator ! reverses a Boolean value.

逻辑非运算符 ! 会把一个布尔值取反。

!true  → false
!false → true

Consider:

观察下面的代码:

boolean homeworkDone = false;

if (!homeworkDone)
{
    System.out.println("Finish your homework.");
}
Finish your homework.

homeworkDone is false, so !homeworkDone is true.

homeworkDone 为假,因此 !homeworkDone 为真。

You can also negate a complete comparison:

也可以对一个完整的比较表达式取反:

int score = 70;
boolean result = !(score >= 60);

First calculate:

先计算:

score >= 60 → true

Then reverse it:

然后取反:

!true → false

Therefore, result is false.

所以,result 的值是 false

5. Use && for Values Inside a Range
使用 && 判断范围内部

Suppose a valid score must be from 0 through 100, including both endpoints.

假设合法分数必须在 0100 之间,并且包含两个边界值。

if (score >= 0 && score <= 100)
{
    System.out.println("Valid score");
}

Both conditions must be true:

两个条件必须同时为真:

score is at least 0
AND
score is at most 100
score >= 0 && score <= 100

Examples:

例如:

score score >= 0 score <= 100 Complete result
75 true true true
-5 false true false
110 true false false

To be inside the range, the value must satisfy both boundaries.

要位于范围内部,数值必须同时满足左右两个边界。

Java does not allow mathematical chained comparisons such as:

Java 不支持数学中的连续比较写法:

0 <= score <= 100

Use two complete comparisons joined by &&.

应该写出两个完整的比较表达式,并使用 && 连接。

6. Use || for Values Outside a Range
使用 || 判断范围外部

A score is outside the valid range when it is below 0 or above 100.

当分数小于 0 或大于 100 时,它位于合法范围之外。

if (score < 0 || score > 100)
{
    System.out.println("Invalid score");
}

Only one condition needs to be true.

只需要其中一个条件为真。

Examples:

score score < 0 score > 100 Complete result
75 false false false
-5 true false true
110 false true true

A useful pattern is:

一个实用的规律是:

Goal Common structure    
Inside a range
范围内部
lower <= value && value <= upper    
Outside a range
范围外部
value < lower | | value > upper    

7. Operator Precedence
运算符优先级

Among the three logical operators, Java uses this order:

在三个逻辑运算符之间,Java 使用下面的优先顺序:

!  first
&& second
|| third

括号优先于这些运算符。

For example:

例如:

boolean result = true || false && false;

Java evaluates && first:

Java 会先计算 &&

true || (false && false)
true || false → true

The result is true.

结果为 true

Compare that with:

与下面的表达式比较:

boolean result = (true || false) && false;

Parentheses force the OR expression to run first:

括号要求 Java 先计算 OR 表达式:

(true || false) && false
true && false
false

The two expressions produce different results.

两个表达式会得到不同的结果。

Even when parentheses are not required, they can make the intended grouping easier to see.

即使语法上不需要括号,也可以使用括号让逻辑分组更加清楚。

8. Short-Circuit Evaluation
短路求值

Java does not always evaluate both sides of && or ||.

Java 不一定会计算 &&|| 的左右两边。

This behavior is called short-circuit evaluation.

这种行为叫作 short-circuit evaluation(短路求值)

Short-circuit with &&
&& 的短路求值

For:

对于:

A && B

If A is false, the entire expression must be false. Java skips B.

如果 A 为假,整个表达式一定为假,因此 Java 会跳过 B

int x = 0;
int y = 6;

if (x != 0 && y / x == 3)
{
    System.out.println("Match");
}
else
{
    System.out.println("No match");
}
No match

Java first checks:

Java 首先检查:

x != 0 → false

Because the left side of && is false, Java does not calculate:

因为 && 左边为假,Java 不会计算:

y / x

Therefore, no division-by-zero exception occurs.

因此,不会发生除以零的运行时错误。

Short-circuit with ||
|| 的短路求值

For:

对于:

A || B

If A is true, the complete expression must be true. Java skips B.

如果 A 为真,整个表达式一定为真,因此 Java 会跳过 B

int x = 0;
int y = 6;

if (x == 0 || y / x == 3)
{
    System.out.println("First case");
}
First case

Because x == 0 is already true, Java never evaluates y / x.

因为 x == 0 已经为真,所以 Java 不会计算 y / x

Operator When the right side is skipped    
A && B When A is false    
A | | B When A is true    

9. Common Beginner Mistakes
常见初学者错误

Mistake Why it is wrong Correct understanding
Using || for an inside range.
使用 || 判断范围内部。
Almost every value satisfies at least one side.
几乎所有数值都会满足其中一个条件。
Use &&: score >= 0 && score <= 100.
范围内部使用 &&
Treating || as “exactly one.”
认为 || 表示只能有一个条件为真。
true || true is also true.
两个条件都为真时,结果仍然为真。
Java uses inclusive OR.
Java 使用包含性或。
Reading strictly from left to right.
完全按照从左到右计算。
&& is evaluated before ||.
&& 的优先级高于 ||
Add parentheses or apply the correct precedence.
使用括号或按照正确优先级计算。
Forgetting that ! reverses only the expression it controls.
不清楚 ! 对哪部分取反。
!a && b means (!a) && b.
! 先作用于紧跟其后的表达式。
Use parentheses when negating a larger expression.
对较大表达式取反时使用括号。
Assuming both sides always run.
认为左右两边总会计算。
&& and || use short-circuit evaluation.
&&|| 会进行短路求值。
Check whether the left side already determines the result before evaluating the right side.
先判断左边是否已经决定最终结果。
Putting an unsafe expression first.
把可能出错的表达式放在左边。
It may be evaluated before the safety check.
安全条件可能还没检查,危险运算就已经执行。
Put the safety check first.
先写安全检查条件。

10. Debugging Compound Conditions
调试复合条件

The following code is supposed to print "Valid" only when score is between 0 and 100.

下面的代码原本应该只在 score 位于 0100 之间时输出 "Valid"

int score = 150;

if (score >= 0 || score <= 100)
{
    System.out.println("Valid");
}

Actual output:

Valid

The code runs, but the result is wrong. This is a logic error.

代码可以运行,但结果错误。这属于逻辑错误

For score = 150:

对于 score = 150

score >= 0   → true
score <= 100 → false
true || false → true

The program accepts the score because || requires only one true condition.

程序接受了这个分数,因为 || 只要求一个条件为真。

Fixed code

int score = 150;

if (score >= 0 && score <= 100)
{
    System.out.println("Valid");
}
score >= 0   → true
score <= 100 → false
true && false → false

Nothing is printed, which is correct.

不会输出任何内容,这才是正确结果。

Unsafe condition order
不安全的条件顺序

Consider:

观察:

int x = 0;
int y = 9;

if (y / x == 3 && x != 0)
{
    System.out.println("Match");
}

Java evaluates the left side first, so y / x causes an arithmetic exception before Java reaches x != 0.

Java 会先计算左边,因此还没有检查 x != 0y / x 就已经导致算术异常。

This is a runtime error.

这属于运行时错误

Fixed order

if (x != 0 && y / x == 3)
{
    System.out.println("Match");
}
Problem Error type Fix        
score >= 0 | | score <= 100 Logic error
逻辑错误
Use && for the inside range.
范围内部使用 &&
       
y / x == 3 && x != 0 Runtime error when x is 0
x0 时发生运行时错误
Put x != 0 first.
先检查 x != 0
       
Misreading a | | b && c Logic/tracing mistake
逻辑或追踪错误
Read it as a | | (b && c).
先计算 b && c
       

11. Mini Practice
小练习

Practice 1: AND and OR
练习一:AND 与 OR

What is the value of result?

result 的值是什么?

boolean result = (8 > 3) && (4 == 5);

Answer: false

8 > 3  → true
4 == 5 → false
true && false → false

Both sides of && must be true.

&& 的两边必须都为真。


Practice 2: Inclusive OR
练习二:包含性或

What is the result?

结果是什么?

boolean result = true || true;

Answer: true

Java’s || is true when one or both sides are true.

当一个或两个条件为真时,Java 的 || 都会得到 true


Practice 3: Range Check
练习三:范围判断

Which expression correctly tests whether age is from 13 through 19, including both endpoints?

下面哪个表达式可以正确判断 age 是否位于 1319 之间,并包含两个边界?

A. age >= 13 || age <= 19 B. age >= 13 && age <= 19 C. age < 13 && age > 19 D. age == 13 || 19

Answer: B

The value must satisfy both the lower and upper boundaries.

这个值必须同时满足下限和上限。


Practice 4: Operator Precedence
练习四:运算符优先级

What is the value of result?

result 的值是什么?

boolean result = false || true && false;

Answer: false

&& is evaluated first:

先计算 &&

false || (true && false)
false || false
false

Practice 5: Short-Circuit Evaluation
练习五:短路求值

What happens when this code runs?

下面的代码运行时会发生什么?

int x = 0;
int y = 12;

if (x != 0 && y / x == 3)
{
    System.out.println("First");
}
else
{
    System.out.println("Second");
}

Answer:

Second

x != 0 is false, so Java skips y / x == 3. No exception occurs.

x != 0 为假,因此 Java 跳过 y / x == 3,不会发生异常。

Quick Checklist
快速检查清单

Before answering a Topic 2.5 question, check:

做 2.5 的题目之前,检查: