单片机C语言编程实践
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

3.6 选择结构

假如某一单位要给职工增加工资,它的规定是工资低于2000元的职工,每人增加工资200元,超过2000元的职工增加工资100元。

如果用计算机解决上述问题,首先用关系运算判断工资是否低于2000元,如果是“真”,就选择增加工资200元,否则选择增加工资100元。

在C语言中,一般用关系运算、逻辑运算解决选择结构中的选择条件;用if、switch语句实现选择结构,if语句实现2路选择,switch语句实现多路选择。选择语句又称为分支语句或开关语句。

3.6.1 if语句

if语句根据给定选择条件的表达式值为“真(非0)”或”假(0)”两种情况,从两个供选择的成分语句中自动选取一个语句执行,它有以下3种形式。

1.第一种形式

      if(表达式){ 语句;}

执行过程:计算表达式的值,如果表达式的值为“真(非0)”,则执行其后的语句,并结束if语句,否则立即结束if语句。

例如:输入三个整数,输出其中的最大数。

为求三个数中的最大者,最简洁的办法是先将其中某一个数预设为最大,存于某变量中,然后逐一与其他两个数比较,当发现有更大者时,就以它重置该变量的值,最后变量中存储的就是最大数。

【例3-10】

      main()
      { int a, b, c, max;
        printf("请输入三个整数:");
        scanf("%d%d%d", &a, &b, &c);
        max = a;
        if (max <b) max = b;
        if (max <c) max = c;
        printf("最大数是%d\n", max);
      }

程序运行结果如图3-10所示。

图3-10 程序运行结果

if语句中if之后括号内的表达式,一般为逻辑表达式或关系表达式,如if语句:“if(a !=0 && x/a>0.5)printf("a != 0 && x/a > 0.5\n");”。

在C语言中,if语句对表达式的值的测试以“非0”或“0”作为真或假的标准,所以当if语句以某表达式的值不等于0作为条件时可直接简写成表达式作为条件。

例如:

      if (x+y != 0) printf("x + y != 0\n");

可简写成:

      if (x+y) printf("x + y != 0\n");

而语句:

      if (x == 0) printf("x = 0\n");

可写成:

      if (!x) printf("x = 0\n");

2.第二种形式

      if(表达式){ 语句1;}
      else{ 语句2;}

执行过程:计算表达式的值,若表达式的值为“真(非0)”,则执行语句1,并结束if语句;否则执行语句2,并结束if语句。

注意

无论条件表达式的值为何值,只能执行语句1或语句2中的一个。else子句(可选)是if语句的一部分,必须与if配对使用,不能单独使用。

【例3-11】

根据三角形的三条边长a、b、c,求三角形面积。

      #include<math.h>                     //包含数学计算库函数
      main()
      {  float a, b, c, s, area;
        printf("please input 3 lengths of the three altitudes of a triangle:\n");
        scanf("%f%f%f", &a,&b,&c);
        if(a+b>c&&b+c>a&&c+a>b)           //判断输入数据是否有效
          {s=(a+b+c)/2.0;
          area=sqrt(s*(s-a)*(s-b)*(s-c));
              }
        else{ area=0.0; }
        printf("The area of the triangle is %f\n", area);
        }

程序运行结果如图3-11所示。

图3-11 程序运行结果

【例3-12】

输入任意三个整数,求三个数中的最大值。采用直接比较方式,不设中间变量。

      main()
      {  int n1,n2,n3 ;
        printf("please input 3 integers:\n");
        scanf("%d, %d, %d",&n1,&n2,&n3);
        if(n1>n2){
              if (n1>n3) printf("max=%d\n", n1);
              else printf("max=%d\n", n3);
                  }
        else{
          if(n2>n3) printf("max=%d\n", n2);
          else printf("max=%d\n", n3);
              }
      }

程序运行结果如图3-12所示。

图3-12 程序运行结果

3.第三种形式

      if(表达式1){ 语句组1;}
      else if(表达式2){ 语句组2;}
      else if(表达式3){ 语句组3;}
      …
      else if(表达式n-1){ 语句组n-1;}
      else{ 语句组n;}

执行过程:计算“表达式1”的值,为“真(非0)”时,则执行语句组1,并结束if语句;否则计算“表达式2”的值,为“真(非0)”时,则执行语句组2,并结束if语句;以此类推,当全部条件不满足时,执行else里的语句组n。

在if语句第3种形式中,else if不能单独出现,其数量不受限制,从语句组1到语句组n,有且仅有一条语句组被执行。if语句第3种形式可实现多路选择,if语句第1、2种形式是第3种形式的简化。

【例3-13】

输入“+、-、*、/”4种运算符,输出对应的英文单词。

      #include<stdio.h>
      main()
      { char ch;
        ch=getchar();
          if(ch=='+'){ printf("plus\n"); }
            else if(ch=='-'){ printf("minus\n"); }
            else if(ch=='*'){ printf("multiply\n"); }
            else if(ch=='/'){ printf("divide\n"); }
            else{ printf("error\n"); }
      }

程序运行结果如图3-13所示。

图3-13 程序运行结果

在if语句的3种形式中,如果if、else、else if后面只有一条语句,可以省略大括号{ },但为了便于理解,作为习惯,建议不要省略。

