一起学习C语言:C语言基本语法(二)

  上一篇 <一起学习C语言:C语言基本语法(一)> 中,我们了解if语句的语法和不同的应用场景,以及语句块的使用方式。本篇文章中,我们分析逻辑运算符的用法,并通过几个示例分析逻辑运算符之间的执行顺序。


章节预览:

2. 逻辑运算符
2.1 逻辑运算符用法
2.2 布尔型变量
2.3 逻辑表达式
2.4 逻辑运算符的优先级
目录预览


章节内容:


2. 逻辑运算符

  部分场景下,一个简单条件已无法满足判断需求时,可以通过对多个简单条件优化,组成复合条件。

  【例2.1】 如果今天不上班,并且健身房照常营业,那么我会去健身房锻炼。
   这个示例是由两个简单条件组成的复合条件:1. 今天是否上班;2. 健身房是否营业。只有这两个条件都满足时,才去健身房。


2.1 逻辑运算符用法

  逻辑运算符分为三种:与(&&)、或(||)、非(!)。参考图2.1-1 逻辑运算符表:

逻辑运算符 英文名 含义 相近含义 举例 说明
&& AND 逻辑与 且/而且 a && b 如果a和b都为真,则表达式成立,否则表达式不成立
|| OR 逻辑或 或者 a || b 如果a或b其中一个为真,则表达式成立,否则表达式不成立
! NOR 逻辑非 不等于 !a 如果a为假,则!a为真,表达式成立,如果a为真,则!a为假,表达式不成立
2.1-1 逻辑运算符表

  现在我们分析 【例2.1】
    根据这个例子,我们选择使用“&&”,表示式为:if (今天不上班 && 健身房照常营业)。

    表达式成立代码

        int a = 1, b = 1;
        if (a == 1 && b == 1)
        {
            printf(“表达式成立。”);
        }
        else
        {
            printf(“表达式不成立。”);
        }


 【例2.2】 班主任在同学们的提议下组织一次春游活动。如果参团人数达到50人,使用班级费用报销活动费用。如果参团人数少于50人,则由每位参团同学交纳20元钱用于活动费用,如果同学们不愿交纳活动费用,则取消春游活动。

    根据这个例子,我们选择使用“||”,表示式为:if (参团人数大于等于50人 || 每位参团同学交纳20元钱)。

    表达式不成立代码
        int a = 49, b = 0;
        if (a >= 50 || b == 20)
        {
            printf(“本次春游活动组织成功,同学们可以玩耍一天了。”);
        }
        else
        {
            printf(“本次春游组活动织失败,同学们继续上课。”);
        }


    程序分析

     【例2.1】【例2.2】 实现代码中,我们分别使用了与、或运算符,并通过对变量值修改,制造出表达式成立和表达值不成立两种情况。在实际编程中,我们需要考虑更多的因素,比如:数据是否异常、数据值范围不明确、运算符的优先级等问题。

    逻辑与、或运算符分析

      “&&”、“||”属于双目运算符,它需要有两个运算对象,比如: (a != 0) && (b != 0) ,(a != 0) || (a > b)。“&&”和“||”的执行顺序都是从左向右,即先判断左侧条件,然后判断右侧条件。

  现在,我们还没有讲述“!”运算符,别着急!我们先了解一个新的变量,参考这个变量更容易理解。


2.2 布尔型变量

  在C99标准中,增加了一种称作“逻辑型”的单字节数据类型,一般叫做布尔型。布尔型的原型是_Bool关键字,定义在<stdbool.h>文件中,程序中一般使用它的宏定义bool。bool类型拥有两个符号常量true和false,true代表1,false代表0,程序中用它们表示真和假。

    布尔型在程序可以这么用
      int a = 1, b = 2;
      bool c = a < b; //关系赋值

      或 bool a = true, b = false; //直接赋值


 【2.3】 班主任在同学们的提议下组织一次春游活动。如果参团人数少于50人,使用班级费用报销活动费用。如果参团人数达到50人,则由每位参团同学交纳20元钱用于活动费用,如果同学们不愿交纳活动费用,则取消春游活动。

   (1) 根据这个例子,我们选择使用“!”,表示式为:if (!(参团人数大于等于50人 || 每位参团同学交纳20元钱))。

        表达式成立代码

            int a = 20, b = 0;
            if (!(a >= 50 || b == 20))
            {
                printf(“本次春游活动组织成功,同学们可以玩耍一天了。”);
            }
            else
            {
                printf(“本次春游组活动织失败,同学们继续上课。”);
            }


   (2) 现在使用bool对象编写if语句,表示式为:if (!c)。

        表达式不成立代码

            int a = 50, b = 0;
            bool c = a >= 50 || b == 20;
            if (!c)
            {
                printf(“本次春游活动组织成功,同学们可以玩耍一天了。”);
            }
            else
            {
                printf(“本次春游组活动织失败,同学们继续上课。”);
            }


    程序分析

     【例2.3】 我们编写两种实现代码:(1)采用“!”和“||”两种逻辑运算符组合编写,这种方式需要我们理解不同逻辑运算符之间的优先级关系,稍有不慎就会得到意料之外的结果。(2)采用“!”和布尔型对象组合编写,这种方式可以让我们更容易分析判断逻辑,但在实际编程中,使用第一种(1)方式更直观一些。
