首页 > 代码库 > c语言中的选择结构

c语言中的选择结构

     选择结构体现了程序的判断能力。具体地说,在程序执行中能依据运行时某些变量的值。确定某些操作是做还是不做,或者确定若干个操作中选择哪个操作来执行。选择结构有三种形式:单分支结构、双分支结构、多分支结构。C语言为这三种结构分别提供了相应的语句。

一、单分支选择语句

在C语言中,实现单分支结构的语句称为if语句。

[格式] if(表达式) 
         语句;
[功能] 计算表达式的值。如果为真(非0)则执行“语句”,否则不执行语句。
[说明]
(1) 表达式可以是任何类型,常用的是关系或逻辑表达式。
(2) 语句可以是任何可执行语句,也可以是另一个if语句(称嵌套if语句)。
(3) 语句可以是单一语句或复合语句。

【例】简单的if语句。输入一个字符,若是字母则输出“YES!"。
程序清单如下:
main()
{

     char c; 
     printf("输入一个字符:");
     scanf("%c",&c);
     if(c>=‘a‘&&c<=‘z‘||c>=‘A‘&&c<=‘Z‘)  
     printf("YES!\n");
}

【例】嵌套的if语句。输入一个整数,若是大于5且小于10的,则输出“5<AND<10"。
程序清单如下:
main()
{

      int x;
      scanf("%d",&x);
      if(x>5)  
      if(x<10)  
      printf("5<AND<10\n");
}

注意,程序中第一个“if语句”中的“语句”又是一个“if语句”,这种结构称为“嵌套的if语句”。可以看出“嵌套的if语句”等同于下面单个“if语句”:
if((x>5)&&(x<10)) 
  printf("5<AND<10\n");

二、双分支选择语句

在C语言中,实现双分支结构的语句称为if-else语句。

[格式] if(表达式) 
         语句1;
    else 
         语句2;
[功能]计算表达式的值。如果为真(非0)则执行“语句1”,否则执行“语句2”。
[说明]
(1) 表达式可以是任何类型的,常用的是关系或逻辑表达式。
(2) “语句1”和“语句2”可以是任何可执行语句,当然也可以是另一个if-else语句(称嵌套的if-else语句)。
(3) 作为结构化程序的书写要求,通常都是将else及其后的语句2另起一行,并且让else和if对齐。
(4) 语句1或语句2可以是单一语句或复合语句(如果必须使用两个以上的语句时)。

【例】简单的if-else语句。输入一个字符,若是字母则输出“YES!”;否则输出“NO!”。
程序清单如下:
main()

    char c; 
    printf("输入一个字符:");
    scanf("%c",&c);
    if(c>=‘a‘&&c<=‘z‘||c>=‘A‘&&c<=‘Z‘) 
    printf("YES!\n");
    else 
    printf("NO!\n");
}

【例】嵌套的if-else语句。计算下列分段函数,x由键盘输入。
    ┌ 0  (x<-1.0)
  y =├ 1  (-1.0<=x<=1.0)
    └ 10 (1.0<x)
程序清单如下:
main()

    int y; 
    float x;
    printf("输入一个实数:");
    scanf("%f",&x);
    if(x<-1.0)
        y=0;
    else if (x>=-1.0&&x<=1.0) 
        y=-1;
    else 
        y=10;
    printf("y=%d\n",y);
}

注意:程序中第一个“if-else语句”中,else后面的“语句”又是一个“if-else语句”,这种结构称为“嵌套的if-else语句”。

if语句的规则嵌套形式:所谓规则嵌套是指嵌套的位置是规则地固定在else分支下,即在每一层的else分支下嵌套着另一个if-else语句。其嵌套形式如下所示:
if(表达式1)
  语句1;
else if(表达式2)
  语句2;
else if(表达式3)
  语句3;
  ……
else if(表达式(n-1))
  语句(n-1);
else
  语句n;

这种有规则的多层嵌套,又称为if语句的else if结构。最后一个else及其下面的语句也可以不存在。

