第4章 选择结构程序设计4.1 选择结构和条件判断4.2 用if语句实现选择结构4.3 选择结构的嵌套4.4 用switch语句实现多分支选择结构4.5选择结构程序综合举例4.1 选择结构和条件判断•在现实生活中,需要进行判断和选择的情况是很多的–如果你在家,我去拜访你–如果考试不及格,要补考–如果遇到红灯,要停车等待–周末我们去郊游–70岁以上的老年人,入公园免票4.1 选择结构和条件判断•在现实生活中,需要进行判断和选择的情况是很多的•处理这些问题,关键在于进行条件判断•由于程序处理问题的需要,在大多数程序中都会包含选择结构,需要在进行下一个操作之前先进行条件判断4.1 选择结构和条件判断•C语言有两种选择语句:(1)if语句,实现两个分支的选择结构(2)switch语句,实现多分支的选择结构4.1 选择结构和条件判断 例4.1 在例3.5的基础上对程序进行改进题目要求是求 方程的根 由键盘输入a,b,c假设a,b,c的值任意,并不保证 需要在程序中进行判别,如果 ,就计算并输出方程的两个实根,否则就输出“方程无实根”的信息。
计算计算 •解题思路:输入输入a,b,c?b2-4ac <0计算计算x1,x2输出无实根输出无实根输出输出x1,x2真真假假b2-4ac结束结束开始开始#include #include int main ( ) { double a,b,c,disc,x1,x2,p,q; scanf("%lf%lf%lf",&a,&b,&c); disc=b*b-4*a*c;计算计算b2-4ac,,disc的值变为的值变为-15 if (disc<0) printf(“has not real roots\n”); else { p=-b/(2.0*a); q=sqrt(disc)/(2.0*a); x1=p+q; x2=p-q; printf(“real roots:\nx1=%7.2f\n x2=%7.2f\n”,x1,x2); } return 0;}-15<0为真为真#include #include int main ( ) { double a,b,c,disc,x1,x2,p,q; scanf("%lf%lf%lf",&a,&b,&c); disc=b*b-4*a*c;计算计算b2-4ac,,disc的值变为的值变为8 if (disc<0) printf(“has not real roots\n”); else { p=-b/(2.0*a); q=sqrt(disc)/(2.0*a); x1=p+q; x2=p-q; printf(“real roots:\nx1=%7.2f\n x2=%7.2f\n”,x1,x2); } return 0;}8<0为假为假p的值变为的值变为-1q的值变为的值变为0.71x1的值变为的值变为-0.29x2的值变为的值变为-1.71 if (disc<0) printf(“has not real roots\n”); else { p=-b/(2.0*a); q=sqrt(disc)/(2.0*a); x1=p+q; x2=p-q; printf(“real roots:\nx1=%7.2f\n x2=%7.2f\n”,x1,x2); } return 0;}选择结构选择结构,,用用if语句实现语句实现的的 if (disc<0) printf(“has not real roots\n”); else { p=-b/(2.0*a); q=sqrt(disc)/(2.0*a); x1=p+q; x2=p-q; printf(“real roots:\nx1=%7.2f\n x2=%7.2f\n”,x1,x2); } return 0;}复合语句复合语句4.2 用if语句实现选择结构4.2.1 用if语句处理选择结构举例4.2.2 if语句的一般形式4.2.1 用if语句处理选择结构举例 例4.2 输入两个实数,按代数值由小到大的顺序输出这两个数。
•解题思路:–只需要做一次比较,然后进行一次交换即可–用if语句实现条件判断–关键是怎样实现两个变量值的互换★●AB互换前互换前●★AB互换后互换后4.2.1 用if语句处理选择结构举例★●ABC★4.2.1 用if语句处理选择结构举例★●ABC★●4.2.1 用if语句处理选择结构举例ABC★● ★4.2.1 用if语句处理选择结构举例●#include int main(){ float a,b,t; scanf("%f,%f",&a,&b); if(a>b) { t=a; a=b; b=t; } printf("%5.2f,%5.2f\n",a,b); return 0;}将将a和和b的值互换的值互换如果如果a>b#include int main(){ float a,b,t; scanf("%f,%f",&a,&b); if(a>b) { t=a; a=b; b=t; } printf("%5.2f,%5.2f\n",a,b); return 0;}选择结构,用选择结构,用if语句实现的语句实现的 例4.3 输入3个数a,b,c,要求按由小到大的顺序输出。
•解题思路:可以先用伪代码写出算法:–if a>b,a和b对换 (a是a、b中的小者)–if a>c,a和c对换 (a是三者中最小者)–if b>c,b和c对换 (b是三者中次小者)–顺序输出a,b,c#include int main(){ float a,b,c,t; scanf("%f,%f,%f",&a,&b,&c); if(a>b) { t=a; a=b; b=t; } if(a>c) { t=a; a=c; c=t; } if(b>c) { t=b; b=c; c=t; } printf("%5.2f,%5.2f,%5.2f\n",a,b,c); return 0;}如果如果 a>b,将,将a和和b对换对换a是是a、、b中的小者中的小者#include int main(){ float a,b,c,t; scanf("%f,%f,%f",&a,&b,&c); if(a>b) { t=a; a=b; b=t; } if(a>c) { t=a; a=c; c=t; } if(b>c) { t=b; b=c; c=t; } printf("%5.2f,%5.2f,%5.2f\n",a,b,c); return 0;}如果如果 a>c,将,将a和和c对换对换a是是三者三者中的小者中的小者#include int main(){ float a,b,c,t; scanf("%f,%f,%f",&a,&b,&c); if(a>b) { t=a; a=b; b=t; } if(a>c) { t=a; a=c; c=t; } if(b>c) { t=b; b=c; c=t; } printf("%5.2f,%5.2f,%5.2f\n",a,b,c); return 0;}如果如果 b>c,将,将b和和c对换对换b是是三者三者中的中的次次小者小者4.2.2 if语句的一般形式 if (表达式) 语句1 [ else 语句2 ]关系表达式关系表达式逻辑表达式逻辑表达式数值表达式数值表达式方括号内的部分为可选的方括号内的部分为可选的4.2.2 if语句的一般形式 if (表达式) 语句1 [ else 语句2 ]简单的语句简单的语句复合语句复合语句另一个另一个if语句语句等等最常用的3种if语句形式:1. if (表达式) 语句1 (没有else子句)2. if (表达式) 语句1 else 语句2 (有else子句)3. if(表达式1) 语句1 else if(表达式2) 语句2 else if(表达式3) 语句3 ┆ else if(表达式m) 语句m else 语句m+1 (在else部分又嵌套了多层的if语句)if(number > 500) cost = 0.15;else if (number > 300) cost = 0.10;else if (number > 100) cost = 0.075;else if (number > 50) cost = 0.05;else cost=0;if (number > 500) cost = 0.15;else if (number > 300) cost = 0.10; else if (number > 100) cost = 0.075; else if (number > 50) cost = 0.05; else cost = 0;等价于等价于分号不能丢分号不能丢•说明:(1)整个if语句可写在多行上,也可写在一行上 但都是一个整体,属于同一个语句(2)“语句1”…“语句m”是if中的内嵌语句 内嵌语句也可以是一个if语句(3)“语句1”…“语句m”可以是简单的语句,也可以是复合语句4.3 选择结构的嵌套•在if语句中又包含一个或多个if语句称为if语句的嵌套•一般形式:if( ) if( ) 语句1 else 语句2 else if( ) 语句3 else 语句4 内嵌内嵌ifelse总是与它上面最总是与它上面最近的未配对的近的未配对的if配对配对4.3 选择结构的嵌套•在if语句中又包含一个或多个if语句称为if语句的嵌套if (){ if () 语句1 } else语句2内嵌内嵌if{ }限定了内嵌限定了内嵌if范围范围4.3 选择结构的嵌套 例4.5有一函数: 编一程序,输入一个x值,要求输出相应的y值。
4.3 选择结构的嵌套•解题思路:–用if语句检查x的值,根据x的值决定赋予y的值–由于y的可能值不是两个而是三个,因此不可能只用一个简单的(无内嵌if)的if语句来实现4.3 选择结构的嵌套•解题思路:方法1(1) 先后用3个独立的if语句处理:输入x若 x < 0, 则y =-1若 x = 0, 则y = 0若 x > 0, 则y = 1输出x和yscanf("%d",&x);if(x<0) y = -1;if(x==0) y = 0;if(x>0) y = 1;printf("x=%d,y=%d\n",x,y);4.3 选择结构的嵌套•解题思路:方法2(2) 用一个嵌套的if语句处理:输入x若x < 0, 则y = -1 否则 若 x = 0, 则y = 0 否则 y = 1输出x和yscanf("%d",&x);if(x<0) y=-1;else if(x==0) y=0; else y=1;printf("x=%d,y=%d\n",x,y);•解题思路:方法2(2) 用一个嵌套的if语句处理:输入x若x < 0, 则y = -1 否则 若 x = 0, 则y = 0 否则 y = 1输出x和yscanf("%d",&x);if(x<0) y=-1;else if(x==0) y=0; else y=1;printf("x=%d,y=%d\n",x,y);scanf("%d",&x);if (x>=0) if (x>0) y=1; else y=0;else y=-1;printf("x=%d,y=%d\n",x,y);提倡提倡内嵌内嵌if放在放在else中中4.4 用switch语句实现多分支选择结构•switch语句用来实现多分支选择结构–学生成绩分类85分以上为’A’等70~84分为’B’等60~69分为’C’等……–人口统计分类 按年龄分为老、中、青、少、儿童4.4 用switch语句实现多分支选择结构 例4.6 要求按照考试成绩的等级输出百分制分数段,A等为85分以上,B等为70~84分,C等为60~69分 ,D等为 60分以下 。
成绩的等级由键盘输入4.4 用switch语句实现多分支选择结构•解题思路:–判断出这是一个多分支选择问题–根据百分制分数将学生成绩分为4个等级–如果用if语句,至少要用3层嵌套的if,进行3次检查判断–用switch语句进行一次检查即可得到结果#include int main(){ char grade; scanf("%c",&grade); printf("Your score:"); switch(grade) { case 'A': printf("85~100\n");break; case 'B': printf("70~84\n");break; case 'C': printf("60~69\n");break; case 'D': printf("<60\n");break; default: printf("enter data error!\n"); } return 0; }值为值为A#include int main(){ char grade; scanf("%c",&grade); printf("Your score:"); switch(grade) { case 'A': printf("85~100\n");break; case 'B': printf("70~84\n");break; case 'C': printf("60~69\n");break; case 'D': printf("<60\n");break; default: printf("enter data error!\n"); } return 0; }不能少不能少#include int main(){ char grade; scanf("%c",&grade); printf("Your score:"); switch(grade) { case 'A': printf("85~100\n");break; case 'B': printf("70~84\n");break; case 'C': printf("60~69\n");break; case 'D': printf("<60\n");break; default: printf("enter data error!\n"); } return 0; }值为值为C#include int main(){ char grade; scanf("%c",&grade); printf("Your score:"); switch(grade) { case 'A': printf("85~100\n");break; case 'B': printf("70~84\n");break; case 'C': printf("60~69\n");break; case 'D': printf("<60\n");break; default: printf("enter data error!\n"); } return 0; }值为值为F#include int main(){ char grade; scanf("%c",&grade); printf("Your score:"); switch(grade) { case 'A': printf("85~100\n");break; case 'B': printf("70~84\n");break; case 'C': printf("60~69\n");break; case 'D': printf("<60\n");break; default: printf("enter data error!\n"); } return 0; }此行位置有问题,此行位置有问题,应如何修改?应如何修改?•switch语句的作用是根据表达式的值,使流程跳转到不同的语句•switch语句的一般形式:switch(表达式){ case 常量1 :语句1 case 常量2 :语句2 ┇ ┇ ┇ case 常量n :语句n default : 语句n+1}整数类型整数类型(包括字符型包括字符型)•switch语句的作用是根据表达式的值,使流程跳转到不同的语句•switch语句的一般形式:switch(表达式){ case 常量1 :语句1 case 常量2 :语句2 ┇ ┇ ┇ case 常量n :语句n default : 语句n+1}不能相同不能相同 scanf("%c",&grade); printf("Your score:"); switch(grade) { case 'A': printf("85~100\n");break; case 'B': printf("70~84\n");break; case 'C': printf("60~69\n");break; case 'D': printf("<60\n");break; default: printf("enter data error!\n"); } scanf("%c",&grade); printf("Your score:"); switch(grade) { case 'A': printf("85~100\n");break; case 'B': printf("70~84\n");break; case 'C': printf("60~69\n");break; case 'D': printf("<60\n");break; default: printf("enter data error!\n"); } scanf("%c",&grade); printf("Your score:"); switch(grade) { case 'A‘: case 'B‘: case 'C': printf("60~69\n");break; case 'D': printf("<60\n");break; default: printf("enter data error!\n"); } 例4.7 编写程序,用switch语句处理菜单命令。
•解题思路:在许多应用程序中,用菜单对流程进行控制,例如从键盘输入一个’A’或’a’字符,就会执行A操作,输入一个’B’或’b’字符,就会执行B操作,等等#include int main(){ void action1(int,int),action2(int,int); char ch; int a=15,b=23; ch=getchar(); switch(ch) { case 'a': case ‘A’: action1(a,b);break; case 'b': case ‘B’: action2(a,b);break; default: putchar(‘\a’); } return 0;}输入输入a或或A调用调用action1函数,执行函数,执行A操作操作void action1(int x,int y) { printf("x+y=%d\n",x+y);}#include int main(){ void action1(int,int),action2(int,int); char ch; int a=15,b=23; ch=getchar(); switch(ch) { case 'a': case ‘A’: action1(a,b);break; case 'b': case ‘B’: action2(a,b);break; default: putchar(‘\a’); } return 0;}输入输入b或或B调用调用action2函数,执行函数,执行B操作操作void action2(int x,int y){ printf("x*y=%d\n",x*y);}#include int main(){ void action1(int,int),action2(int,int); char ch; int a=15,b=23; ch=getchar(); switch(ch) { case 'a': case ‘A’: action1(a,b);break; case 'b': case ‘B’: action2(a,b);break; default: putchar(‘\a’); } return 0;}输入其他字符输入其他字符发出警告发出警告•这是一个非常简单的示意程序•实际应用中,所指定的操作可能比较复杂: –A:输入全班学生各门课的成绩–B:计算并输出每个学生各门课的平均成绩–C:计算并输出各门课的全班平均成绩–D:对全班学生的平均成绩由高到低排序并输出•可以按以上思路编写程序,把各action函数设计成不同的功能以实现各要求4.8选择结构程序综合举例例4.8 写一程序,判断某一年是否闰年。
•解题思路:在前面已介绍过判别闰年的方法•本例用不同的方法编写程序4.5选择结构程序综合举例•用变量leap代表是否闰年的信息若闰年,令leap=1;非闰年,leap=0最后判断leap是否为1(真),若是,则输出“闰年”信息•参见教材图4.13#include int main(){int year,leap; printf("enter year:"); scanf("%d",&year); if (year%4==0) if(year%100==0) if(year%400==0) leap=1; else leap=0; else leap=1; else leap=0; if (leap) printf("%d is ",year); else printf("%d is not ",year); printf("a leap year.\n"); return 0;}标志变量标志变量与与if (leap!=0)含义相同含义相同#include int main(){int year,leap; printf("enter year:"); scanf("%d",&year); if (year%4==0) if(year%100==0) if(year%400==0) leap=1; else leap=0; else leap=1; else leap=0; if (leap) printf("%d is ",year); else printf("%d is not ",year); printf("a leap year.\n"); return 0;}采取锯齿形式采取锯齿形式#include int main(){int year,leap; printf("enter year:"); scanf("%d",&year); if (year%4==0) if(year%100==0) if(year%400==0) leap=1; else leap=0; else leap=1; else leap=0; if (leap) printf("%d is ",year); else printf("%d is not ",year); printf("a leap year.\n"); return 0;}if(year%4!=0) leap=0;else if (year%100!=0) leap=1;else if(year%400!=0) leap=0;else leap=1;#include int main(){int year,leap; printf("enter year:"); scanf("%d",&year); if (year%4==0) if(year%100==0) if(year%400==0) leap=1; else leap=0; else leap=1; else leap=0; if (leap) printf("%d is ",year); else printf("%d is not ",year); printf("a leap year.\n"); return 0;}if((year%4==0 && year%100!=0) || (year%400==0)) leap=1;else leap=0; 例4.9 求 方程的解。
Ø解题思路:解题思路:处理以下各情况处理以下各情况①① a=0,不是二次方程a=0,不是二次方程②② ,有两个相等实根,有两个相等实根 ③③ ,有两个不等实根有两个不等实根 ④④ ,有两个共轭复根有两个共轭复根 应当以应当以p+qi和和p-qi的形式输出复根的形式输出复根 其中,其中,p=-b/2a,,q=( )/2aØ参见教材参见教材图图4.14#include #include int main(){ double a,b,c,disc,x1,x2,realpart, imagpart; scanf("%lf,%lf,%lf",&a,&b,&c); printf("The equation "); if(fabs(a)<=1e-6) printf("is not a quadratic\n");实型不能用实型不能用if (a==0) else {disc=b*b-4*a*c; if(fabs(disc)<=1e-6) printf("has two equal roots:%8.4f\n", -b/(2*a)); else先算先算disc,以减少重复计算,以减少重复计算不能用不能用if (disc==0) if(disc>1e-6) {x1=(-b+sqrt(disc))/(2*a); x2=(-b-sqrt(disc))/(2*a); printf("has distinct real roots:%8.4f and %8.4f\n",x1,x2); } else { realpart=-b/(2*a); imagpart=sqrt(-disc)/(2*a); printf(" has complex roots:\n"); printf("%8.4f+%8.4fi\n“ ,realpart,imagpart); printf("%8.4f-%8.4fi\n", realpart,imagpart); } } return 0;} { realpart=-b/(2*a); imagpart=sqrt(-disc)/(2*a); printf(" has complex roots:\n"); printf("%8.4f+%8.4fi\n“ ,realpart,imagpart); printf("%8.4f-%8.4fi\n", realpart,imagpart); } } return 0;} { realpart=-b/(2*a); imagpart=sqrt(-disc)/(2*a); printf(" has complex roots:\n"); printf("%8.4f+%8.4fi\n“ ,realpart,imagpart); printf("%8.4f-%8.4fi\n", realpart,imagpart); } } return 0;} 例4.10 运输公司对用户计算运输费用。
路程(s km)越远,每吨·千米运费越低•标准如下: s < 250 没有折扣 250≤s < 500 2%折扣 500≤s < 1000 5%折扣 1000≤s < 2000 8%折扣 2000≤s < 3000 10%折扣 3000≤s 15%折扣•解题思路:–设每吨每千米货物的基本运费为p,货物重为w,距离为s,折扣为d–总运费f的计算公式为f=p×w×s×(1-d)•折扣的变化规律(参见教材图4.15):–折扣的“变化点”都是250的倍数–在横轴上加一种坐标c,c的值为s/250–c代表250的倍数–当c<1时,表示s<250,无折扣–1≤c<2时,表示250≤s<500,折扣d=2%–2≤c<4时,d=5%;4≤c<8时,d=8%; 8≤c<12时,d=10%;c≥12时,d=15%#include int main(){ int c,s; float p,w,d,f; printf("please enter price,weight,discount:"); scanf("%f,%f,%d",&p,&w,&s); if(s>=3000) c=12; else c=s/250; 输入单价、重量、距离输入单价、重量、距离 switch(c) { case 0: d=0; break; case 1: d=2; break; case 2: case 3: d=5; break; case 4: case 5: case 6: case 7: d=8; break; case 8: case 9: case 10: case 11: d=10; break; case 12: d=15; break; } f = p * w * s * (1 - d / 100); printf(“freight=%10.2f\n”,f); return 0;}。