实现代码(1)和(2)表达的意思相同,首先运算出逻辑或表达的值,然后通过“!”运算取反结果,即1取反为0,0取反为1。


    逻辑非运算符分析
      “!”属于单目运算符,它要求有一个运算对象,比如:!a,!(a > b)。“!”的执行顺序是从右向做,即先判断右侧条件,然后结果取反,即“真”为“假”,“假”为“真”。


2.3 逻辑表达式

  由逻辑运算符“控制”运算结果的表达式,称为逻辑表达式。逻辑表达式的结果由数字1或数字0,即“真”或“假”表示,结果为“真”时,即表达式成立,结果为“假”时,即表达式不成立。而在一个条件中,“假”由0表示,而“真”由非0值表示,比如:

  1. !(条件)
形式 描述 非运算形式 结果
!-2,!2,!(a = -2) 条件得到的都是非0值,由“真”表示。 !真 “假”,即0。
!0,!(a = 0) 条件得到的值都为0,由“假”表示。 !假 “真”,即1。

  1. 条件1 && 条件2
形式 描述 与运算形式 结果
0 && (a = -2) 它的条件1得到的值为0,即“假”,直接可以得出“&&”运算结果。 假 && 不需要运算 “假”,即0。
(a = 2) && 0 它的条件1中,首先变量a赋值为2,得到条件值为2,即“真”。它的条件2得到的值为0,即“假”。 真 && 假 “假”,即0。
(a = 2) && (b = -2) 它的条件1中,首先变量a赋值为2,得到条件值为2,即“真”。它的条件2中,首先变量b赋值为-2,得到条件值为-2,即“真”。 真 && 真 “真”,即1。

  1. 条件1 || 条件2
形式 描述 或运算形式 结果
2 || (a = 0) 它的条件1得到的值为2,即“真”,直接可以得出“||”运算结果。 真 || 不需要运算 “真”,即1。
0 && (a = -2) 它的条件1得到的值为0,即“假”。它的条件2中,首先变量a赋值为-2,得到条件值为-2,即“真”。 假 && 真 “真”,即1。
0 && 0 它的条件1和条件2得到的值都为0,即都为“假”。 假 && 假 “假”,即0。

2.4 逻辑运算符的优先级

  在一个逻辑表达式中,可以包含多个逻辑运算符,比如:!(a != 0) && (a > 2) || (b == 0)。这时候,需要我们了解每个逻辑运算符的优先顺序,才能设计出我们需要的表达式。下面我们编写个示例,分析出它们之间的执行顺序。

  【例2.4】 通过“!(a != 0) && (a > 2) || (b == 0)”表达式分析出“!”、“&&”和“||”之间的执行顺序。

      根据不同逻辑运算符的特性,我们可以把示例中的表达式分成多个部分单独运算

        【部分1】 通过“&&”运算符编写出结果为“真”的表达式:

             int a = 20;
             if ((a != 0) && (a > 2))
             {
                 printf(“表达式成立。”);
             }
             else
             {
                 printf(“表达式不成立。”);
             }

        【部分1】 执行结果:
             输出:“表达式成立。”。


        【部分2】 在部分1的实现代码中,分别在表达式左侧和右侧判断条件前增加“!”运算符,并输出结果:

            【部分2.1】 左侧增加“!”运算符:

                 int a = 20;
                 if (!(a != 0) && (a > 2))
                 {
                     printf(“表达式成立。”);
                 }
                 else
                 {
                     printf(“表达式不成立。”);
                 }

           【部分2.1】 执行结果:
                输出结果为:“表达式不成立。”。


           【部分2.2】 右侧增加“!”运算符:
                int a = 20;
                if ((a != 0) && !(a > 2))
                {
                    printf(“表达式成立。”);
                }
                else
                {
                    printf(“表达式不成立。”);
                }

           【部分2.2】 执行结果:
                输出结果为:“表达式不成立。”。


        【部分2】 执行分析:

