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

  上一篇 <一起学习C语言:C语言基本语法(四)> 中,我们了解了位运算符的语法和不同的应用场景中的选择。本篇文章中,我们分析switch语句,并通过几个示例分析break、#define和三目运算符的应用场景。


章节预览:

5. switch语句
5.1 break用法
5.2 switch语句分析
5.3 #define用法
5.4 switch语句用法
6. 三目运算符
6.1 三目运算符保护形式
7. 本章总结
8. 练习题
目录预览


章节内容:


5. switch语句


  C语言中,if和switch都属于分支结构,其中if分支条件可以是表达式,也可以是常量表达式。而switch入口条件可以是表达式,也可以是常量表达式,而分支条件只能是常量表达式。

 比如:if (a == 1) 语句一 形式一
            else if (a == ‘2’)   形式二
              语句二
            else
              语句三


  使用switch可以写为:
       int a = 1,或a = ‘2’,或a = 0(或a不等于1且a不等于2)
       switch (a 或 常量值) {
       case 1: 语句一 形式一
       case ‘2’:           形式二
         语句二
       default:
         语句三
       }


  【例4.25】 使用伪随机函数rand()得到3以内的值,然后加上“表达式n”的n值并输出结果。

      #include <stdio.h>
      #include <stdlib.h>
      #include <time.h>

      int main() {
         int N = 0;
         srand((unsigned)time(NULL));
         N = rand() % 3;

         switch(N) {
           case 1: (“N=%d,n=%d. \n”, N, N + 1);          //语句形式一
           case 2:                                                         //语句形式二
             printf(“N=%d,n=%d. \n”, N, N + 2);

           default: printf(“N=%d,n=%d. \n”, N, N + 3); //语句形式一
         }
         return 0;
      }


  程序分析

    1. 根据time()函数获取到当前时间,并通过srand()函数重新“播种”伪随机数种子。
    2. 通过rand()函数生成随机数,然后通过取模运算符“%”获取到0-3的整数(3会被整除,余0)。
    3. 由多个switch语句组成的分支结构,它首先从“case 1:”开始判断,如果N不相等1,则继续向下执行一直到“case 2:”,如果都不相等,则进入default:分支下的语句执行。


  程序结果

    【例4.25】 如果N == 1,输出case 1、case 2和default对应的语句块“N=1,n=2.”、“N=1,n=3.”和“N=1,n=4.”,参考图4-19。

在这里插入图片描述

4-19 switch(1)

    如果N == 2,输出case 2和default对应的语句块 “N=2,n=4.”和“N=2,n=5.” ,参考图4-20。

在这里插入图片描述

4-20 switch(2)

    如果N == 0,输出default对应的语句块 “N=0,n=3.” ,参考图4-21。

在这里插入图片描述

图4-21 switch(0)

  结果分析

    【例4.25】 只有N == 0输出的结果是我们想要的,而N1,N2时,都输出了它们之后的分支结果。


  接来下,我们来了解在实际编程中,如何避免这种情况的发生。


5.1 break用法

  上述示例中,switch结构的某个分支内的语句执行完成时,应跳出switch语句块,并执行switch之后的语句。


  【例4.25】 中,switch语句可以改为:

      switch(N) {
        case 1: (“N=%d,n=%d. \n”, N, N + 1); break; //语句形式一
        case 2: //语句形式二
          printf(“N=%d,n=%d. \n”, N, N + 2);
          break;

        default: printf(“N=%d,n=%d. \n”, N, N + 3); //语句形式一
      }

      即分支语句后增加break(12)语句(13)。再次执行程序会发现,输出结果与我们的设计思路符合。


  (12):break属于关键字,它用来跳出switch结构或循环结构使用。

  (13):在C程序中,分号(;)是一条语句的结束符,即“break;”是一条跳转语句。


