1. 逻辑关系“与” #
我们来回忆一下之前学习的 if 嵌套结构。
if(input > 0) // 条件表达式 1 { if(input <= 10) // 条件表达式 2 { // 执行语句 X } }
请问:(选择题)
如果,我们希望执行“语句 X”,“条件表达式 1 ” 和 “条件表达式 2 ” 应该是什么关系?
- A. “条件表达式 1 ” 和 “条件表达式 2 ” 都成立;
- B. “条件表达式 1 ” 成立, “条件表达式 2 ” 不成立;
- C. “条件表达式 1 ” 不成立, “条件表达式 2 ” 成立;
- D. “条件表达式 1 ” 和 “条件表达式 2 ” 都不成立;
这里,应该是选择“条件表达式 1 ” 和 “条件表达式 2 ” 都成立;
还记得我们在数学中,怎么表达这样的关系吗?
上面的关系,在数学中被称为: 逻辑关系“与”。
1.1 逻辑关系表达式 #
上面的数学不等式,在 C++ 可以表达为:
0 < input && input >= 10
- C++ 中,使用 && 来表示 逻辑关系“与”;
- 符号 && 表示:判断“条件表达式 1 ” 和 “条件表达式 2 ” 是不是都成立;
- 这也是一种“表达式”,我们称之为“逻辑关系表达式”,逻辑关系“与” 是其中的一种;
- 【注意】不能写成:0 < input <= 10; 这不是 C++ 语法;
上面的关系,可以再写作:
bool is_ok; is_ok = 0 < input && input <= 10; is_ok = (0 < input) && (input <= 10); // 可以有括号 0 < input <= 10; // 【错误】注意,C++ 不支持这样的语法,必须使用 && 表达“与”关系。
“逻辑关系表达式”的取值说明:
bool output = “条件表达式 1 ” && “条件表达式 2 ”
条件表达式 1 | 条件表达式 2 | output |
true | true | true |
false | true | false |
true | false | false |
false | false | false |
1.2 逻辑关系“与”的辅助理解 #
- 逻辑关系“与”的理解1:
- 逻辑关系“与”的理解2:
- 逻辑关系“与”的理解3:
2. 逻辑关系“或” #
小练习:
C++ 成绩达标或者数学成绩达标,都可以获得一个小奖品。
请编程,模拟判断,小明是否可以获奖。
请输入 1 或者 2,分别表示 “C++ 成绩达标” 和 “数学成绩达标”,输入其它数字,则输出“你还需要努力哦!”。
// 请编程。完成后,查看后续示例程序。(提示:使用else if)
示例程序:
#include <iostream> using namespace std; int main() { int input(0); cout << "请输入 1 或者 2" << endl; cin >> input; if(input == 1) cout << "恭喜你,获得一个小奖品!" << endl; else if(input == 2) cout << "恭喜你,获得一个小奖品!" << endl; else cout << "你还需要努力哦!" << endl; return 0; }
我们来详细看一下上面的 if 结构。
if(input == 1) // 条件 1 { cout << "恭喜你,获得一个小奖品!" << endl; // 语句 X,注意,和下面的一样。 } else if(input == 2) // 条件 2 { cout << "恭喜你,获得一个小奖品!" << endl; // 语句 X,注意,和上面的一样。 }
请问:(选择题)
如果,我们希望执行“语句 X”,“条件表达式 1 ” 和 “条件表达式 2 ” 应该是什么关系?
- A. “条件表达式 1 ” 和 “条件表达式 2 ” 都成立;
- B. “条件表达式 1 ” 成立, “条件表达式 2 ” 不成立;
- C. “条件表达式 1 ” 不成立, “条件表达式 2 ” 成立;
- D. “条件表达式 1 ” 和 “条件表达式 2 ” 都不成立;
这里,应该是选择ABC;
还记得我们在数学中,怎么表达这样的关系吗?
上面的关系,在数学中被称为: 逻辑关系“或”。
2.1 逻辑关系表达式 #
上面的数学不等式,在 C++ 可以表达为:
input == 1 || input == 2
- C++ 中,使用 || 来表示 逻辑关系“或”;
- 符号 || 表示:判断“条件表达式 1 ” 和 “条件表达式 2 ” 是不是有一个成立;
- 这也是一种“表达式”,我们称之为“逻辑关系表达式”,逻辑关系“或” 是其中的一种;
- 【注意】判断相等,需要使用符号 ==;
上面的关系,可以再写作:
bool is_ok; is_ok = input == 1 || input == 2; is_ok = (input == 1) || (input == 2); // 可以有括号
“逻辑关系表达式”的取值说明:
bool output = “条件表达式 1 ” || “条件表达式 2 ”
条件表达式 1 | 条件表达式 2 | output |
true | true | true |
false | true | true |
true | false | true |
false | false | false |
2.2 逻辑关系“或”的辅助理解 #
- 逻辑关系“或”的理解1:
- 逻辑关系“或”的理解2:
- 逻辑关系“或”的理解3:
3. 逻辑关系“非” #
小练习:
请补全下面的程序,判断一个数是否是负数。
如果是,则输出“是负数”。否则不做处理。
// 请补全 #include <iostream> using namespace std; int main() { int input(0); cout << "请输入一个整数" << endl; cin >> input; if(input >= 0) { } else { } return 0; }
示例程序:
#include <iostream> using namespace std; int main() { int input(0); cout << "请输入一个整数" << endl; cin >> input; if(input >= 0) { } else { cout << "是负数" << endl; } return 0; }
我们来详细看一下上面的 if 结构。
if(input >= 0) // 条件 1 { } else { cout << "是负数" << endl; // 语句 X }
请问:(选择题)
如果,我们希望执行“语句 X”,“条件表达式 1 ” 应该如何?
A. “条件表达式 1 ” 成立;
B. “条件表达式 1 ” 不成立;
这里,应该是选择B;
还记得我们在数学中,怎么表达这样的关系吗?
上面的关系,在数学中被称为: 逻辑关系“非”。
其实,逻辑关系“非”非常容易理解,甚至还有点哲学的味道。
一些通俗的解释:
逻辑关系“非”是硬币的另一面;
中国传统哲学讲阴阳,如果一个表达式为“阳”,那么他的“非”就是“阴”;
3.1 逻辑关系表达式 #
3.1.1 “!”符号 #
上面的数学不等式,在 C++ 可以表达为:
!(input >= 0) // 这里的 括号 不能缺少。
C++ 中,使用 ! 来表示 逻辑关系“非”;
符号 ! 表示:取反“条件表达式 1 ” ;
这也是一种“表达式”,我们称之为“逻辑关系表达式”,逻辑关系“非” 是其中的一种;
上面的关系,可以再写作:
bool is_ok; is_ok = !(input >= 0); is_ok = !(is_ok); // 如果是变量,可以省略括号 is_ok = !is_ok; // 如果是变量,可以省略括号 is_ok = !true; // 如果是 bool 值,可以省略括号 is_ok = !0; // 如果是 bool 值,可以省略括号
“逻辑关系表达式”的取值说明:
bool output = !(条件表达式 1)
条件表达式 1 | output |
true | false |
false | true |
3.1.2 取反“关系表达式” #
在上面的代码中,你一定发现了,我们还可以这样来改写;
if(input >= 0) // 条件 1 { } else { cout << "是负数" << endl; // 语句 X }
等价于下面的写法
if(input < 0) // 条件 2 { cout << "是负数" << endl; // 语句 X }
请仔细分析以一下,条件 1 和 条件 2 的逻辑关系。
!(input >= 0) <== 等价于 ==> (input < 0)
很显然,这个逻辑是成立的。
我们来看一些例子:
!(input >= 0) <== 等价于 ==> (input < 0) !(input > 0) <== 等价于 ==> (input <= 0) !(input == 0) <== 等价于 ==> (input != 0) !(input <= 0) <== 等价于 ==> (input > 0) !(input < 0) <== 等价于 ==> (input >= 0) !(true) <== 等价于 ==> (false) !(false) <== 等价于 ==> (true)
至此,请务必掌握这里列出的所有变换。
3.2 逻辑关系“非”的辅助理解 #
- 逻辑关系“非”的理解1:
- 逻辑关系“非”的理解2:
4. “关系运算符”和“逻辑运算符”的运算优先级 #
在数学中,我们学习过四则运算,还记得加减乘除的“运算优先级”吗?
+ - 运算优先级相等; * / % 运算优先级相等; // C++ 的取余运算,是数学中还没有学习到的。特此补充说明 + - 运算优先级小于 * / % // 也就是,先计算 * / %,后计算 + -
在“关系运算符”和“逻辑运算符”中,其实也有“运算优先级”。
它们的“运算优先级”,从高到底排列如下:
高 - ! 中 - && || 运算优先级相等; 低 - < <= == != > >= 运算优先级相等;
请看下面的表达式,并在数轴上画出 a 的范围。
-2 < a && a < 2
请看下面的表达式,并在数轴上画出 a 的范围。
!(-2 < a && a < 2)
4.1 图解法 #
答案:
- -2 < a && a < 2
- !(-2 < a && a < 2)
小练习:
请将 !(-2 < a && a < 2) 对应的答案图,改写成“或”关系的表达式。
答案:
!(-2 < a && a < 2) <== 等价于 ==> (-2 >= a || a >= 2)
理解这样的改写,对 C++ 的学习非常重要。针对这一的问题,主要有两种思路。
- 1. 图解法 – 如上面的说明
- 2. 分解法
4.2. 分解法 #
在解题前,我们先来思考以下的几种情形。
请回答:
!(true && true ) <== 等价于 ==> ? !(true && false) <== 等价于 ==> ? !(false && true ) <== 等价于 ==> ? !(false && false) <== 等价于 ==> ? !(true || true ) <== 等价于 ==> ? !(true || false) <== 等价于 ==> ? !(false || true ) <== 等价于 ==> ? !(false || false) <== 等价于 ==> ?
答案:
!(true && true ) <== 等价于 ==> (false || false) !(true && false) <== 等价于 ==> (false || true ) !(false && true ) <== 等价于 ==> (true || false) !(false && false) <== 等价于 ==> (true || true ) !(true || true ) <== 等价于 ==> (false && false) !(true || false) <== 等价于 ==> (false && true ) !(false || true ) <== 等价于 ==> (true && false) !(false || false) <== 等价于 ==> (true && true )
基于上面的分析,我们可以得到这样的规律:
- 1. && 和 || 互换;
- 2. true 和 false 互换;
那接下来我们来看一下,怎么解决上述的问题。
!(-2 < a && a < 2) || \/ !((-2 < a) && (a < 2)) // 根据计算的优先级,加括号。 || \/ !((******) && (#####)) // 将第二层的括号内容,看成整体。 || \/ !(-2 < a ) || !(a < 2) // 先分解最外层括号。 || \/ -2 >= a || a >= 2 // 继续分解当下的最外层括号。
如果遇到多层的逻辑关系嵌套,也像这样,由外向内,逐层分解即可。
小练习:
!(a <= 7 || 20 < a) <== 等价于 ==> !(15 < a && a < 59) <== 等价于 ==> !(a > 5) && a < 10 <== 等价于 ==> !(true && false && true) <== 等价于 ==> !(true || false || true) <== 等价于 ==>
答案:
!(a <= 7 || 20 > a) <== 等价于 ==> 7 < a && a <= 20 !(15 < a && a < 59) <== 等价于 ==> a <= 15 || a >= 59 !(a > 5) && a < 10 <== 等价于 ==> 5 <= a && a < 10 !(true && false && true) <== 等价于 ==> (false || true || false) !(true || false || true) <== 等价于 ==> (false && true && false)