选择结构体现了程序的判断能力。具体地说,在程序执行中能依据运行时某些变量的值。确定某些操作是做还是不做,或者确定若干个操作中选择哪个操作来执行。选择结构有三种形式:单分支结构、双分支结构、多分支结构。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
原文地址:http://jeason.blog.51cto.com/9704473/1594536