C程序设计
南京师范大学
地图学与地理信息系统 04级
专业选修课
主讲教师, 汪闽
4.2 if 语句
4.3 switch 语句
4.1 选择结构简介
4.4 选择结构程序示例
第四章 选择结构设计
P
A B
真 假 P
BA
真 假
k
A1 A2 Ai An
k=k2k=k1
k=kn
k=ki
...,..
?二分支选择结构
?多分支选择结构
4.1 选择结构简介
形式一:
格式,if (expression)
statement
执行过程:
expr
statement
非 0
=0
例,if (x>y)
printf(“%d”,x);
expr
statement1 statement2
非 0 =0?形式二,
?格式, if (expression)
statement1
else
statement2
?执行过程,例,if (x>y) max=x;
else max=y;
4.2 if 语句
形式三,
if ( expr1 ) statement1
else if (expr2 ) statement2
else if (expr3 ) statement3
…...
[ else statementn ]
expr1
statemnt1
非 0
=0
expr2
expr3
statemntnstatemnt3statemnt2
非 0
非 0
=0
=0
?执行过程:
例,if (salary>1000) index=0.4;
else if (salary>800) index=0.3;
else if (salary>600) index=0.2;
else if (salary>400) index=0.1;
else index=0;
如,if(a==b&&x==y) printf(“a=b,x=y”);
if(3) printf(“OK”);
if(?a?) printf(“%d”,?a?);
if(x) ? if(x!=0)
if(!x) ? if(x==0)
?if后面的表达式类型任意,必须用 ()
?语句可以是复合语句
?else子句(可选)是 if语句的
一部分,必须与 if配对使用,
不能单独使用 。
?当 if和 else下面的语句组,仅
由一条语句构成时,也可不使
用复合语句形式(即去掉花括
号)。
例 考虑下面程序的输出结果,
#include <stdio.h>
main()
{ int x,y;
scanf(“%d,%d”,&x,&y);
if(x>y)
x=y; y=x;
else
x++; y++;
printf(“%d,%d\n”,x,y);
}
Compile Error!
?对 If语句的说明
一般形式:
if (expr1)
if (expr2) statement1
else statement2
else
if(expr3) statement3
else statement4
内嵌 if
内嵌 if
if (expr1)
if (expr2)
statement1
else
statement2
内嵌 if
if (expr1)
if (expr2)
statement1
else
statement3
内嵌 if
if (expr1)
statement1
else
if(expr3)
statement3
else
statement4
内嵌 if
?if语句嵌套 ? 续 If语句说明
/*ch4_4.c*/
#include <stdio.h>
main()
{ int x,y;
printf("Enter integer x,y:");
scanf("%d,%d",&x,&y);
if(x!=y)
if(x>y) printf("X>Y\n");
else printf("X<Y\n");
else
printf("X==Y\n");
}
运行,Enter integer x,y:12,23?
X<Y
Enter integer x,y:12,6?
X>Y
Enter integer x,y:12,12?
X==Y
例 输入两数并判断其大小关系
? 续 If语句的说明
– 缺省 { }时,else总是和它上面离它最近的未配
对的 if配对
if(……)
if(……)
if(……)
else…...else…...
else…...
?if ~ else 配对原则
? 续 If语句的说明
例,if (a==b)
if(b==c)
printf(“a==b==c”);
else
printf(“a!=b”);
修改,if (a==b)
{ if(b==c)
printf(“a==b==c”);
}
else
printf(“a!=b”);
实现 if ~ else 正确配对方法:加 { }
? 续 If语句的说明
?一般形式 switch( 表达式 )
{ case E1:
语句组 1;
break;
case E2:
语句组 2;
break;
…….
case En:
语句组 n;
break;
[default:
语句组 ;
break}
?执行过程
switch
表达式
语句组 1 语句组 2 语句组 n 语句组…...
E 1 E 2 En default
case
4.3 switch语句(开关分支语句)
( 1)当 switch后面, 表达式, 的值,与某个 case后面的, 常量表
达式, 的值相同时,就执行该 case后面的语句(组);当执行到
break语句时,跳出 switch语句,转向执行 switch语句的下一条。
( 2) 如果没有任何一个 case后面的, 常量表达式, 的值, 与, 表
达式, 的值匹配, 则执行 default 后面的语句 ( 组 ) 。 然后, 再执
行 switch语句的下一条 。
? 说明
( 1) switch后面的, 表达式,, 可以是 int,char和枚举型中
的一种 。
( 2) 每个 case后面, 常量表达式, 的值, 必须各不相同,
否则会出现相互矛盾的现象 ( 即对表达式的同一值, 有两种或
两种以上的执行方案 ) 。
( 3) case后面的常量表达式仅起语句标号作用, 并不进行
条件判断 。 系统一旦找到入口标号, 就从此标号开始执行, 不
再进行标号判断, 所以必须加上 break语句, 以便结束 switch语句 。
? 续执行过程
(4)case后可包含多个可执行语句,且不必加 { }
(5)switch可嵌套
(6)多个 case可共用一组执行语句
如,……
case ?A?:
case ?B?:
case ?C?,
printf(“score>60\n”);
break;
……..
? 续说明
例 switch(score)
{ case 5,printf(“Very good!”);
case 4,printf(“Good!”);
case 3,printf(“Pass!”);
case 2,printf(“Fail!”);
default, printf(“data error!”);
}
运行结果,score为 5时,输出:
Very good! Good! Pass! Fail! data error!
?switch 示例( 1)
/*ch4_5.c*/
#include <stdio.h>
main()
{ int c;
printf("Enter m or n or h or other:");
c=getchar();
switch(c)
{ case 'm',printf("\nGood morning!\n");break;
case 'n',printf("\nGood night!\n"); break;
case 'h',printf("\nHello!\n"); break;
default, printf("\n\n"); break;
}
}
根据输入字母输出字符串?switch 示例( 2),
从键盘上输入一个百分制成绩 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,转化成 switch语句中的 case
标号 */
switch (grade)
{case 10:
case 9,printf(“grade=A\n”); break;
?Switch 示例( 3),
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”);
}
}
[程序演示 ]
程序运行情况如下:
Input a score(0~100),85↙
grade=B
4.4 选择结构程序设计举例
[案例 1] 求一元二次方程 ax2+bx+c=0的解( a≠0)。
/*案例代码文件名,AL4_6.C。 */
/*功能:求一元二次方程的解。 */
#include "math.h"
main()
{float a,b,c,disc,x1,x2,p,q;
scanf(“%f,%f,%f”,&a,&b,&c);
disc=b*b-4*a*c;
if (fabs(disc)<=1e-6) /*fabs():求绝对值库函数 */
printf(“x1=x2=%7.2f\n”,-b/(2*a)); /*输出两个相等的实根 */
else
{ if (disc>1e-6)
{x1=(-b+sqrt(disc))/(2*a); /*求出两个不相等的实根 */
x2=(-b-sqrt(disc))/(2*a);
printf("x1=%7.2f,x2=%7.2f\n",x1,x2);
}
else
{p=-b/(2*a); /*求出两个共轭复根 */
q=sqrt(fabs(disc))/(2*a);
printf(“x1=%7.2f + %7.2f i\n“,p,q); /*输出两个共轭复根 */
printf(”x2=%7.2f - %7.2f i\n“,p,q);
}
}
} [程序演示 ]
说明,由于实数在计算机中存储时,经常会有一些
微小误差,所以本案例判断 disc是否为 0的方法是:判断
disc的绝对值是否小于一个很小的数(例如 10-6)。
[案例 2] 已知某公司员工的保底薪水为 500,某月所接工程的利润
profit( 整数 ) 与利润提成的关系如下 ( 计量单位:元 ),
profit≤1000 没有提成;
1000< profit≤2000 提成 10%;
2000< profit≤5000 提成 15%;
5000< profit≤10000 提成 20%;
10000< profit 提成 25%。
算法设计要点:
为使用 switch语句, 必须将利润 profit与提成的关系, 转换成某些
整数与提成的关系 。 分析本题可知, 提成的变化点都是 1000的整数倍
( 1000,2000,5000,…… ), 如果将利润 profit整除 1000,则当:
profit≤1000 对应 0,1
1000< profit≤2000 对应 1,2
2000< profit≤5000 对应 2,3,4,5
5000< profit≤10000 对应 5,6,7,8,9,10
10000< profit 对应 10,11,12,……
为解决相邻两个区间的重叠问题, 最简单的方法就是:利润
profit先减 1( 最小增量 ), 然后再整除 1000即可:
profit≤1000 对应 0
1000< profit≤2000 对应 1
2000< profit≤5000 对应 2,3,4
5000< profit≤10000 对应 5,6,7,8,9
10000< profit 对应 10,11,12,……
/*案例代码文件名,AL4_7.C。 */
main()
{long profit;
int grade;
float salary=500;
printf("Input profit,");
scanf("%ld",&profit);
grade= (profit – 1) / 1000; /*将利润 -1,再整除 1000,转化成
switch语句中的 case标号 */
switch(grade)
{ case 0,break; /*profit≤1000 */
case 1,salary += profit*0.1; break; /*1000< profit≤2000 */
case 2:
case 3:
case 4,salary += profit*0.15; break; /*2000< profit≤5000 */
case 5:
case 6:
case 7:
case 8:
case 9,salary += profit*0.2; break; /*5000< profit≤10000 */
default,salary += profit*0.25; /*10000< profit */
}
printf("salary=%.2f\n",salary);
}