5.2 switch语句分析

  switch的分支结果范围只能是逻辑值、整数值或字符值,比如:布尔false、整数2或字符’3’。现在我们来分析switch语法:

      switch (N) {
        case !true: printf(“false.”); break;
        case 1 == 1: printf(“1 == 1.”); break;
        case 2:
        {
          printf(“2.”);
          break;
        }
        case ‘3’:
        {
          printf("‘3’.");
        }
        break;
        case 1 << 4:
          printf(“1 << 4.”); break;

        default:
          printf(“default.”);
       }


  示例分析

      第一个case表达式为!true,它的结果为逻辑值“假”,即false或数字0。
      第二个case表达式为1 == 1,它的结果为逻辑值“真”,即true或数字1。
      第三个case是一个数字值2。
      第四个case是一个字符值’3’,转换成数字为51(14)。
      第五个case表达式为1 << 4,即数字16。
      第六个是default(15),它属于默认分支,一般在写case分支最后位置。


  (14):字符值一般选择ascll码表128以内的十进制数字,它的值由一个整数表示。比如字符’3’对应ascll码表中的十进制数字51。字符值转换到整数值也比较简单,即’3’ – ‘0’ = 3,其中字符’0’-‘9’是数字段,我们只需要拿字符值减去它对应的数字段首个值即可得到。类似的情况还有’a’、’A’,它们的数字段长度为26,即表示’a’-’z’和’A’-’Z’。

  (15):default的用法类似于if语句中的else,即所有case都不进入的情况下,进入default。default语句后可以不加break,我们只需把它写在所有case的后面即可。


  上述示例中,无论我们是否使用语句块,都应在执行语句最后写上break语句。使用语句块的情况下,break可以写在语句块内,也可以写在语句块外。


5.3 #define用法


  实际编码时,如果不确定某个常量值是否修改,或者为这个常量值定义一个标识符,可以通过 #define来实现这部分功能。比如case 1,我们为数字1起个名字,可以写成#define TAG 1,完整代码如下:

      #include <stdio.h>
      #include <stdlib.h>
      #define SNOW 1

      int main() {
        int N = 1;
        switch (N) {
          case TAG:
            printf(“1.”);
            break;

          default:
            printf(“default.”);
        }

        return 0;
      }


  #define定义标识符的一般形式为
    #define 标识符 常量

  “#define XXXX XXXX”是在程序编译之前要处理的内容,称为编译预处理命令。

  #define一般称为宏定义,标识符是定义中的宏名称,简称宏。宏在程序中不占内存,它只是一个临时变量,预编译后这个符号就不存在了。宏所表示的常量可以是数字、字符、字符串、表达式。

  #define语句可以写在“#include XXXX”下面,也可以写在函数中。但大部分情况下,都建议写在“#include XXXX”下面。


5.4 switch语句用法


  switch语句中的case分支应写常量值,这样即可以减少编译时的开销,又可以表达出具体数字。比如“case 1 << 4”和 “case 16”,其中“case 16”不通过运算就能表达出具体数字。


  【例4.26】 为了帮助学生更接近实际编程,学校决定购买100套“四通道信号数据采集卡”。每套采集卡工作时,只能开启一个数据通道,通道号占用一个字节,并按照1、10、100、1000二进制数字分别表示通道一至通道四的开启情况。现在,我们根据二进制数字计算出开启通道号。

      根据这个例子,我们首先计算出二进制数字对应的十进制数字,然后通过宏定义写出每个通道的宏

        二进制数字1、10、100、1000,分别对应十进制表达式1 << 0、1 << 1、1 << 2、1 << 3,即十进制数字1、2、4、8。

        #define CHANNEL1 1
        #define CHANNEL2 2
        #define CHANNEL3 4
        #define CHANNEL4 8

        char N = CHANNEL1;
        switch (N)
        {
          case CHANNEL1:
            printf(“通道一.”);
            break;
          case CHANNEL2:
            printf(“通道二.”);
            break;
          case CHANNEL3:
            printf(“通道三.”);
            break;
          case CHANNEL4:
            printf(“通道四.”);
            break;

          default:
            printf(“未开启通道.”);
        }


  示例分析

      1. 程序中使用宏,可以较清晰表达出代码的含义。
      2. 当某个具有实际意义的常量值被大量使用时,使用宏也可以做到避免出错的情况。比如:数字1,它在示例中表示开启通道一,代码中多处使用它时,修改较为困难。如果用宏表示,只需修改宏所对应的常量值。


