1、第5章 选择结构程序设计,关 系 运 算 逻辑运算 switch语句 if 语 句,5.1问题的引出,上一章讲过的例题“输入三角形的三个边,求三角形的面积并输出”,若要判断三角形的三边a,b,c是否能构成三角形,用顺序结构是无法达到要求的。必须用选择结构来解决这些问题。C语言提供了进行分支判断的if语句和switch语句来完成这种功能。,5.2 关系运算符和关系表达式,关系运算:比较运算,用“关系表达式”进行运算。例、a 3是一个关系表达式,它取两个值:“真“和“假“。,5.2.1 关系运算符及其优先次序,C语言有六种关系运算符:大于 = 大于或等于 =(连续两个=) 优先级相同(低) !=
2、不等于,关系表达式:用关系运算符将两个表达式连接起来的式子 关系表达式的值:真(1,任意非0值也作为真) 假(0) 关系运算符与算术运算符、赋值运算符的优先级关系,高 算术运算符关系运算符赋值运算符 低(优先级关系),例、a=3,b=2,c=1; 1). ca+b 2). ab=c 3). a!=bc 5).d=abc,等效于c(a+b) 表达式的值为0 等效于(ab)=c 表达式的值为1 等效于a!=(bc) 表达式的值为1d的值为0。 f的值为0,5.3 逻辑运算,5.2.1 逻辑运算符及其优先次序 & 逻辑“与”双目运算符 | 逻辑“或”双目运算符 ! 逻辑“非”单目运算符a b a&b
3、 a | b !a0 0 0 0 10 非0 0 1 1 非0 0 0 1 0 非0 非0 1 1 0,!非 高 算术运算符 关系运算符& | 赋值运算符 优先级关系 低,&与运算的求值顺序 a&b 若表达式a的值为0则不论表达式b为何值,整个表达式的值都为0。因此,在计算时先求解表达式a,若a为非0值,再求解表达式b,根据b的值来决定整个表达式的值;若a为0,则不再求解表达式b。 |或运算的求值顺序 a|b 若表达式a的值为非0值则不论表达式b为何值,整个表达式的值都为1。因此,在计算时先求解表达式a,若a为0时,再求解表达式b,根据b的值来决定整个表达式的值;若a为非0值,则不再求解表达式
4、b。,例:设a=3,b=4,x=0,y=0,求值:1、a y 2、a = = b | | x = = y 3、! a | | a b 4、! a k=(m=a+b)&(n=c+d),!非 高 算术运算符 关系运算符& | 赋值运算符 优先级关系 低,值为0 值为1 值为0 值为0,k为0 ,m为0, n为2,例:判别某一年year是闰年,闰年的条件符合下面二者之一: (1)能被4整除,但不能被100整除; (2)能被4整除,又能被400整除。 可以用一个逻辑表达式表示: (year % 4= =0 &year %100 !=0)|year%400= =0 上述表达式为真,则year是闰年;否则
5、为非闰年。,5.4 if语句,if语句:判别条件是否满足,来决定程序的流程(执行两路操作之一)。if语句的三种形式 1、if (表达式) 语句例如:if (xy) printf(“%d“,x);,例5.1 输入两个实数,按代数值由小到大输出这两个数。main() float a,b,t; scanf(“%f,%f“, 运行示例 3.6 ,-3.2 -3.2, 3.6,例5.2 输入三个数,按由小到大输出。 main() float a,b,c,t; scanf(“%f,%f,%f“, 运行:3,7,1 1.00,3.00,7.00,3 7 1,3 7 1,1 7 3,1 3 7,2、if (表
6、达式) 语句1 else 语句2例如:if (xy) printf(“%d“,x);else printf(“%d“,y);,输入任意三个整数num1、num2、num3,求这三个数中的最大值,main( ) int num1,num2,num3,max;printf(“please input three numbers:”);scanf(“%d,%d,%d”, ,3、if (表达式1) 语句1 else if (表达式2)语句2else if (表达式3)语句3else if (表达式m)语句melse 语句n,例如: if (a500) b=4; else if ( a300 ) b=3
7、;else if ( a100 )b=2; else if ( a50 )b=1;else b=0;,5.4.2 if语句的嵌套 :,一般形式:if ( ) if ( ) 语句1else 语句2 else if ( ) 语句3 else 语句4 使用嵌套if语句时,必须特别注意if与else配对。配对原则: 从最内层开始,else总是与它上面最接近的(未曾配对的)if配对。 避免if与else配对错位的最佳办法是加大括号,同时,为了便于阅读,使用适当的缩进,(只有大括号能保证if和else不错位配对,缩进仅便于阅读),内嵌if,内嵌if,例5.3 有一函数如下,编一程序,输入一个x值,输出y值
8、。 程序1: main() int x,y; scanf(“%d“, ,程序2: if (x=0) if (x0) y = 1; else y = 0; else y = -1;,程序3: y = -1; if (x != 0) if (x0) y = 1; else y = 0;,5.4.3 条件运算符,在if语句中,在“表达式”为“真”和“假”时,都只执行一个赋值语句给同一变量赋值, 例、if (ab) max = a; else max = b; 可以用如下条件运算符来处理:max = (ab) ? a : b 条件运算符,称为“三目运算符”(C语言中唯一的一个三目运算符)。条件表达式的
9、一般形式: 表达式1?表达式2:表达式3 条件运算符的优先级仅高于赋值运算符和逗号运算符 并且结合性为自右向左。(不是指运算的顺序),其中,“(ab) ? a : b”是一个条件表达式,若条件(ab)成立,则条件表达式取值a;否则,取值b。,条件表达式的求解过程 先求解表达式1的值 若表达式1的值为真(非0);则求解表达式2的值,将 其作为条件表达式的值。表达式3不计算。若表达式1的值为假(0);则求解表达式3的值,将 其作为条件表达式的值。表达式2不计算。 例:int a=1,b=2,c=3,d=4,m=5,n=6,k;k=ab?(m=cb): (n=bd) 例:int a=1,b=2,c=
10、3,d=4,m=5,n=6,k;k=ac?(m=cb): (n=bd),条件表达式不能取代一般的if 语句,只有在if 语句中内 嵌语句是赋值语句时,且两个分支都对同一个变量赋 值时,才能代替if 语句。 如:if (ab) max=a;else max=b;此时可用 max = ab ? a : b ; 代替前面的if 语句。 其它情况的if 语句不能用条件表达式代替。 条件表达式中,三个子表达式的类型可以互不相同。 若表达式2与表达式3类型不同时,则条件表达式的类 型为二者较高的类型。如:int a=1,b=2; 表达式 ab?24.6 的值为 2.0 。,例5.4 输入一个字符。判别它是
11、否大写字母,如果是,将其转换为小写,否则不转换。然后输出最后得到的字符。 main() char ch; scanf(“%c“, printf(“%c“,ch); ,5.5 switch语句,switch语句直接处理多个分支(当然包括两个分支)。其一般形式: switch(表达式) case 常量表达式1:语句组1case 常量表达式2:语句组2 case 常量表达式n:语句组n default:语句组n+1 ,几点说明: 开关表达式,可以是整型、字符型或其它类型, 若表达式是实型表达式时,switch会自动取整, 舍去小数部分。 case 后的常量表达式,必须是整型、字符型或 枚举类型,不能
12、是实型表达式,在常量表达式 中不允许出现变量。每个case后的常量表达式 的值都必须各不相同,否则出错。 开关表达式的值与某个case后的常量表达式的,值相等时,就执行此case后面的语句。若所 有的case中的常量表达式的值都没有与开关 表达式的值相匹配,则执行default后的语句, 此选项亦可省略。 执行完一个case后的语句后,遇到break语句, 就退出switch语句的执行,若没有break语句, 程序会顺序执行下去,case 常量表达式 仅起 到一个语句标号的作用。break 语句非常重要。 多个case语句可以共用一组语句。,例、根据考试成绩的等级(grade)打印出百分制分数
13、段:,switch (grade) case A:printf(“85100n“);break; case B:printf(“7084n“);break; case C:printf(“6069n“);break; case D:printf(“60n“);break; default: printf(“errorn“); break语句使程序跳出switch结构。,习题5-6:判别学生成绩的等级: 小于60分,E级;小于70分,D级;小于80分,C级;小于90分,B级;小于100分,A级;1.算法:分数/10:6 ,E级7 ,D级8 ,C级9 ,B级10 ,A级,5.6 程序举例,2. 框
14、图:,#include “stdio.h“ main() int score,s; char grade;printf(“请输入学生的成绩:“);scanf(“%dn“,case 5 :case 4 :case 3 :case 2 :case 1 :case 0 :grade=E; break;printf(“成绩是%d,相应的等级是%cn“,score,grade);,例5.6 求方程的解:1.算法:有以下几种可能性: a = 0,不是二次方程。 b2-4ac=0,有两个相等实根。 b2-4ac 0,有两个不等实根。 b2-4ac 0, 有两个共轭复根。 2. N-S流程图:disc= b2
15、-4ac,程序如下:(disc= b2-4ac )#include “math.h” main() float a,b,c,disc,x1,x2,realpart,imagpart; scanf(“%f,%f,%f”, /* disc */,if (fabs(disc) 1E-6) /* disc0 */ x1 = (-b + sqrt(disc)/(2*a); x2 = (-b - sqrt(disc)/(2*a); printf(“has distinct real roots:%8.4f and %8.4fn”,x1,x2); else /* disc 0 */ realpart = -
16、b/(2*a); imagpart = sqrt(-disc)/(2*a); printf(“has complex roots:n”); printf(“%8.4f+%8.4fin”,realpart,imagpart); printf(“%8.4f-%8.4fin”,realpart,imagpart); ,例5.7 运输公司对用户计算运费。距离()越远,每公里运费越低。标准如下: 250 km 没有折扣 250 500 折扣 500 1000 折扣 1000 2000 折扣 2000 3000 10折扣 3000 15折扣 设每公里每吨货物的基本运费为,货物重为,距离为,折扣为,则总运费
17、 的计算公式为:*() ,由键盘输入,试编程计算总运费。,#include “conio.h“ #include “stdio.h“ main() int c,s,d; float p,w,f; clrscr(); printf(“please input p,w,s:“); scanf(“%f%f%d“,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; f=p*w*s*(1-d/1
18、00.0); printf(“freight=%-15.4fn“,f); getch(); ,5.7阅读程序训练,例1、以下程序的运行结果为: main( ) int a,b,c;a=10;b=50;c=30;if(ab)a=b,b=c;c=a;printf(“a=%d,b=%d,c=%d”,a,b,c); 运行结果: a=10,b=50,c=10,2、 main( ) int x=3,y=0,z=0;if(x=y+z) printf(“*”);else printf(“#”); 运行结果: # 3、若执行时从键盘上输入9,则输出结果是: main( ) int n;scanf(“%d“, 运
19、行结果: 9 10,4、 main( ) int a=0;a+=(a=8);prinf(“%dn”,a); 运行结果:16,5、 main( ) int x=1,y=0,a=0,b=0;switch(x)case1:switch(y)case 0:a+;break;case 1:b+;break;case 2:a+,b+;break;printf(“a=%d,b=%dn”,a,b); 运行结果: a=2,b=1,练习,1、若有定义:float w;int a,b;则合法的switch语句是( ) (a)switch(w) case 1.0;printf(“*n”);case 2.0;print
20、f(“* *n”); (b)switch(a)case 1 printf(“*n”);case 2 printf(“*n”); (c)switch(w); case 1:printf(“*n”);default:printf(“n”); case 1+2:printf(“*n”); ,(d)switch(a+b) case 1:printf(“*n”);case 2:printf(“*n”); default:printf(“n”); 选d,2、如下程序的输出结果是( ) #include main() int x=1,a=0,b=0;Switch(x)case 0:b+;case 1:a+;
21、case 2:a+;b+;printf(“a=%d,b=%dn”,a,b); ,(a)a=2,b=1 (b)a=1,b=1 (c)a=1,b=0 (d)a=2,b=2 选(a),3、如下程序的输出结果是( ) #include”stdio.h” main() int a=12,b=5,c=-3; if(ab)if(b0) c=0;else c+; Printf(“%dn”,c); ,(a) 0 (b) 1 (c) -2 (d) -3 选(c),4、若执行以下程序时从键盘上输入9,则输出结果是( ) #include”stdio.h” main() int n; scanf(“%d”,(a)11
22、 (b)10 (c)9 (d)-2 选(b),5、阅读以下程序 #include”stdio.h” main() int x; scanf(“%d”, 程序运行后,如果从键盘上输入5,则输出的结果是( )。 (a)3 (b) 4 (c) 5 (d)6 选(b),6、若k是int型变量,且有下面的程序段,其输出结果是( ) K=-3; if(k=0) printf(“#”); else printf(“ (a)# (b)& (c)#& (d)有语法错误,无输出结果 选(a),7、若要求在if后一对圆括号中表示a不等于0的关系,则能正确表示这一关系的表达式为( ) (a)a0 (b)!a (c)a
23、=0 (d)a 选(d),实验,1、编写程序,输入一位学生的生日,且输入当前日期,并输出该学生的实足年龄。 2、编写程序,输入一个整数,打印它是奇数还是偶数。,思考题,写出下面程序在以下情况的输出结果:a=10,b=5; a=-5,b=-10; a=0,b=-3; a=6,b=7。main( ) int a,b;scanf(“%d,%d“,2. 本程序的作用是判断year是否闰年,如是闰年则输出“leap year”字样,闰年的条件是符合下面二者之一:能被4整除,但不能被100整除;能被400整除。请对程序填空(填入一个运算符)。main( ) int year;scanf(“%d“,第5章小
24、节,一、运算符关系运算符:、=、b) ? a : b;c(a+b) (ab)&(ac)(ab) |(ab),二、语句,1 if语句 1) if (表达式) 语句2) if (表达式) 语句1 else 语句23) if (表达式1) 语句1else if (表达式2) 语句2.else if (表达式m) 语句melse 语句nif语句的嵌套:if ( ) if ( ) 语句1 内嵌if else 语句2 else if ( ) 语句3 内嵌if else 语句4,2 switch语句switch(表达式) case 常量表达式1:语句1 case 常量表达式2:语句2 case 常量表达式n:语句n default:语句n+1 ,作业,编写程序,输入一个整数,打印它是奇数还是偶数。,