C程序设计 第4章 选择结构程序设计 主讲教师: 鲁 萍 西安建筑科技大学 理学院
第4章 选择结构程序设计 为什么要用选择结构 ? 实现选择结构的语句 如何表示“判断条件” ? 条件运算符及表达式 选择结构综合举例 if….else… switch 如何表示“判断条件” ? 关系 运算符及表达式 逻辑 运算符及表达式 条件运算符及表达式 选择结构综合举例 小 结 习 题 游 戏
选择结构 条件成立 A事情 if else 条件 B事情 A事情 B事情 如果 b2-4ac≥0 方程有实根 否则 方程没有实根 不成立 条件成立 A事情 如果 b2-4ac≥0 方程有实根 否则 方程没有实根 如果 明天不下雨 出去郊游 如果 考试不及格 参加补考 如果 遇到红灯 停车等待 if else B事情 年龄大于70岁 0元 年龄小于7岁 10元 年龄大于50岁小于70岁 20元 其他 50元 公园门票,如果
选择结构程序设计 A0307例: 求 ax2+bx+c=0 方程的根。设b2-4ac>0 a, b, c 由键盘输入 输入a b c 计算disc= b2-4ac 输入a b c #include<math.h> int main() { float a,b,c,disc,x1,x2,p,q; printf("输入a b c : "); scanf("%lf%lf%lf",&a,&b,&c); disc=b*b-4*a*c; p=-b/(2.0*a); q=sqrt(disc)/(2.0*a); x1=p+q; x2=p-q; printf("x1=%7.2f \nx2=%7.2f\n", x1,x2); return 0; } 计算根 x1 和 x2 输出x1,x2 计算 p 和 q 本例题 复习: (1)算术表达式的C语言表示 (2) math.h (3) 键盘输入,输出 延伸:控制 小数点后位数 引出:输入输出函数及格式 讲解方式: 先在黑板上分析 二元一次方程的求根过程,给出p和q的定义 再演示幻灯片上的算法
4.1 选择结构程序设计 A0401例: 求 ax2+bx+c=0 方程的根。 a, b, c 由键盘输入 输入a b c 计算disc= b2-4ac 输入a b c A0401例: 求 ax2+bx+c=0 方程的根。 a, b, c 由键盘输入 int main() { float a,b,c,disc,x1,x2,p,q; scanf("%lf%lf%lf",&a,&b,&c); disc=b*b-4*a*c; if (disc>=0) { } else printf("无实根\n"); return 0; disc≥0 成立 不成立 p=-b/(2.0*a); q=sqrt(disc)/(2.0*a); x1=p+q; x2=p-q; printf("%f ,%f", x1,x2); 计算 x1, x2 输出x1,x2 计算 p 和 q 输出 "无实根" 本例题 复习: (1)算术表达式的C语言表示 (2) math.h (3) 键盘输入,输出 延伸:控制 小数点后位数 引出:输入输出函数及格式 讲解方式: 先在黑板上分析 二元一次方程的求根过程,给出p和q的定义 再演示幻灯片上的算法
选择结构程序设计 A0402 [例4.3]输入任意三个数a、b、c,按从小到大的顺序排序输出。 分析: a b c 交换a和b 输入:5 2 3 输出:2 3 5 if (a>b) a和b交换 (交换后 a=min{a, b} if (a>c) a和c交换 (交换后 a=min{a, b, c} if (b>c) b和c交换(交换后 b为次大值,c为最大值 交换a和b t=a; a=b; b=t; 如何交换两个数,在黑板上讲
选择结构程序设计 A0402 [例4.3]输入任意三个数a、b、c,按从小到大的顺序排序输出。 int main() 思路: { int a,b,c,t; scanf("%d,%d,%d",&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(" %d,%d,%d\n",a,b,c); return 0; } 思路: if (a>b) a和b交换 if (a>c) a和c交换 if (b>c) b和c交换 如何交换两个数,在黑板上讲 交换a和b t=a; a=b; b=t;
4.2 if 语句 一般格式:if(表达式) 语句体 【说明】 1)执行过程: 当表达式的值为真(非0)时,执行语句体 2)表达式:常量、变量、函数调用、表达式 3)表达式必须加()括起来 4)语句体:一条 或 多条语句(多条语句用{}括起来 5) 一个if语句总体上只算一条语句
if…else…语句 if~else 的执行过程 if(表达式) 语句体1 else 语句体2 【说明】 例如: if (a>b) max=a; else max=b; 表达式的值 语句体1 语句体2 执行if后的语句 真 假
if…else…语句 √ √ 例5.3 程序1: if(x>=0) if(x>0) y=1; else y=0; 程序2: if(x<0) y=-1; else if(x==0) y=0; else y=1; √ √ if语句嵌套时,else子句与 1.在它上面、 2.距它最近、 3. 尚未匹配 的if配对。 程序3: y=-1; if(x!=0) if(x>0) y=1; else y=0; 程序4: y=0; if(x>=0) if(x>0) y=1; else y=-1; x=0时 × x=-5 ×
选择结构程序设计 ticket if (age>=70) ticket=0 ticket=20 age=65 年龄大于70岁 0元 年龄小于7岁 10元 年龄大于50岁小于70岁 20元 其他 50元 所有条件都不成立时的 “其他” 公园门票,如果 if (age>=70) ticket=0 if (age<7) ticket=10 if (50≤age ≤70) ticket=20 else ticket=50 ticket=20 ticket=50 age=65 age=80 age= 5 正确的逻辑关系在黑板上讲清楚 50≤age ≤70不成立时的“其他”
if~else if~语句 年龄大于70岁 0元 年龄小于7岁 10元 年龄大于50岁小于70岁 20元 公园门票,如果 其他 50元 年龄大于70岁 0元 年龄小于7岁 10元 年龄大于50岁小于70岁 20元 其他 50元 公园门票,如果 age≥70 ticket=0 F T age<7 ticket=10 50≤age ≤70 ticket=20 ticket=50 if (age>=70) ticket=0 else if (age<7) ticket=10 else if (50≤age ≤70) ticket=20 else ticket=50 正确的逻辑关系在黑板上讲清楚 所有条件都不成立时的 “其他”
if~else if~语句 int main() { int age, ticket; scanf(“%d”,&age); 年龄大于70岁 0元 年龄小于7岁 10元 年龄大于50岁小于70岁 20元 其他 50元 A0403 公园门票,如果 int main() { int age, ticket; scanf(“%d”,&age); if (age>=70) ticket=0; else if (age<7) ticket=10; else if (50≤age ≤70) ticket=20; else ticket=50; printf(“age=%d, ticket=%d”,age,ticket); return 0; }
if~else if~语句 1.格式 if(表达式1) 语句组1 else if (表达式2) 语句组2 … else if (表达式n) 语句组n else 语句组n+1 表达式1 语句1 F T 表达式2 语句2 表达式3 语句3 语句n+1
if~else if~语句 √ √ 例5.3 程序1: if(x>=0) if(x>0) y=1; else y=0; 程序2: if(x<0) y=-1; else if(x==0) y=0; else y=1; 小 结
输入星期中的某一天,显示对应的英文 main() { int i; printf("Input 1- 7: "); scanf("%d",&i); if (i==1) printf ( "Today is Monday!\n"); else if (i==2) printf ("Today is Tuesday!\n"); else if (i==3) printf ("Today is Wednesday !\n"); else if (i==4) printf( "Today is Thursday!\n"); else if (i==5) printf( "Today is Friday!\n"); else if (i==6) printf( "Today is Saturday!\n"); else printf( "Today is Sunday!\n"); } main() { int i; printf( "Input 1- 7: "); scanf("%d",&i); switch(i){ case 1: printf( "Today is Monday!"); case 2: printf( "Today is Tuesday!"); case 3: printf( "Today is Wednesday !"); case 4: printf( "Today is Thursday!"); case 5: printf( "Today is Friday!"); case 6: printf( "Today is Saturday!"); default: printf( "Today is Sunday!"); }
4.7 switch实现多分支结构 没有分号 1.一般形式 switch (条件表达式) { case 常量表达式1:语句组1; ...... case 常量表达式n:语句组n; default: 语句组n+1; } 2.执行过程 (1)若 条件表达式==常量表达式i 则 执行语句组i 以及语句组i+1…语句组n+1 (2)若 条件表达式 != 任何常量表达式 则 执行default 的语句组n+1 没有分号
A0405输入星期中的某一天,显示对应的英文 break:跳出switch结构 运行结果 Input 1- 7: 4↙ Today is Thursday! Today is Friday! Today is Saturday! Today is Sunday! main(){ int i; printf( "Input 1- 7: "); scanf("%d",&i); switch(i){ case 1: printf( "Today is Monday!"); case 2: printf( "Today is Tuesday!"); case 3: printf( "Today is Wednesday !"); case 4: printf( "Today is Thursday!"); case 5: printf( "Today is Friday!"); case 6: printf( "Today is Saturday!"); default: printf( "Today is Sunday!"); } 空格 break; break:跳出switch结构
switch语句 3.说明 (1)条件表达式:常量表达式,int、char、枚举型 例: case 3+4:/* 正确*/ case x+y: /*错误 设int x=3,y=4;*/ (2)多个case子句,可共用同一语句(组)。 例如: case 10: case 9: printf("grade=A\n"); break; (3)default可以省略; (4)每个case后面的语句有多条语句时可以不加{}括起来。 小 结
4.7 switch实现多分支结构 A0406例:从键盘上输入一个百分制成绩score,输出其等级:score≥90,等级为A; 80≤score<90,等级为B; 70≤score<80,等级为C; 60≤score<70,等级为D; score<60,等级为E。 分析: switch结构, 如何分段? (score/10) -> 0-10
4.7 switch实现多分支结构 void main() { int score; printf("Input a score(0~100): "); scanf("%d", &score); /* 将成绩转化成10种情形 */ switch (score/10) { case 10: case 9: printf("grade=A\n"); break; 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"); } }
switch实现菜单结构 A0407: 演示简单计算器程序,分析实现思路 说明:由键盘输入2个数字,让用户选择加、减、乘、除四个功能,选择一个功能后显示计算结果 分析 : (1)键盘键入2个操作数 (2)显示功能菜单 (3)接收用户的选择(整数) (4)在switch结构中选择分支执行计算 (5)显示计算结果
A0407: 简单计算器程序 void main() { int a,b,fun,result; printf("Input two numbers a and b like 1,2: "); scanf("%d,%d", &a,&b); printf("1 a+b\n 2 a-b\n 3 a*b\n 4 a/b\n "); printf("please choose 1-4: "); scanf("%d",&fun); switch (fun) { case 1: result=a+b; break; case 2: result=a-b; break; case 3: result=a*b; break; case 4: result=a/b; break; default: printf("The score is out of range!\n"); } printf("result=%d\n",result); printf("1 a+b\n "); printf("2 a-b\n "); printf("3 a*b\n "); printf("4 a/b\n "); 小 结
4.3 关系运算符及表达式 1)进行比较运算 2)连接的运算对象:都是双目运算符号。可以 连接整型、实型、字符型、枚举型数据; 关系运算符 含义 例子 结果 优先级 > 大于 4+6>9 T < 小于 8<9 T >= 大于或等于 6>=5 T <= 小于或等于 8<=7 F == 等于 2+3==6 F != 不等于 9+3!=12 F 相同,高 相同,低 1)进行比较运算 2)连接的运算对象:都是双目运算符号。可以 连接整型、实型、字符型、枚举型数据;
关系运算符 3)运算结果 结果为数值型,用0表示假,1表示真(可参与其它运算,如算术运算等) 例:printf("result=%d " , 2>1); 4)优先级别:算术运算> 关系运算>赋值运算 例:int x=2,y=3,z; z=3-1>=x+1<=y+2; 例:int x=1,y=7,z; z=x+(y%4!=0); 5)结合方向:从左到右。 例:f=3>4>5>2>1 result=1 结果:z=1 结果:z=2 结果:f=0
关系运算符 用关系运算符将两个算术表达式或两个字符串表达式联起来的式子,其值为逻辑值。 例 1: 关系运算符 例 2:混合运算 #include<stdio.h> main(){ int a,b; a=10= =5<6; b=(10= =5)<6; printf("%d,%d\n",a,b); } 输出结果: 例 2:混合运算 #include<stdio.h> main(){ int a,b; a=6*7>7+8; b=7!=7>3; printf("%d,%d\n",a,b); } 输出结果: 0,1 1,1
4.4 逻辑运算及表达式 1) && || ! 逻辑与(同时) 逻辑或(或者) 逻辑非(否定) 2)运算规则 1) && || ! 逻辑与(同时) 逻辑或(或者) 逻辑非(否定) 2)运算规则 A && B : A和B都"真",结果"真",否则"假" A || B: A和B都"假",结果"假",否则"真" ! A :A为"真",结果"假";A为"假",结果"真"例:假定x=5, 则 (x<-1) || (x>5) 的值为"假" 6 && 3 结果为"真" 表达式A和B的结果只要是非0数,都认为是"真" "假" :0、0.0、'\0'、NULL
逻辑运算符 3)运算结果为数值型:0表示假,1表示真。 4)结合方向: 从左到右(&&、||); 从右到左(!) 从左到右(&&、||); 从右到左(!) 例: f=!(3>4) 结果为1 5)优先级别: (高) !, &&、|| (低)
优先级图示 1、逻辑运算符的优先级 2、运算符的优先级 ? : ! && || 高 低 ( ) !, ++,--,(类),sizeof *,/ ,% +,- 自右至左 <,<=,>,>= ==,!= 赋值运算符 ? :
逻辑表达式 例:用逻辑表达式表达下述数学式 (1) 0<x<10 (2) x<60 , x>80 用逻辑运算符连接关系表达式的式子称逻辑表达式。 用逻辑运算符连接关系表达式的式子称逻辑表达式。 用逻辑运算符连接关系表达式的式子称逻辑表达式。 例:用逻辑表达式表达下述数学式 (1) 0<x<10 (2) x<60 , x>80 (3) 10≤x ≤ 30, 50 ≤ x ≤ 90 例:用逻辑表达式表达下述数学式 (1) 0<x<10 (2) x<60 , x>80 (3) 10≤x ≤ 30, 50 ≤ x ≤ 90 例:用逻辑表达式表达下述数学式 (1) 0<x<10 (2) x<60 , x>80 (3) 10≤x ≤ 30, 50 ≤ x ≤ 90 相应的逻辑表达: (1) 0<x && x<10 x<60 || x>180 (3) (x>=10 && x<=30) || (x>=50 && x<=90) 相应的逻辑表达: (1) 0<x && x<10 x<60 || x>180 (3) (x>=10 && x<=30) || (x>=50 && x<=90)
逻辑运算的特殊规则 当某个表达式可以决定整个表达式的结果时,其他的表达式则不需要计算 1)a&&b&&c: 依次计算各表达式,若某个表达式值为0,则停止计算。整个表达式为0。 2)a||b||c: 依次计算各表达式,若某个表达式值为1,则停止计算。整个表达式为1。
关系,逻辑运算符练习 混合运算中,看 优先级! 1. 设有x,y,z;x=y=z=0;执行++x||++y&&++z;后,变量z和表达式的值分别为:( ) A)3,0 B)0,1 C)2,0 D)1,1 2. 设有int a=3,b=4,c=5;则表达式!(a>b)&&!c||b的值为( ) A)0 B)2 C)1 D)5 3. 有定义int a=23,b=25,c=12;执行c=c+b= =a;后变量c的结果为:( ) A)23 B)25 C)0 D)1 4、设有int a=10,b=3,c=9;以下表达式运算结果为1的是( ) A) !(a<b&&b<c) B) a>b && b>c C) !a>b || !b>c D) a+b&&(b>c) 混合运算中,看 优先级!
课堂练习:if 语句应用实例 A0404 A0503:用三种if语句编写程序:键盘输入x,输出y (1)简单if语句、 (2)if…else…语句、 (3)if…else if…语句分别实现。
算法一:用if语句实现 main() { float x,y; printf("x=?"); scanf("%f",&x); if(x<1) y=x; if(x<10&&x>=1) y=2*x-1; if(x>=10) y=3*x+11; printf("%.2f",y); }
算法二:用if…else…语句实现 main() { float x,y; printf("x=?"); scanf("%f",&x); if(x<1) y=x; else // x>=1 if (x<10) y=2*x-1; // x>=1 && x<10 else y=3*x+11 ; // x>=10 printf("%.2f",y); }
算法三:用if…else if…语句实现 main(){ float x,y; printf("x=?"); scanf("%f",&x); if(x<1) y=x; else if (x<10) y=2*x-1; /* x>=1 && x<10 */ else y=3*x+11 ; /* x>=10 */ printf("%.2f",y); }
4.5 条件运算符 m=(a>b?a:b); 1.一般格式: 表达式1?表达式2:表达式3 3个表达式的类型可以各不相同。 2.运算规则 表达式1 非0,运算结果等于"表达式2"的值; 为0,运算结果等于"表达式3"的值。 例1: if(a>b) m=a; else m=b; 例2: x?’a’: ‘b’ 含义:x值非0,取‘a’,否则取‘b’ m=(a>b?a:b);
4.5 条件运算符 [例] 从键盘上输入一个字符,如果是大写字母,则转换成小写字母输出;否则,直接输出。 main(){ char ch; printf("Input a character: "); scanf("%c",&ch); ch= (ch>=‘A’&&ch<=‘Z’)? (ch=ch+32) : ch; printf("ch=%c\n",ch); }
4.8 选择结构程序综合举例 printf("%f + %f i", p, q); 输出 数值 数值+数值i A0408 求一元二次方程ax2+bx+c=0的解(a≠0) 分析:disc=b2-4ac=0 x1=x2=-b/(2a) disc=b2-4ac>0 x1=(-b+sqrt(disc))/(2a) x2=(-b-sqrt(disc))/(2a) disc=b2-4ac<0 x1=(-b/(2a))+sqrt(disc))/(2a) i x2=(-b/(2a))-sqrt(disc))/(2a) i #include<math.h> main() { int a,b,c,disc; float x1,x2,p,q; scanf("%d, %d,%d", &a, &b, &c); printf("%f + %f i", p, q);
4.8 选择结构程序设计举例 disc=b*b-4*a*c; if (disc==0) printf("x1=x2=%f\n", -b/(2*a)); else /* disc!=0*/ { if (disc>0) /* disc>0*/ { x1=(-b+sqrt(disc))/(2*a); /*两个不等实根*/ x2=(-b-sqrt(disc))/(2*a); printf("x1=%f, x2=%f\n", x1, x2); } else /* disc<0*/ { p=-b/(2*a); /*两个共轭复根*/ q=sqrt(fabs(disc))/(2*a); printf("x1=%f + %f i\n", p, q); printf("x2=%f - %f i\n", p, q); } } }
4.8 选择结构程序设计举例 A0408求一元二次方程ax2+bx+c=0的解(a≠0)。 分析:disc=b2-4ac=0 x1=x2=-b/(2a) disc=b2-4ac>0 x1=(-b+sqrt(disc))/(2a) x2=(-b-sqrt(disc))/(2a) disc=b2-4ac<0 x1=(-b/(2a))+sqrt(disc))/(2a) i x2=(-b/(2a))-sqrt(disc))/(2a) i 输出 数值 数值+数值i #include<math.h> main() { int a,b,c,disc; float x1,x2,p,q; scanf("%d, %d,%d", &a, &b, &c); float f f f
选择结构程序设计举例 计算机存储实数时有微小误差, 所以判断disc是否为0的方法是: |disc| <10-6 (一个非常小的数) disc=b*b-4*a*c; /*float*/ if (disc==0) printf("x1=x2=%f\n", -b/(2*a)); else /* disc!=0*/ { if (disc>0) /* disc>0*/ { x1=(-b+sqrt(disc))/(2*a); /*两个不等实根*/ x2=(-b-sqrt(disc))/(2*a); printf("x1=%f, x2=%f\n", x1, x2); } else /* disc<0*/ { p=-b/(2*a); /*两个共轭复根*/ q=sqrt(fabs(disc))/(2*a); printf("x1=%f + %f i\n", p, q); printf("x2=%f - %f i\n", p, q); } } } (fabs(disc)<=1e-6) (disc>1e-6)
小结----if语句 if ( 表达式) 语句体1 else 语句体2 if (表达式1) 语句组1 else if (表达式2) 语句组2 条件 A事情 B事情 成立 不成立 if ( 表达式) 语句体1 else 语句体2 表达式1 语句1 F T 表达式2 语句2 表达式3 语句3 语句n+1 if (表达式1) 语句组1 else if (表达式2) 语句组2 else if (表达式3) 语句组3 … else if (表达式n) 语句组n else 语句组n+1
小结—— 关系、逻辑表达式 关系运算符: > < >= <= == != 逻辑运算符: && || ! 关系运算符: > < >= <= == != 逻辑运算符: && || ! 将判断条件转换为关系、逻辑表达式 0<x<10 => 0<x && x<10 英文字符 => (ch>='A' && ch<='Z')|| (ch>='a' && ch<='z') 表达式为"真":表达式的结果只要是非0数 表达式为“假” :表达式的结果是0、0.0、'\0'、NULL
分支结构 习题 B0401:输入三角形的三边长,判断是否能够成三角形,如果不能给出提示信息,如果可以,求三角形面积。 B0402(习题4.12) 有4个圆塔,圆心分别为(2,2)、 (-2,2)、 (-2,-2)、 (2,-2),圆半径为1。4个塔的高度为10m,塔外无建筑(高度为零)。输入任一点的坐标,求该点的建筑高度。 B0403:键盘输入一个字符,如果是英文字符,按顺序输出该字符前一个字符、该字符以及后一个字符(注意边界字符A和Z);如果不是英文字符,给出提示信息 B0404 :输入一个字符, 如果是大写字母,则输出小写及对应的ASCII码值。 如果是小写字母,则输出大写及对应的ASCII值。 如果是其他字符则原样输出该字符及ASCII码值。
游戏扩展 B0405 分支游戏1:随机算式A0502 随机算式游戏: 系统生成0-N之间随机数组成算式,用户输入答案,判断对错 (以时间为种子的随机数) C0401 分支结构小游戏:闯关提问。自定义问题5个(每个题20分),并给定答案。显示问题1,让游戏者输入答案,如果正确则显示问题2,让游戏者输入答案,如果对则显示问题3,…依此类推;如果某个问题回答错误,则退出游戏,并给出游戏分数。 C0402 游戏扩展:对上题中的数字产生0-100的随机数,显示并自行判断。
分支结构 游戏扩展 A0502 随机算式游戏: 系统生成0-N之间随机数组成算式,用户输入答案,判断对错 (以时间为种子的随机数) 分支结构 游戏扩展 A0502 随机算式游戏: 系统生成0-N之间随机数组成算式,用户输入答案,判断对错 (以时间为种子的随机数) #include<stdio.h> #include<stdlib.h> #include<time.h> #define N 100 void main() { int a,b,c,ans; srand(time(0)); /*设置种子, 生成伪随机序列*/ a=rand()%N; /*n为0~N之间的随机数*/ b=rand()%N; c=a+b; printf("%d+%d=",a,b); scanf("%d",&ans); if(ans==c) printf("right!\n"); else { printf("wrong!\n"); printf("%d+%d=%d",a,b,c); } system("PAUSE"); 任务驱动:演示程序结果,启发思考知识点
If语句练习 c1=getchar(); #include<stdlib.h> #include <stdio.h> A0405 A0504例:A0504扩展,输入一个字符,若是大写字母,则输出小写及对应的ASCII码值;若是小写字母,则输出大写及对应的ASCII值;否则原样输出该字符及ASCII码值。 #include<stdlib.h> #include <stdio.h> void main() { char c1,c2; printf("Input a char: "); c1=getchar(); printf("%c %d\n",c1,c1); if (c1>='A' && c1<='Z') { c2=c1+32; printf("%c %d\n",c2,c2); } else if(c1>='a' && c1<='z') { c2=c1-32; printf("%c %d\n",c2,c2); } system("PAUSE"); } If语句练习 多个语句要加{ } 暂停系统的方法