6. 三目运算符


  C语言中,有一种运算符即可以通过判断条件输出语句,也可以结合赋值运算符为变量赋值,它称为三目运算符。三目运算符由三个表达式或表达式结果组成,又称为三元运算符。


  三目运算符的形式
      表达式1 ? 表达式2 : 表达式3;

  三目运算符的用法
      true ? printf(“表达式成立.”) : printf(“表达式不成立.”);


  【例4.27】 判断int类型变量a和b的值,并输出比较结果。

      int a = 1, b = 2;
      a > b ? printf(“a大于b.”) : printf(“a小于b.”);


  示例结果

      a小于b.


  示例分析

      程序首先执行“a > b ?”,如果为“真”,执行printf(“a大于b.”),否则执行printf(“a小于b.”)。


  【例4.28】 判断int类型变量a和b的值,并把最大值赋给c。

      int a = 1, b = 2, c;
      a > b ? c = a : c = b;
      或
      c = a > b ? a : b;


  示例结果

      c等于2.


  示例分析

      程序首先执行“a > b ?”,如果为“真”,a赋值给c,否则b赋值给c。


  三目运算符的用途不仅仅如此,在后面的示例中将接触更多写法。


6.1 三目运算符保护形式

  当三目运算符与别的运算符一起使用时,也存在优先级的关系,接下来我们了解如何避免因运算符优先级的原因导致结果出错。


  【例4.29】“非”运算符和三目运算符一起运算。

      int a = 1, b = 1, c;
      c = !a == b ? 3 : 2;


  示例结果

      c等于2.


  示例分析

      1. 程序如果先执行“a == b”,得到"!3",结果为“假”,即0。
      2. 程序如果先执行“!a”,得到“0 == 1”,结果为2。

      从输出结果来看,程序执行顺序符合“2.”,即先执行“!a”,破坏了三目运算符的运算数据。


  接下来,增加小括号保护三目运算符

      int a = 1, b = 2, c;
      c = !(a == b ? 3 : 2);


  示例结果

      c等于0.


  示例分析

      这次把三目运算符放入小括号内,得到的结果符合我们的设计逻辑。


  实际使用时,如果我们不能确定三目运算符内是否存在优先级问题,可以写成以下形式

      ((表达式1) ? (表达式2) : (表达式3));


7. 本章总结


  本章节,我们了解了C语言基本语法和不同的运算符的使用方式,日常编程中,我们需要做到正确选择分支结构、正确使用运算符,这样可以避免结构体积庞大、数据运算错误等问题。本章节内容相对简单一些,但也需要多次学习才能完全理解。


8. 练习题


  1. if语句分为几种形式?
  2. 逻辑运算符和关系运算符分别适合哪些场景?
  3. 计算出int类型数字“-1234567 >> 9”的结果,并通过数据保护方式做到清除高位保留低位的效果。
  4. if语句和switch语句有哪些不同之处?如何保证switch执行得到正确结果?
  5. 宏定义是什么?结合宏定义编写出合理的switch结构。
  6. 三目运算符适合用在哪些场景?当a = 1,b = 2,c =3时,计算出!a < b ? a > c ? a : c : b;的结果,然后使用小括号按照“表达式1 ? 表达式2 : 表达式3”执行顺序,编写新的语句。

目录预览


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

发布了102 篇原创文章 · 获赞 225 · 访问量 19万+

猜你喜欢

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