CSP-J教程——第一阶段——第四课:算术与逻辑运算

课程目标
- 掌握算术运算符的使用
- 理解关系运算符和逻辑运算符
- 学会使用运算符优先级
- 能够编写复杂的计算和逻辑判断程序
- 理解表达式求值过程
第一部分:算术运算符(40分钟)
1.1 基本算术运算符
五种基本算术运算符:
| 运算符 | 名称 | 例子 | 结果 |
|---|---|---|---|
+ | 加法 | 5 + 3 | 8 |
- | 减法 | 5 - 3 | 2 |
* | 乘法 | 5 * 3 | 15 |
/ | 除法 | 6 / 3 | 2 |
% | 取模(求余) | 7 % 3 | 1 |
1.2 算术运算符示例
#include <iostream>
using namespace std;int main() {int a = 10, b = 3;cout << "a = " << a << ", b = " << b << endl;cout << "a + b = " << (a + b) << endl; // 13cout << "a - b = " << (a - b) << endl; // 7cout << "a * b = " << (a * b) << endl; // 30cout << "a / b = " << (a / b) << endl; // 3(整数除法)cout << "a % b = " << (a % b) << endl; // 1return 0;
}
1.3 整数除法与浮点数除法
重要区别:
#include <iostream>
using namespace std;int main() {int a = 7, b = 2;double x = 7.0, y = 2.0;cout << "整数除法: " << a << " / " << b << " = " << (a / b) << endl; // 3cout << "浮点数除法: " << x << " / " << y << " = " << (x / y) << endl; // 3.5// 混合运算:整数与浮点数cout << "混合运算: " << a << " / " << y << " = " << (a / y) << endl; // 3.5return 0;
}
1.4 取模运算符的特殊性
取模运算规则:
- 只能用于整数
- 结果的符号与被除数相同
#include <iostream>
using namespace std;int main() {cout << "7 % 3 = " << (7 % 3) << endl; // 1cout << "7 % -3 = " << (7 % -3) << endl; // 1cout << "-7 % 3 = " << (-7 % 3) << endl; // -1cout << "-7 % -3 = " << (-7 % -3) << endl;// -1// 取模运算的用途int number = 123;cout << number << "的个位数是: " << (number % 10) << endl; // 3cout << number << "的十位数是: " << (number / 10 % 10) << endl; // 2cout << number << "的百位数是: " << (number / 100) << endl; // 1return 0;
}
1.5 复合赋值运算符
简化写法:
| 完整写法 | 简化写法 |
|---|---|
a = a + b | a += b |
a = a - b | a -= b |
a = a * b | a *= b |
a = a / b | a /= b |
a = a % b | a %= b |
#include <iostream>
using namespace std;int main() {int score = 10;cout << "初始分数: " << score << endl;score += 5; // score = score + 5cout << "加分后: " << score << endl; // 15score *= 2; // score = score * 2cout << "翻倍后: " << score << endl; // 30score /= 3; // score = score / 3cout << "除以3后: " << score << endl; // 10return 0;
}
第二部分:关系运算符(30分钟)
2.1 什么是关系运算符?
用于比较两个值的大小关系,结果是布尔值(true/false)
| 运算符 | 名称 | 例子 | 结果 |
|---|---|---|---|
== | 等于 | 5 == 3 | false |
!= | 不等于 | 5 != 3 | true |
> | 大于 | 5 > 3 | true |
< | 小于 | 5 < 3 | false |
>= | 大于等于 | 5 >= 3 | true |
<= | 小于等于 | 5 <= 3 | false |
2.2 关系运算符示例
#include <iostream>
using namespace std;int main() {int a = 10, b = 5;cout << boolalpha; // 让bool值显示为true/false而不是1/0cout << a << " == " << b << " : " << (a == b) << endl; // falsecout << a << " != " << b << " : " << (a != b) << endl; // truecout << a << " > " << b << " : " << (a > b) << endl; // truecout << a << " < " << b << " : " << (a < b) << endl; // falsecout << a << " >= " << b << " : " << (a >= b) << endl; // truecout << a << " <= " << b << " : " << (a <= b) << endl; // falsereturn 0;
}
2.3 浮点数比较的注意事项
浮点数精度问题:
#include <iostream>
#include <cmath> // 用于fabs函数
using namespace std;int main() {double a = 0.1 + 0.2; // 理论上应该是0.3double b = 0.3;cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "a == b : " << (a == b) << endl; // 可能是false!// 正确的浮点数比较方法double tolerance = 1e-10; // 很小的容差值cout << "使用容差值比较: " << (fabs(a - b) < tolerance) << endl; // truereturn 0;
}
第三部分:逻辑运算符(30分钟)
3.1 三种逻辑运算符
用于组合多个条件:
| 运算符 | 名称 | 含义 | 例子 |
|---|---|---|---|
&& | 逻辑与 | 两个条件都为真 | (a > 0) && (a < 10) |
| ` | ` | 逻辑或 | |
! | 逻辑非 | 条件取反 | !(a == b) |
3.2 逻辑运算符真值表
逻辑与(&&):
| A | B | A && B |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
逻辑或(||):
| A | B | A || B |
|—|—|--------|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
逻辑非(!):
| A | !A |
|---|---|
| true | false |
| false | true |
3.3 逻辑运算符示例
#include <iostream>
using namespace std;int main() {int age = 15;double height = 1.6;bool hasTicket = true;cout << boolalpha;// 逻辑与:两个条件都要满足bool canRideRollerCoaster = (age >= 12) && (height >= 1.4);cout << "可以坐过山车: " << canRideRollerCoaster << endl;// 逻辑或:至少满足一个条件bool hasDiscount = (age < 12) || (age >= 60);cout << "有折扣优惠: " << hasDiscount << endl;// 逻辑非:条件取反bool cannotEnter = !hasTicket;cout << "不能入场: " << cannotEnter << endl;// 复杂逻辑表达式bool specialOffer = (age >= 10 && age <= 18) && hasTicket;cout << "青少年特惠: " << specialOffer << endl;return 0;
}
3.4 短路求值
重要特性:
&&:如果第一个条件为false,不再计算第二个条件||:如果第一个条件为true,不再计算第二个条件
#include <iostream>
using namespace std;int main() {int x = 5, y = 0;// 由于x != 0为true,所以会计算y/x,这里会除以0错误// if (x != 0 && y / x > 2) {// cout << "条件成立" << endl;// }// 正确的写法:利用短路特性避免除以0if (x != 0 && y / x > 2) {cout << "条件成立" << endl;} else {cout << "条件不成立" << endl;}return 0;
}
第四部分:运算符优先级(20分钟)
4.1 优先级规则
从高到低:
()- 括号!+-- 逻辑非、正负号(一元运算符)*/%- 乘除取模+-- 加减<<=>>=- 关系比较==!=- 相等比较&&- 逻辑与||- 逻辑或=+=-=等 - 赋值
4.2 优先级示例
#include <iostream>
using namespace std;int main() {int a = 5, b = 3, c = 2;bool result;// 复杂的表达式result = a + b * c > 10 && b % c == 1;// 等价于:((a + (b * c)) > 10) && ((b % c) == 1)// 计算步骤:// 1. b * c = 3 * 2 = 6// 2. a + 6 = 5 + 6 = 11// 3. 11 > 10 = true// 4. b % c = 3 % 2 = 1// 5. 1 == 1 = true// 6. true && true = truecout << "result = " << result << endl; // truereturn 0;
}
4.3 使用括号明确优先级
良好习惯: 使用括号让表达式更清晰
#include <iostream>
using namespace std;int main() {int x = 10, y = 5, z = 3;// 难以理解的表达式bool hardToRead = x + y * z > 20 && y % z == 2 || x - y > 5;// 使用括号明确意图bool easyToRead = ((x + (y * z)) > 20) && ((y % z) == 2) || ((x - y) > 5);cout << "hardToRead: " << hardToRead << endl;cout << "easyToRead: " << easyToRead << endl;return 0;
}
第五部分:综合应用示例(30分钟)
5.1 学生成绩评定系统
#include <iostream>
using namespace std;int main() {int math, english, chinese;cout << "=== 学生成绩评定系统 ===" << endl;cout << "请输入数学成绩: ";cin >> math;cout << "请输入英语成绩: ";cin >> english;cout << "请输入语文成绩: ";cin >> chinese;// 计算平均分double average = (math + english + chinese) / 3.0;// 多重条件判断bool isExcellent = (average >= 90) && (math >= 85 && english >= 85 && chinese >= 85);bool isGood = (average >= 75) && (math >= 60 && english >= 60 && chinese >= 60);bool needsHelp = (math < 60) || (english < 60) || (chinese < 60);cout << "\n=== 评定结果 ===" << endl;cout << "平均分: " << average << endl;cout << "优秀生: " << (isExcellent ? "是" : "否") << endl;cout << "良好生: " << (isGood ? "是" : "否") << endl;cout << "需要帮助: " << (needsHelp ? "是" : "否") << endl;return 0;
}
5.2 数字特性分析器
#include <iostream>
using namespace std;int main() {int number;cout << "请输入一个整数: ";cin >> number;// 分析数字特性bool isEven = (number % 2 == 0); // 偶数bool isPositive = (number > 0); // 正数bool isMultipleOf3 = (number % 3 == 0); // 3的倍数bool isMultipleOf5 = (number % 5 == 0); // 5的倍数bool isTwoDigit = (number >= 10 && number <= 99) || (number <= -10 && number >= -99); // 两位数cout << "\n=== 数字特性分析 ===" << endl;cout << number << " 是偶数: " << (isEven ? "是" : "否") << endl;cout << number << " 是正数: " << (isPositive ? "是" : "否") << endl;cout << number << " 是3的倍数: " << (isMultipleOf3 ? "是" : "否") << endl;cout << number << " 是5的倍数: " << (isMultipleOf5 ? "是" : "否") << endl;cout << number << " 是两位数: " << (isTwoDigit ? "是" : "否") << endl;// 组合特性if (isEven && isMultipleOf3) {cout << number << " 是6的倍数" << endl;}if (isMultipleOf3 && isMultipleOf5) {cout << number << " 是15的倍数" << endl;}return 0;
}
5.3 简易计算器
#include <iostream>
using namespace std;int main() {double num1, num2;char operation;cout << "=== 简易计算器 ===" << endl;cout << "请输入第一个数字: ";cin >> num1;cout << "请输入运算符 (+, -, *, /): ";cin >> operation;cout << "请输入第二个数字: ";cin >> num2;double result;bool validOperation = true;// 根据运算符进行计算if (operation == '+') {result = num1 + num2;} else if (operation == '-') {result = num1 - num2;} else if (operation == '*') {result = num1 * num2;} else if (operation == '/') {// 检查除数是否为0if (num2 != 0) {result = num1 / num2;} else {cout << "错误:除数不能为0!" << endl;validOperation = false;}} else {cout << "错误:不支持的运算符!" << endl;validOperation = false;}if (validOperation) {cout << "计算结果: " << num1 << " " << operation << " " << num2 << " = " << result << endl;}return 0;
}
练习与作业
基础练习(必做)
练习1:闰年判断器
编写程序判断输入的年份是否为闰年:
- 闰年规则:能被4整除但不能被100整除,或者能被400整除
- 使用逻辑运算符组合条件
练习2:三角形类型判断
输入三角形三条边的长度,判断三角形类型:
- 等边三角形:三边相等
- 等腰三角形:两边相等
- 直角三角形:a² + b² = c²(注意三条边都可能作为斜边)
- 普通三角形:满足三角形不等式
练习3:数字游戏
输入一个三位数,完成以下操作:
- 计算各位数字之和
- 计算各位数字之积
- 判断是否是水仙花数(各位数字立方和等于该数本身)
挑战练习(选做)
挑战1:表达式求值器
编写程序计算复杂表达式的结果,要求:
- 支持括号、加减乘除、取模运算
- 正确处理优先级
- 可以分步显示计算过程
挑战2:逻辑谜题求解
解决经典逻辑谜题:
"教室里有5个学生,已知:
- 如果小明来了,那么小红也来了
- 小刚和小丽要么都来,要么都不来
- 如果小丽来了,那么小明没来
- 小华来了
请问哪些学生来了?"
挑战3:日期验证器
编写程序验证日期的合法性:
- 检查月份是否在1-12之间
- 根据月份检查日期是否合理
- 考虑闰年对2月天数的影响
实验任务
任务1:运算符优先级实验
测试以下表达式,验证你的理解:
int a = 5, b = 3, c = 2;
bool r1 = a + b * c == 11;
bool r2 = a % b + c > 3;
bool r3 = !a == 0 && b > 2;
任务2:短路求值实验
设计实验验证&&和||的短路特性:
int x = 0, y = 10;
// 测试:if (x != 0 && y/x > 2) 是否会出错
// 测试:if (x == 0 || y/x > 2) 是否会出错
任务3:边界条件测试
测试各种边界情况:
- 除数为0的情况
- 整数溢出的情况
- 浮点数精度问题
- 负数取模的结果
常见错误与调试
常见错误
1. 混淆=和==
int a = 5;
if (a = 3) { // 错误:应该是a == 3// 这里总会执行,因为a=3的结果是3(true)
}
2. 整数除法错误
double result = 5 / 2; // 结果是2.0,不是2.5
3. 优先级错误
bool result = a & b == 1; // 错误:==优先级高于&
调试技巧
- 分步计算:将复杂表达式拆分成多个简单表达式
- 输出中间结果:用cout显示每一步的计算结果
- 使用括号:明确指定计算顺序
学习总结
今天学到了:
- ✅ 算术运算符:
+,-,*,/,% - ✅ 关系运算符:
==,!=,>,<,>=,<= - ✅ 逻辑运算符:
&&,||,! - ✅ 运算符优先级:计算顺序规则
- ✅ 复合赋值:
+=,-=,*=,/=,%=
关键概念:
- 整数除法:结果取整
- 取模运算:求余数,用于判断整除
- 布尔逻辑:真值表和短路求值
- 表达式求值:按照优先级顺序计算
下一课预告:
下一节课我们将学习程序流程控制:选择结构,包括if、if-else、switch语句,让程序能够根据不同条件执行不同的代码!
