4.6 选择程序设计
【例4.11】 将任意3个整数a、b、c按从大到小的顺序输出。
分析:
① 如果只有两个整数a、b,可以用一个if语句直接输出结果,例如:
if(a>b)printf("%d,%d ",a,b); else printf("%d,%d ",b,a);
② 对于3个整数,有6种可能:
a > b > c
a > c > b
b > a > c
b > c > a
c > a > b
c > b > a
若直接输出,写出的程序会很“累赘”,例如,
if(a>b && b>c)printf("%d,%d,%d ",a,b,c); if(a>c && c>b)printf("%d,%d,%d ",a,c,b); …… if(c>b && b>a)printf("%d,%d,%d ",c,b,a);
这样写程序不仅“难看”,而且“难懂”,还容易犯错。
③ 可采用交换法先排序,然后再输出结果,方法如下:
● 若a < b,则交换a和b;
● 若a < c,则交换a和c,结果a最大;
● 若b < c,则交换b和c,结果a > b > c;
● 输出a、b、c。
其N-S图如图4.9所示。
图4.9 3个数的排序算法
程序如下:
1 #include<stdio.h> 2 void main() 3 { 4 int a,b,c,t; 5 printf("input 3 numbers:"); 6 scanf("%d,%d,%d",&a,&b,&c); 7 if(a<b) 8 { t=a;a=b;b=t; } 9 if(a<c) 10 { t=a;a=c;c=t; } 11 if(b<c) 12 { t=b;b=c;c=t; } 13 printf("sorted result:%d,%d,%d\n",a,b,c); 14 }
程序第5~6行是数据输入部分;第7~12行是数据处理部分,完成排序;第13行是数据输出部分。这种结构符合结构化程序设计的要求。
【例4.12】 在射击比赛模拟系统中,靶面被分隔为若干同心圆,如图4.10所示。如果与10、9、8、7、6环对应的圆的半径分别为1、2、3、4、5,脱靶计为0环。若以靶心为坐标原点,那么根据中靶点M (x, y) 的坐标,就可以计算出每次击发的成绩。试编程模拟这一计算过程。
分析:要计算M点对应的环数,就要先计算M到靶心的距离r=x2+y2。若r≤1则为10环;若1<r≤2,则为9环;……;以此类推。若r>5,则为0环。
算法N-S图如图4.11所示。
图4.10 例4.12的示意图
图4.11 例4.12的算法
程序如下:
1 #include<stdio.h> 2 #include<math.h> /* 用到了数学库函数sqrt */ 3 void main() 4 { 5 float x,y,r; 6 int score; 7 printf("input x,y:"); 8 scanf("%f,%f",&x,&y); 9 r=sqrt(x*x+y*y); 10 if(r<=1)score=10; 11 else if(r<=2)score=9; 12 else if(r<=3)score=8; 13 else if(r<=4)score=7; 14 else if(r<=5)score=6; 15 else score=0; 16 printf("score:%d\n",score); 17 }
【例4.13】 求一元二次方程ax2+bx+c=0的实根。如果没有实根,则输出提示信息。
分析:根据数学知识,对于一元二次方程,求解的关键是判断disc=b 2-4 ac的值。disc>0时,方程有两个不相等的实根;disc=0时,方程有两个相等的实根;disc<0时,方程没有实根。由此不难画出算法的N-S图,如图4.12所示。
图4.12 一元二次方程的求根算法
程序如下:
1 #include "stdio.h" 2 #include "math.h" 3 void main() 4 { 5 float a,b,c,disc,x1,x2; 6 printf("Please input a、b、c:"); 7 scanf("%f%f%f",&a,&b,&c); /* 输入数据用空白分开 */ 8 if(a==0) 9 printf("The equation is not a quadratic.\n"); 10 else 11 { 12 disc=b*b-4*a*c; 13 if(disc<0) 14 printf("The equation has not real roots.\n"); 15 else if(disc>0) 16 { 17 x1=(-b+sqrt(disc))/(2*a); 18 x2=(-b-sqrt(disc))/(2*a); 19 printf("The equation has distinct real roots:%7.3f and %7.3f\n",x1,x2); 20 } 21 else 22 { 23 x1=-b/2/a; 24 printf("The equation has two equal real roots:%7.3f\n",x1); 25 } 26 } 27 }
以下是分别输入不同参数运行了4次的结果:
① Please input a、b、c:1 5 4 ↙ The equation has distinct real roots: -1.000 and -4.000 ② Please input a、b、c:1 2 1 ↙ The equation has two equal real roots: -1.000 ③ Please input a、b、c:2 3 5 ↙ The equation has not real roots. ④ Please input a、b、c:0 2 5 ↙ The equation is not a quadratic.
通过以上例子,可以看到选择程序设计的特点:从整体上看,程序的执行流程还是自顶向下的;从程序的内部具体来看,程序的执行流程是可以根据所给定的条件是否成立来决定的。
对于选择程序,程序的一次运行只能执行选择结构的某个分支,其他分支则不被执行。因此,在调试程序的时候,应该选择不同的输入数据多次试运行程序,确保每个分支都被调试过,以免遗漏错误。以例4.13为例,程序有4个分支,因此至少选择4组不同类型的数据进行测试,程序最少也要试运行4次。