3.6.2 if语句的嵌套与嵌套匹配原则

if语句嵌套,是指if、else、else if执行的语句中又包含有if语句的情况。例如:按学生得分(score)输出成绩等级A、B、C、D。

      if(score>=90) printf("A") ;
      else if(score<60) printf("D");
      if(score>=80) printf("B");
      else printf("C");

上面的程序,比较难看出选择关系,为避免不同理解,C语言约定:if语句嵌套时,else子句与在它上面、距它最近、且尚未匹配的if配对。

在编程时,为使程序清晰、易于阅读,处于同一层的if和else对齐,低一层的if和else缩进,全部使用大括号{}进行限定。

【例3-14】

      main()
      { int a, b, c, d, x;
        a=b=c=0; d=20;
        if(a){ d=d-10; }
        else if(d+2)
              {
            if(!c){ x=15; }
            else{ x=25; }
              }
        else{ x=35; }
        printf("d=%d,x=%d\n",d,x)
      }

程序运行结果如图3-14所示。

图3-14 程序运行结果

3.6.3 switch语句

C语言提供switch语句用于描述多路选择情况,其一般形式如下。

        switch(表达式)
        { case常量表达式1:语句组1;
              case常量表达式2:语句组2;
              ...
              case常量表达式n:语句组n;
              default:语句组n+1;
        }

说明如下:

① case、default只能在switch语句中使用。

② switch后面括号内的表达式只限于是int整型、char字符型或enum枚举型表达式。

③ 要求case后的所有常量表达式的值互不相同,并与switch后面括号内的表达式值的类型相一致。

④ 多个case子句可共用同一语句组,default可以缺省,但最多出现一次,各个case和default的出现次序不影响选择结果。

执行过程:先计算表达式的值,将该值依次与各case之后的常量表达式的值比较,按下列比较结果,选择执行的入口。

① 如果表达式的值等于某个常量表达式的值,switch语句就从该常量表达式之后的语句组的第一个语句开始执行,然后一直向下执行,如果没有break或其他转向语句提前结束switch语句,就自动依次进入每一个常量表达式之后的语句组继续执行,直到执行完语句组n+1,结束switch语句。

注意

case后面的常量表达式仅起语句标号作用,并不进行条件判断。一旦找到入口标号,就从此标号开始执行,不再进行标号判断。

② 如果没有相匹配的常量表达式,就执行default后面的语句组n+1,并结束switch语句。

③ 如果没有相匹配的常量表达式,也没有default,则立即结束switch语句。

【例3-15】

根据输入字母,显示相应的字符串。

      main()
      {char choice;
        printf("Enter choice !(A, B, C, ...)\n");
        scanf("%c", &choice);
        printf("\n");
        switch(choice){
                  case 'A': printf(" A chosen!\n");
                  case 'B': printf(" B chosen!\n");
                  case 'C':
                  case 'D': printf(" C,D chosen!\n");
                  default: printf(" default chosen!\n");
                        }
      }

执行上述示例程序时,输入字符'B',则程序的执行将如图3-15所示输出。

图3-15 程序运行结果

由于choice的值为'B',进入case 'B'的语句序列执行,由于没有提供转出手段,因此执行将穿过case 'C', case 'D'和default,顺序执行这些选择的语句序列,产生上述的输出结果。

如果要使各种情况互相排斥,仅执行各case所对应的语句序列,最常用的办法是使用break语句。

3.6.4 break语句

在switch语句中,执行break语句将结束当前switch语句,使控制转向switch语句的后继语句。

【例3-16】

从键盘上输入一个百分制成绩score,按下列原则输出其等级。

      score≥90,         //等级为A;
      80≤score<90,     //等级为B;
      70≤score<80,     //等级为C;
      60≤score<70,     //等级为D;
      score<60,       //等级为E
      main()
      { int score, grade;
        printf("Input a score(0~100): ");
        scanf("%d", &score);
        grade= score/10;                 // 成绩整除10,转化case标号
        switch (grade)
          { case 10:
            case  9: printf("grade=A\n"); break;
            case  8: printf("grade=B\n"); break;
            case  7: printf("grade=C\n"); break;
            case  6: printf("grade=D\n"); break;
            case  5:
            case  4:
            case  3:
            case  2:
            case  1:
            case  0: printf("grade=E\n"); break;
            default: printf("The score is out of range!\n");
            }
      }

程序运行结果如图3-16所示。

图3-16 程序运行结果

若输入score为101~109或-1~-9中某数,输出如何呢?读者可以考虑如何修改使本程序更加完备。

由于switch语句用于选择的常量表达式的数量有限,当表达式范围较宽时,通常乘上一个适当的比例因子,将表达式的值映照到一个较小的范围内。

【例3-17】

switch语句的嵌套使用:

      main()
      { int a=2, b=7, c=5;
        switch(a>0)
      {
        case 1: switch(b<0){
                            case 0: printf("@"); break;
                            case 1: printf("! "); break;
                        }
        case 0: switch(c==5){
                            case 0: printf("*"); break;
                            case 1: printf("#"); break;
                            default: printf("$"); break;
                        }
        default: printf("&");
        }
      }

程序运行结果如图3-17所示。

图3-17 程序运行结果