跳至正文
View Categories

4 min read

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条件表达式 2output
truetruetrue
falsetruefalse
truefalsefalse
falsefalsefalse

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条件表达式 2output
truetruetrue
falsetruetrue
truefalsetrue
falsefalsefalse

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)
条件表达式 1output
truefalse
falsetrue

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)

5. 小结 #

5.1 “与”、“或”、“非”的意义 #

5.2 “与”、“或”、“非”的取值 #

5.3 “与”、“或”、“非”和 if 的联系 #

6. 课后练习 #

  1. 判断一个数能否同时被3和5整除
  2. 闰年判断
  3. 公交卡充值问题
  4. 小明家的电费
  5. 小高考