第二章 运算符与表达式 —— 让数据产生交互
2.1 算术运算符的细节与陷阱
// Java算术运算符
int a = 17;
int b = 5;
System.out.println(a + b); // 22
System.out.println(a - b); // 12
System.out.println(a * b); // 85
System.out.println(a / b); // 3(整数除法,截断小数)
System.out.println(a % b); // 2(取余数)
// 整数除法的陷阱
double result = 17 / 5; // 结果是3.0,不是3.4!
// 原因:两边都是整数,先执行整数除法得3,再转double
double correct = 17.0 / 5; // 3.4,浮点数除法
double correct2 = (double)17 / 5; // 显式转换
// 负数取余
System.out.println(-17 % 5); // -2
System.out.println(17 % -5); // 2
// 规则:结果的符号与被除数相同
// 复合赋值运算符
a += 5; // 等价于 a = a + 5
a -= 3; // a = a - 3
a *= 2; // a = a * 2
a /= 4; // a = a / 4
a %= 3; // a = a % 3
2.2 关系运算符与逻辑运算符
# Python关系运算符
x = 10
y = 20
print(x < y) # True
print(x <= y) # True
print(x > y) # False
print(x >= y) # False
print(x == y) # False
print(x != y) # True
# 链式比较(Python特色)
print(5 < x < 15) # True,等价于 5 < x and x < 15
print(5 < x > 8) # True,注意这不是数学表达式
# 逻辑运算符
a = True
b = False
print(a and b) # False(与)
print(a or b) # True(或)
print(not a) # False(非)
# 短路求值(Short-circuit evaluation)
def risky_operation():
print("This won't be called")
return 1 / 0 # 不会执行
False and risky_operation() # 左侧False,短路,右侧不执行
True or risky_operation() # 左侧True,短路,右侧不执行
# 利用短路实现默认值
name = input("Enter name: ") or "Anonymous" # 如果输入为空字符串,使用默认值
2.3 位运算符(底层优化利器)
// C语言位运算(同样适用于Java、C++等)
unsigned int a = 0b1100; // 12
unsigned int b = 0b1010; // 10
// 按位与:两个都为1才为1
printf("%d\n", a & b); // 0b1000 = 8
// 按位或:至少一个为1则为1
printf("%d\n", a | b); // 0b1110 = 14
// 按位异或:不同为1,相同为0
printf("%d\n", a ^ b); // 0b0110 = 6
// 按位取反
printf("%u\n", ~a); // 0b...11110011(高位全变1)
// 左移:乘以2的n次方
printf("%d\n", a << 1); // 0b11000 = 24
printf("%d\n", a << 2); // 0b110000 = 48
// 右移:除以2的n次方(整数除法)
printf("%d\n", a >> 1); // 0b0110 = 6
// 实际应用:权限系统
#define READ 0b100 // 4
#define WRITE 0b010 // 2
#define EXEC 0b001 // 1
int permission = READ | WRITE; // 0b110 = 6
if (permission & READ) {
printf("Can read\n"); // 执行
}
if (permission & EXEC) {
printf("Can exec\n"); // 不执行
}
// 应用:快速判断奇偶
int isOdd = (x & 1); // 最后一位为1则是奇数
// 应用:交换两个数(不借助临时变量)
int x = 5, y = 7;
x = x ^ y;
y = x ^ y;
x = x ^ y;
// 现在 x=7, y=5
2.4 运算符优先级(复杂表达式的求值顺序)
// 运算符优先级表(从高到低)
// 1. 括号 ()
// 2. 后缀 ++ --
// 3. 一元 ++ -- + - ! ~
// 4. 乘除 * / %
// 5. 加减 + -
// 6. 移位 << >> >>>
// 7. 关系 < <= > >= instanceof
// 8. 相等 == !=
// 9. 逻辑与 &
// 10. 逻辑异或 ^
// 11. 逻辑或 |
// 12. 条件与 &&
// 13. 条件或 ||
// 14. 三元 ?:
// 15. 赋值 = += -= *= ...
// 易错示例
int result = 5 + 3 * 2; // 11,不是16
int result2 = (5 + 3) * 2; // 16
boolean flag = true || false && false; // true
// 原因:&&优先级高于||,等价于 true || (false && false)
// 赋值运算符从右向左结合
int a, b, c;
a = b = c = 10; // 等价于 a = (b = (c = 10))
// 建议:复杂表达式使用括号增加可读性
int result3 = ((a + b) * (c - d)) / (e + f);
第三章 控制流程 —— 程序的决策与循环
3.1 条件分支的精髓
if-else 家族的完整形态
// Java条件语句完整示例
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("不及格");
}
// 嵌套if
boolean hasTicket = true;
boolean isVip = false;
if (hasTicket) {
if (isVip) {
System.out.println("VIP通道");
} else {
System.out.println("普通通道");
}
} else {
System.out.println("请先购票");
}
// if-else 的代码块注意事项
int x = 10;
if (x > 5)
System.out.println("大于5");
System.out.println("这行永远执行"); // 缩进误导!实际不属于if
// 正确写法:始终使用大括号
if (x > 5) {
System.out.println("大于5");
System.out.println("属于if块");
}
switch 语句的进化
// Java传统switch(支持int, char, String, enum)
int day = 3;
String dayName;
switch (day) {
case 1:
dayName = "Monday";
break;
case 2:
dayName = "Tuesday";
break;
case 3:
dayName = "Wednesday";
break;
default:
dayName = "Unknown";
}
// 穿透现象(如果没有break)
switch (day) {
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("工作日");
break; // 所有1-5都执行这里
case 6:
case 7:
System.out.println("周末");
break;
}
// Java 14+ 增强switch(表达式形式)
String result = switch (day) {
case 1, 2, 3, 4, 5 -> "工作日";
case 6, 7 -> "周末";
default -> "无效";
};
// 带yield的复杂逻辑
String grade = "A";
int points = switch (grade) {
case "A" -> {
System.out.println("优秀");
yield 95; // 产生返回值
}
case "B" -> {
System.out.println("良好");
yield 85;
}
default -> 0;
};
3.2 循环结构的深度剖析
while 和 do-while
# Python while循环
# 基本形式
count = 0
while count < 5:
print(f"Count: {count}")
count += 1
# 无限循环与break
while True:
user_input = input("输入exit退出: ")
if user_input == "exit":
break
print(f"你输入了: {user_input}")
# continue跳过本次循环
num = 0
while num < 10:
num += 1
if num % 2 == 0:
continue # 跳过偶数
print(num) # 打印奇数
# while-else(Python特色)
search = [1, 3, 5, 7, 9]
target = 6
i = 0
while i < len(search):
if search[i] == target:
print("找到了!")
break
i += 1
else:
print("没找到") # 循环正常结束(没有break)时执行
// Java do-while循环(至少执行一次)
int attempts = 0;
int password = 1234;
int input;
do {
System.out.print("请输入密码: ");
input = scanner.nextInt();
attempts++;
if (attempts >= 3) {
System.out.println("超过尝试次数");
break;
}
} while (input != password);
for 循环的多种形态
C语言风格for循环:
// 基本形式
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
// 多个变量
for (int i = 0, j = 10; i < j; i++, j--) {
System.out.println("i=" + i + ", j=" + j);
}
// 省略部分表达式
int i = 0;
for (; i < 10; ) {
System.out.println(i);
i++;
}
// 死循环
for (;;) {
// 等价于 while(true)
}
增强for循环(foreach):
// 遍历数组
int[] numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
System.out.println(num);
}
// 遍历集合
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
Python的for循环(迭代器风格):
# 遍历范围
for i in range(5): # 0,1,2,3,4
print(i)
for i in range(2, 8): # 2,3,4,5,6,7
print(i)
for i in range(1, 10, 2): # 1,3,5,7,9(步长2)
print(i)
# 反向遍历
for i in range(10, 0, -1): # 10,9,8,...,1
print(i)
# 遍历列表
fruits = ["apple", "banana", "orange"]
for fruit in fruits:
print(fruit)
# 同时获取索引和值
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# 遍历字典
person = {"name": "Alice", "age": 25, "city": "New York"}
for key in person:
print(f"{key}: {person[key]}")
for key, value in person.items():
print(f"{key}: {value}")
# 并行遍历多个序列
names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]
for name, score in zip(names, scores):
print(f"{name} 得分: {score}")
# 列表推导式(简洁的循环)
squares = [x**2 for x in range(10)] # [0,1,4,9,16,25,36,49,64,81]
evens = [x for x in range(20) if x % 2 == 0]
matrix = [[i*j for j in range(5)] for i in range(5)] # 二维列表
3.3 循环控制的高级技巧
// 带标签的break和continue(Java)
outer: for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i == 1 && j == 1) {
break outer; // 跳出外层循环
}
System.out.println("i=" + i + ", j=" + j);
}
}
// 输出:i=0,j=0 i=0,j=1 i=0,j=2 i=1,j=0
# Python的for-else和while-else
# 查找质数的例子
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print(f"{n} = {x} * {n//x}")
break
else:
print(f"{n} 是质数")