【例】多层嵌套的if-else语句。输入一个字符,如果是数字则输出1;大写字母则输出2;小写字母则输出3;空格则输出4;回车符号则输出5;其它符号则输出6。
程序清单如下:
main()

    char c;
    scanf("%c",&c);
    if(‘0‘<=c&&c<=‘9‘)
        printf("c=%c   %c\n",c,‘1‘); /*如果是数字,则输出字符1*/
    else if(‘A‘<=c&&c<=‘Z‘)
        printf("c=%c  %c\n",c,‘2‘); /*如果不是数字,而是大写字母,则输出字符2*/
    else if(‘a‘<=c&&c<=‘z‘)
        printf("c=%c  %c\n",c,‘3‘); /*如果不是数字和大写字母,而是字母,则输出字符3*/
    else if(c==‘ ‘)
        printf("c=%c  %c\n",c,‘4‘);   /*如果不是数字和大小写字母,而是空格,则输出字符4*/
    else if(c==‘\n‘)
        printf("c=%c  %c\n",c,‘5‘); /*如果不是数字、大小写字母和空格,而是回车换行符,则输出字符5*/
    else 
        printf("c=%c  %c\n",c,‘6‘);    /*如果不是数字、大小写字母、空格和回车换行符,则输出字符6*/
}
注意:程序中前4个“if-else语句”中,else后面的“语句”都是“if-else语句”,这种结构称为“多层嵌套的if-else语句”。
在设计嵌套的“if语句”和“if-else语句”时,要特别注意else是和前面出现的哪个if配对。请看下面两段程序:

程序段一 if(c>=‘0‘&&c<=‘9‘) 
          if(c==‘5‘) 
            y=0;
     else 
            y=1;
程序段二 if(c>=‘0‘&&c<=‘9‘) 
          if(c==‘5‘) 
            y=0;
          else 
            y=1;

从书写格式上来看,程序段一中else 是和第一个if 配对的;程序段二中else 是和第二个if配对的。由于c程序清单的书写规则并无特定要求,所以两种书写格式都是正确的,但是运行结果不同,这将带来理解上的“二义性”。因此c语言规定,在出现上述情况时,将按照下列原则处理:else总是和最近的if 配对。所以对上述两段程序,是按照程序段二的方式执行的。

如果用户需要设计的运行结果是程序段一的结果,可以采用下列两种方法:
第一种方法是:
if((c>=‘0‘&&c<=‘9‘)&&(c==‘5‘))
  y=0;
else 
  if!(c>=‘0‘&&c<=‘9‘)
    y=1;

第二种方法是用复合语句的方法将不需要配对的if语句用花括号括起来,程序段一可以改成下列程序段:
if(c>=‘0‘&&c<=‘9‘) 
  { 

    if(c==‘5‘)
        y=0;
  }
else
      y=1;
这就确保了else 是和第一个if 配对.

三、多分支选择语句

多分支选择结构通常是有n个操作。分析前面的例子可知,嵌套的双分支语句可以实现多分支结构。
C语言还专门提供了一种实现多分支结构的switch语句。

[格式]switch(表达式)
    { case 常量表达式1:
             语句组1;break;
     case 常量表达式2:
             语句组2;break;
    ┇
     case 常量表达式n: 
             语句组n; break;
     default:语句组n+1;
    }
[功能]计算表达式的值,并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时,即执行其后的语句,直到遇到break语句为止。如表达式的值与所有case后的常量表达式均不相同时,则执行default后的语句。
[说明]
(1) 表达式可以是任何类型的,常用的是字符或整形表达式
(2) 常量表达式是由常量组成的表达式,所有的常量表达式的值必须互不相同。
(3) 语句组是由若干个语句组成的,不需要用大括号括起来,其中的语句可以是任何C语言的可执行语句,当然可以是另一个switch语句(称嵌套switch语句)。
(4) break是C语言的一种语句,其功能是中断正在执行的语句。在switch语句中的作用是:执行某个语句组后,将退出该switch语句。如果省略了break语句,则执行完某个语句组后,将连续执行其后的所有语句组。
(5) 在书写格式上,按上述格式书写,所有的case对齐,每个case后的语句缩格并对齐,以便很容易地看出各个分支的条件依据和应执行的操作。
(6) 允许将相同操作的case及对应的常量表达式连续排列,对应操作的语句组及break只在最后一个case处出现。其语句格式如下;
switch(表达式)
{ case 常量表达式 1:
  case 常量表达式 2:
  case 常量表达式 3: 
       语句组1; break;
   ┇
  case 常量表达式n-1:
  case 常量表达式 n : 
       语句组n; break;
  default:
       语句组n+1;
 } 
其中表达式值等于常量表达式1、2、3时,执行的操作都是语句组1;而表达式值等于常量表达式n-1、n时,执行的操作都是语句组n。

【例】简单的switch语句。输入一个无符号短整数,然后按用户输入的代号,分别以十进制(代号D)、八进制(代号0)、十六进制(代号X)数输出。
程序清单如下:
main()

    unsigned short x;
    char c;
    scanf("%d,%c",&x,&c);          /*输入一个无符号整数和代号*/
    switch(c)                      /*按输入的代号进得判断*/
    { 

        case‘D‘: printf("%dD\n",x);   /*代号为D,则输出对应的十进制数*/
        break;
        case‘O‘:printf("%oO\n",x);   /*代号为O,则输出对应的八进制数*/
        break;
        case‘X‘:printf("%xX\n",x);   /*代号为X,则输出对应的十六进制数*/
        break;
        default: printf("input error!\n"); /*代号错误提示*/
  }
}

