4.3 逻辑运算 (Logical Operations)
1. 概念介绍
逻辑运算用于组合或修改布尔值(true/false),通常与关系运算结合使用,以构建更复杂的条件判断。
- 逻辑与 (
&&) : AND。当且仅当两个操作数都为true时,结果才为true。 - 逻辑或 (
||) : OR。只要两个操作数中至少有一个为true,结果就为true。 - 逻辑非 (
!) : NOT。反转操作数的布尔值。!true结果为false,!false结果为true。
2. 算法步骤
- 逻辑非 (
!) : 计算操作数的布尔值,然后取反。 - 逻辑与 (
&&) : a. 计算左操作数。 b. 如果左操作数为false,则不再计算右操作数,直接返回false(短路求值)。 c. 如果左操作数为true,则计算右操作数,并返回其结果。 - 逻辑或 (
||) : a. 计算左操作数。 b. 如果左操作数为true,则不再计算右操作数,直接返回true(短路求值)。 c. 如果左操作数为false,则计算右操作数,并返回其结果。
3. 算法可视化SVG图示
下图用逻辑门的样式展示了三种逻辑运算。
4. 核心特性
- 短路求值 (Short-circuit Evaluation) : 这是逻辑运算最重要的特性。
-
A && B:如果A为假,则B表达式根本不会被执行。A || B:如果A为真,则B表达式根本不会被执行。 这个特性可以用于避免错误(如if (ptr != nullptr && ptr->value > 0))和进行性能优化。
- 优先级:
!(非) >&&(与) >||(或)。 - 操作数: 可以是任何能转换为布尔值的表达式(在C++中,非零值为
true,零值为false)。
5. C++代码基础实现
#include <iostream>
int main() {
bool is_student = true;
int age = 15;
bool has_ticket = false;
std::cout << std::boolalpha;
// 逻辑与 &&
// 是学生并且年龄小于18岁吗?
if (is_student && age < 18) {
std::cout << "Is a minor student: true" << std::endl;
}
// 逻辑或 ||
// 是学生或者有票吗?
if (is_student || has_ticket) {
std::cout << "Can enter (student or has ticket): true" << std::endl;
}
// 逻辑非 !
// 没有票吗?
if (!has_ticket) {
std::cout << "Does not have a ticket: true" << std::endl;
}
return0;
}
6. 优化策略
- 利用短路特性:
-
- 在
&&链中,将最可能为false的条件或计算成本最低的条件放在最前面。 - 在
||链中,将最可能为true的条件或计算成本最低的条件放在最前面。
- 在
- 化简逻辑: 使用德摩根定律等布尔代数规则来化简复杂的逻辑表达式。例如
!(A || B)等价于!A && !B。
7. 优缺点
- 优点: 能够构建任意复杂的判断逻辑,是程序控制流的粘合剂。短路特性可以提升效率和代码安全性。
- 缺点: 复杂的嵌套逻辑表达式会降低代码的可读性。
8. 应用场景
- 数据校验: 检查输入数据是否同时满足多个条件(例如,年龄在18-60之间
age >= 18 && age <= 60)。 - 状态判断: 在游戏中判断游戏结束条件(例如,生命值为0或时间耗尽
health <= 0 || time_left <= 0)。 - 权限控制: 判断用户是否具有执行某项操作的权限。
- 算法分支: 在算法中根据多个条件的组合来选择不同的执行路径。
9. 扩展
- 位逻辑运算符 (
&,|,^,~) : 这些是位运算符,对整数的每个二进制位进行逻辑运算,与逻辑运算符&&,||,!不同。不要混淆。 - 布尔代数: 逻辑运算是布尔代数的基础,理解布尔代数有助于简化和优化逻辑表达式。
10. 课后配套练习及答案
练习1: 区间判断输入一个整数,判断它是否在区间 [10, 20] 内(包含10和20)。
// 答案
#include <iostream>
int main() {
int n;
std::cin >> n;
if (n >= 10 && n <= 20) {
std::cout << "In range" << std::endl;
} else {
std::cout << "Out of range" << std::endl;
}
return 0;
}
练习2: 判断元音字母输入一个字符,判断它是否是元音字母(a, e, i, o, u,不区分大小写)。
// 答案
#include <iostream>
#include <cctype> // for tolower
int main() {
char c;
std::cin >> c;
c = tolower(c);
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
std::cout << "Vowel" << std::endl;
} else {
std::cout << "Consonant" << std::endl;
}
return 0;
}
练习3: 判断点是否在矩形内输入一个点的坐标(x, y)和一个矩形的左上角坐标(x1, y1)和右下角坐标(x2, y2),判断该点是否在矩形内(含边界)。
// 答案
#include <iostream>
int main() {
int x, y, x1, y1, x2, y2;
std::cin >> x >> y >> x1 >> y1 >> x2 >> y2;
if (x >= x1 && x <= x2 && y >= y1 && y <= y2) {
std::cout << "Inside" << std::endl;
} else {
std::cout << "Outside" << std::endl;
}
return 0;
}
练习4: 登录验证模拟登录,只有当用户名是 "admin" 并且密码是 "123456" 时,才输出 "Login success"。
// 答案
#include <iostream>
#include <string>
int main() {
std::string username, password;
std::cin >> username >> password;
if (username == "admin" && password == "123456") {
std::cout << "Login success" << std::endl;
} else {
std::cout << "Login failed" << std::endl;
}
return 0;
}
练习5: 判断三角形输入三角形的三条边长 a, b, c,判断它们是否能构成一个三角形(任意两边之和大于第三边)。
// 答案
#include <iostream>
int main() {
int a, b, c;
std::cin >> a >> b >> c;
if (a > 0 && b > 0 && c > 0 && (a + b > c) && (a + c > b) && (b + c > a)) {
std::cout << "Valid triangle" << std::endl;
} else {
std::cout << "Invalid triangle" << std::endl;
}
return 0;
}
11. 相关网络资源推荐
- C++ Logical Operators - cppreference.com
- Short-circuit Evaluation - Wikipedia