示例原型 运算表达式 结果
(a != 0) && (a > 2) 真 && 真 “真”,即1。
!(a != 0) && (a > 2) 假 && 真 “假”,即0。
(a != 0) && !(a > 2) 真 && 假 “假”,即0。

            【部分2】 实现代码,在“与”表达式成立的基础上,分别在左侧和右侧条件前增加“非”运算符,值都为“假”。可以推算出“与”的优先级低于“非”,即“!”->“&&”。

            接下来计算“与”和“或”之间的执行顺序,如果“与”的优先级高于“或”,那么不用再继续判断,即可得出结论。


        【部分3】 在部分1的实现代码中,分别在表达式左侧和右侧判断条件增加“||”运算符和条件,并输出结果:
            【部分3.1】 左侧增加“||”运算符和条件:

                  int a = 20, b = 0;
                  if ((b == 0) || (a != 0) && (a < 20))
                  {
                      printf(“表达式成立。”);
                  }
                  else
                  {
                      printf(“表达式不成立。”);
                  }

            【部分3.1】 执行结果:
                  输出结果为:“表达式成立。”。

            【部分3.1】 执行分析:

                  这个示例比较烧脑,我们分析一下它的执行思路。
                  如果程序先执行“(b == 0) || (a != 0)”这部分,得到结果为“真”, (a < 20)得到的结果为“假”,可以得到“与”表达式“真 && 假”,示例结果为“假”,表达式不成立。
                  但实际结果为“真”,只能先执行“与”表达式,得到结果为“假”,然后执行“或”表达式“真 || 假”,示例结果为“真”,表达式成立。


            【部分3.2】 右侧增加“||”运算符和条件:

                  int a = 20, b = 0;
                  if ((a < 0) && (a > 2) || (b == 0))
                  {
                      printf(“表达式成立。”);
                  }
                  else
                  {
                      printf(“表达式不成立。”);
                  }

            【部分3.2】 执行结果:
                  输出结果为:“表达式成立。”。

            【部分3.2】 执行分析:
                  如果程序先执行“(a > 2) || (b == 0)”这部分,得到结果为“真”,(a < 0)得到的结果为“假”,可以得到“与”表达式“假 && 真”,示例结果为“假”,表达式不成立。
                  但这里的实际结果也为“真”,只能先执行“与”表达式,得到结果为“假”,然后执行“或”表达式“假 || 真”,示例结果为“真”,表达式成立。


        【部分3】 执行分析:

示例原型 运算表达式 结果
(a != 0) && (a > 2) 真 && 真 “真”,即1。
(b == 0) || (a != 0) && (a < 20) 真 || (真 && 假) “真”,即1。
(a < 0) && (a > 2) || (b == 0) (假 && 真) || 真 “真”,即1。

              部分3实现代码,在“与”表达式成立的基础上,分别在左侧和右侧条件增加“或”运算符和条件,值都为“真”。可以推算出“与”的优先级高于“或”,即“&&”->“||”。

    程序分析

       【例2.4】 我们通过三部分表达出了逻辑运算符之间的关系,首先通过“与”运算符和“非”运算符比较,得出“非”的优先级高于“与”,然后通过“与”运算符和“或”运算符比较,得出“与”的优先级高于“或”的结论。
“与”、“或”、“非”,之间的优先级关系为:“非”高于“与”,“与”高于“或”,即“!” ->“&&” ->“||”。

    实际编程中,在我们不清楚运算符之间的优先级时,可以通过小括号进行代码保护,比如:!( (a < 0) && ( (a > 2) || (b == 0) ) )


目录预览


<一起学习C语言:C语言发展历程以及定制学习计划>
<一起学习C语言:初步进入编程世界(一)>
<一起学习C语言:初步进入编程世界(二)>
<一起学习C语言:初步进入编程世界(三)>
<一起学习C语言:C语言数据类型(一)>
<一起学习C语言:C语言数据类型(二)>
<一起学习C语言:C语言数据类型(三)>
<一起学习C语言:C语言基本语法(一)>

发布了95 篇原创文章 · 获赞 215 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/a29562268/article/details/104330798