【例】嵌套switch语句。将5级分制改成百分制输出,如下:
   5级分制  5+ 5    5- 4+ 4  4- 3   2   1
   100分制  100  90  85  80  75  70  60  <60  <60 
main()

    char c1,c2;
    scanf("%c%c",&c1,&c2);   /*接受2个字符*/
    switch(c1)               /*判断第一个字符*/
   {

         case‘5‘:switch(c2)             /*判断第二个字符*/

        { 

             case‘+‘:/*第二个字符为+,表示得分为:5+*/
             printf("score=100\n");break;
             case‘\n‘:            /*第二个字符为回车符,表示得分为5*/
             printf("score=90\n");break;
             case‘-‘:             /*第二个字符为-,表示得分为:5-*/
             printf("score=85\n");break;
         }break;
       case‘4‘:/*第一个字符为4*/
    switch(c2)
    { 

         case‘+‘:             /*第二个字符为+,表示得分为:4+*/

          printf("score=80\n");break;
          case‘\n‘:            /*第二个字符为回车符,表示得分为4*/
          printf("score=75\n");break;
          case‘-‘:             /*第二个字符为-,表示得分为:4- */
           printf("score=70\n");break;
     }break;
     case‘3‘:              /*第一个字符为3*/
     printf("score=60\n");break;
     case‘2‘:              /*第一个字符为2*/
     case‘1‘:              /*第一个字符为1*/
     default:              /*其它输入则给出错误提示*/
      printf("input error!\n");
  }
  getch();
}

请读者注意,在外层switch(c1)语句的前两个分支:case‘5‘和case‘4‘的内层,switch语句后均有一个break语句,读者可以分析它们的作用。如果去掉这两个break语句,运行程序出现什么变化?(提示:这两个break语句的作用是中断case‘5‘和case‘4‘分支的,没有它们会继续执行后面的分支。)

四、选择结构程序设计例

【例】输入一个带符号的短整数,输出该数的位数。
程序清单如下:
main()
{

     int x1;
     scanf("%d",&x1);
     if(x1<0) 
         x1=-x1;            /*将输入的短整型数取绝对值*/
     if(x1<10)
        printf("是1位数\n");   /*若<10,则是1位数*/
     else if(x1<100)
        printf("是2位数\n");   /*若>100,则是2位数*/
     else if(x1<1000)
        printf("是3位数\n");   /*>=100且<1000,则是3位数*/
     else if(x1<10000)
        printf("是4位数\n");   /*>=1000且<10000,则是4位数*/
     else 
        printf("是5位数\n");   /*>=10000,则是5位数*/
      getchar();
}

【例】输入一个日期(含年、月、日),输出该日期是该年度中的第几天。
(注意闰年及其判断方法:闰年是能被4整除而不能被100整除的年份,或者是能被400整除的年份。闰年的2月份是29天)。
程序清单如下:
main() 

    int y,m,d,dete=0,flag=1;
    printf("input year,month,day:");
    scanf("%d,%d,%d",&y,&m,&d);    /*输入年、月、日存入变量y,m,d*/
    switch(m)                    /*根据月份求出该月之前的天数*/
   { 

        case 1: dete=0;break;
        case 2: dete=31;break;
        case 3: dete=31+28;break;
        case 4: dete=31+28+31;break;
        case 5: dete=31+28+31+30;break;
        case 6: dete=31+28+31+30+31;break;
        case 7: dete=31+28+31+30+31+30;break;
        case 8: dete=31+28+31+30+31+30+31;break;
        case 9: dete=31+28+31+30+31+30+31+31;break;
        case 10:dete=31+28+31+30+31+30+31+31+30;break;
        case 11:dete=31+28+31+30+31+30+31+31+30+31;break;
        case 12:dete=31+28+31+30+31+30+31+31+30+31+30;break;
        default:printf("input error of month!");flag=0;
    }
  if((m>2)&&((y%4==0)&&(y%100!=0)||(y%400==0)))
    dete++;              /*2月以后且为闰年的则多加1天*/
    dete+=d;               /*加上当月的天数*/
  if(flag==1)
    printf("year=%d month=%d dete=%d---no=%d\n",y,m,d,dete);
  getchar();
}

本文出自 “我成IT成长之路” 博客,请务必保留此出处http://jeason.blog.51cto.com/9704473/1594536

c语言中的选择结构