1、第4章 选择结构程序设计v 关系运算符和关系表达式关系运算符和关系表达式v 逻辑运算符和逻辑表达式逻辑运算符和逻辑表达式v ifif语句语句v switchswitch语句语句v 程序举例程序举例解决选择结构的问题需要对条件进行逻辑判断。解决选择结构的问题需要对条件进行逻辑判断。C 语言提供了关系表达式和逻辑表达式,可以得到语言提供了关系表达式和逻辑表达式,可以得到逻逻辑判断结果辑判断结果。C 语言提供了语言提供了选择语句选择语句,来根据,来根据逻辑判断结果逻辑判断结果决定执决定执行程序的哪一个流程(分支)。行程序的哪一个流程(分支)。问题:问题:如何进行逻辑判断?如何进行逻辑判断?逻辑判断结
2、果如何表达?逻辑判断结果如何表达?4.0 选择结构导入选择结构导入 在程序设计中含有选择结构的问题是大量存在的在程序设计中含有选择结构的问题是大量存在的 逻辑判断结果如何表达?逻辑判断结果如何表达?C 语言的语言的逻辑判断结果逻辑判断结果运算结果运算结果逻辑值逻辑值有两个:有两个:1和和0 “真真”用用1表示表示 “假假”用用0表示表示如何进行逻辑判断?如何进行逻辑判断?对于任意一个表达式(运算量):对于任意一个表达式(运算量):若表达式成立若表达式成立,或其值为或其值为非非0(无论正负无论正负),都代表都代表“真真”;若表达式不成立若表达式不成立,或其值为或其值为0,则代表则代表“假假”。C
3、 语言的逻辑判断、逻辑值语言的逻辑判断、逻辑值 关系运算关系运算实质上实质上就是就是比较运算比较运算。例如例如:a3为一比较运算为一比较运算,若若a=5,a3成立成立,结果为结果为“真真”,若若 a=1,a3不成立不成立,结果为结果为“假假”。上述表达式上述表达式:a3 称为称为关系表达式关系表达式。4.1 关系运算符和关系表达式关系运算符和关系表达式关系运算符及其优先级别关系运算符及其优先级别1.,=为同一优先级为同一优先级,=,!=为为同一优先级,同一优先级,但前者高于后者。但前者高于后者。2.关系运算符优先级低于算术运算符。关系运算符优先级低于算术运算符。3.关系运算符优先级高于赋值运算
4、符。关系运算符优先级高于赋值运算符。关系运算符关系运算符(双目运算双目运算符符)种类种类(六种六种):;=;=;!=;结合方向:自左向右结合方向:自左向右 优先级别:优先级别:=!=优先级(高)优先级(高)优先级(低)优先级(低)算术运算符算术运算符赋值运算符赋值运算符关系运算符关系运算符高高低低算术运算符算术运算符赋值运算符赋值运算符关系运算符关系运算符高高低低例如例如:ca+b c(a+b)ab!=c (ab)!=ca=bc a=(bc a=(bc)=!=优先级(高)优先级(高)优先级(低)优先级(低)定义定义:用用关系运算符关系运算符将将两个表达式两个表达式连接起来式子。连接起来式子。例
5、如:例如:ab a+bb+c (a=3)(b=5)a b (ab)(bc)关系表达式关系表达式1 结果为结果为真真(条件成立条件成立)0 结果为结果为假假(条件不成立条件不成立)关系表达式的值关系表达式的值(逻辑值逻辑值):1或或0,表示逻辑值表示逻辑值“真真”或或“假假”当当a=3,b=2,c=1时时b+cbf=abc条件条件成立成立,值为,值为1条件条件不成立不成立,值为值为0ab值为值为1,所以所以d=1ab为为1,abc为为0,所以所以f=0(ab)=c1.关系运算符左右两边类型不一致,自动进行类型转换,关系运算符左右两边类型不一致,自动进行类型转换,转换成两边的类型相同,然后进行比较
6、。转换成两边的类型相同,然后进行比较。例如例如:若若a=0,b=0.5,转换成转换成a=0.0,则则 a=b的值为的值为1 2.应避免对应避免对实数实数作相等或不等的判断,而作相等或不等的判断,而只能使用只能使用“”,原因在于舍入误差可能造成两个逻辑上应该相,原因在于舍入误差可能造成两个逻辑上应该相等的数不相等。等的数不相等。例如例如:如果如果x、y均为实数,要避免使用均为实数,要避免使用 x=y 应使用应使用 fabs(x-y)0&x104.2 逻辑运算符和逻辑表达式逻辑运算符和逻辑表达式逻辑运算符逻辑运算符逻辑表达式逻辑表达式C语言如何表达数学式子语言如何表达数学式子 0 xy&c (!a
7、)&b)(xy)&c)!高高&低低!(非)算术运算符关系运算符&|赋值运算符=高高低低定义:用定义:用逻辑运算符逻辑运算符将将关系表达式、逻辑量关系表达式、逻辑量连接起连接起来的式子。来的式子。例如例如:!a&bxy&c逻辑表达式逻辑表达式 4&0 2 值值为为1 在逻辑运算中在逻辑运算中,非非0值参加逻辑运算时被看成值参加逻辑运算时被看成1处理处理.53&2|83)&2|(8b)&(n=cd)判断判断m,n的值的值:结果结果m=0,n=1,表达式为,表达式为0例如例如:a&b&c 当当a=0(假假)时时,b,c不需判断。不需判断。当当a=1,b=0,c不需判断不需判断。例如例如:a b c
8、当当a=1时时,b,c均不必判别。均不必判别。逻辑表达式的值逻辑表达式的值满足下列满足下列2个条件中之一的为闰年个条件中之一的为闰年:年号能被年号能被4整除,但不能被整除,但不能被100整除。整除。年号年号能被能被400整除整除。例例1 写出判断年号是否为闰年的逻辑表达式写出判断年号是否为闰年的逻辑表达式用变量用变量year表示年号表示年号,则逻辑表达式:,则逻辑表达式:(year%4=0&year%100!=0)|year%400=0 值为值为1,则,则year为闰年;否则为非闰年。为闰年;否则为非闰年。满足下列满足下列2个条件中之一的为闰年个条件中之一的为闰年:年号能被年号能被4整除但不能
9、被整除但不能被100整除。整除。年号年号能被能被400整除整除。例例1 写出判断年号是否为闰年的逻辑表达式写出判断年号是否为闰年的逻辑表达式用上面的表达式加用上面的表达式加!判别非闰年:判别非闰年:!(year%4=0&year%100!=0)|year%400=0)值为值为1,则,则year为非闰年;否则为闰年。为非闰年;否则为闰年。执行过程执行过程:当表达式值非当表达式值非0时时,执行语句执行语句,否则否则,不执行语句不执行语句。例如例如:if(xy)printf(%d,x);形式形式1:if(表达式表达式)语句语句4.3 if语句(语句(三种形式三种形式)表达式表达式语句语句非0=0例例
10、2 输入两个实数,按其值由输入两个实数,按其值由小到大次序输出这两个数。小到大次序输出这两个数。表达式表达式语句语句非0=0形式形式1:if(表达式表达式)语句语句 main()float a,b,t;scanf(%f,%f,&a,&b);if(ab)t=a;a=b;b=t;printf(%5.2f,%5.2f,a,b);例例3 输入三个数,按从小到大的输入三个数,按从小到大的顺序输出。顺序输出。表达式表达式语句语句非0=0形式形式1:if(表达式表达式)语句语句main()float a,b,c,t;scanf(%f,%f,%f,&a,&b,&c);if(ab)t=a;a=b;b=t;if(
11、ac)t=a;a=c;c=t;if(bc)t=b;b=c;c=t;printf(%5.2f,%5.2f,%5.2f,a,b,c);例如例如:if(xy)printf(%d,x);else printf(%d,y);表达式表达式语句语句1语句语句2非0=0执行过程执行过程:当表达式当表达式值值为非为非0,执行语句执行语句1;当当表达式表达式值值为为0,执行语句执行语句2。形式形式2:if(表达式表达式)语句语句1 else 语句语句2表达式表达式语句语句1语句语句2非0=0例例4 输入一个数,判断它是否能被输入一个数,判断它是否能被3整除。整除。若能,则打印若能,则打印“YES”,否则,打印否则
12、,打印“NO”。形式形式2:if(表达式表达式)语句语句1 else 语句语句2 main()int n;printf(input n:);scanf(“%d”,&n);if(n%3=0)printf(YESn);else printf(NOn);执行过程执行过程:1)从上向下逐一对从上向下逐一对if后面的表达式进行检测。后面的表达式进行检测。2)当某一个表达式的值为非当某一个表达式的值为非0时,就执行与此有关的子句中的时,就执行与此有关的子句中的语句,其余部分就被越过去。语句,其余部分就被越过去。3)如果所有表达式的值都是如果所有表达式的值都是0,则执行最后的,则执行最后的else子句;子句
13、;4)如果没有最后的那个如果没有最后的那个else子句,那么,将不进行任何操作。子句,那么,将不进行任何操作。形式形式3:if(表达式表达式1)语句语句1 else if(表达式表达式2)语句语句2 else if(表达式表达式3)语句语句3 else if(表达式表达式n)语句语句n else 语句语句n+10表达式表达式1 表达式表达式2 表达式表达式n语句语句n+100语句语句n 语句语句2 语句语句1 非非0 非非0 非非0 形式形式3:if(表达式表达式1)语句语句1 else if(表达式表达式2)语句语句2 else if(表达式表达式3)语句语句3 else if(表达式表达式
14、n)语句语句n else 语句语句n+1例如:例如:if (number500)cost=0.15;else if (number300)cost=0.10;else if (number100)cost=0.075;else if (number50)cost=0.05;else cost=0;0表达式表达式1 表达式表达式2 表达式表达式n语句语句n+100语句语句n 语句语句2 语句语句1 非非0 非非0 非非0 形式形式3:if(表达式表达式1)语句语句1 else if(表达式表达式2)语句语句2 else if(表达式表达式3)语句语句3 else if(表达式表达式n)语句语句n
15、 else 语句语句n+10表达式表达式1 表达式表达式2 表达式表达式n语句语句n+100语句语句n 语句语句2 语句语句1 非非0 非非0 非非0 例例5:输入一个学生成绩,:输入一个学生成绩,当成绩当成绩90时,输出时,输出 very good,当当80成绩成绩90时时,输出输出 good,当当60成绩成绩80时时,输出输出pass,当成绩当成绩=90)printf(very good);else if(score=80)printf(good);else if(score=60)printf(pass);else printf(fail);例例6:输入一个字符,请:输入一个字符,请判断
16、是字母、数字还判断是字母、数字还是特殊字符。是特殊字符。#include main()char ch;printf(Please input a character:n);ch=getchar();if(ch=a&ch=A&ch=0&chb)if(3)if(a+88)1.表达式可以是逻辑表达式、关系表达式、算术表达式。表达式可以是逻辑表达式、关系表达式、算术表达式。2.语句必须以分号结束。语句必须以分号结束。3.若语句不止一条若语句不止一条,则必须用则必须用 括起来。在括起来。在 外不加分外不加分号。号。注意的问题注意的问题4.3 if语句(语句(三种形式三种形式)if语句的嵌套语句的嵌套:在
17、在if语句中语句中,又又包含一个或多个包含一个或多个if语句语句。if(表达式1)if(表达式2)语句1 else 语句2else if(表达式3)语句3 else 语句4内嵌if内嵌ifif(表达式1)if(表达式2)语句1 else 语句2内嵌ifif(表达式1)if(表达式2)语句1else 语句3 内嵌ifif(表达式1)语句1else if(表达式3)语句3 else 语句4内嵌ifif语句的嵌套语句的嵌套if(表达式1)if(表达式2)语句1else 语句3 内嵌ifif else 配对原则:配对原则:缺省缺省 时,时,else总是和它上面离它总是和它上面离它最近最近的未配对的的未
18、配对的if 配对。配对。if()if()if()else.else.else.if(表达式1)if(表达式2)语句1else 语句3 内嵌if如果没有如果没有 时的配对时的配对if语句的嵌套语句的嵌套if else 配对原则配对原则修改:修改:if(a=b)if(b=c)printf(a=b=c);else printf(a!=b);实现实现if else 正确配对方法:必要时,加正确配对方法:必要时,加 例例:if(a=b)if(b=c)printf(a=b=c);else printf(a!=b);例例7 7 有一函数有一函数:y=1 (x0)编一程序,输入一个编一程序,输入一个x值,输出
19、值,输出 y 值。值。有以下几种写法,请判断哪些是正确的?有以下几种写法,请判断哪些是正确的?if语句的嵌套语句的嵌套程序程序2:将程序:将程序1的的if语句改为:语句改为:main()int x,y;scanf(d,&x);if(x=0)if(x0)y=1;else y=0;else y=-1;printf(x=%d,y=%dn,x,y);程序程序1:main()int x,y;scanf(d,&x);if(x=0)if(x0)y=1;else y=-1;printf(x=%d,y=%dn,x,y);程序程序3:将程序将程序1的的if语句改为语句改为main()int x,y;scanf(%
20、d,&x);y=-1;if(x!=0)if(x0)y=1;else y=0;printf(x=%d,y=%dn,x,y);if语句的嵌套语句的嵌套y=0 (x0)1.程序程序1 和程序和程序2 是正确的。是正确的。它们代表的函数为它们代表的函数为:2.程序程序3 和程序和程序4 是错误的。是错误的。它们代表的函数为它们代表的函数为:y=0 (x0)y=1 (x0)结论结论:C语言提供了一个简单的语言提供了一个简单的条件赋值语句条件赋值语句或或条件条件表达式表达式。问题问题:当判断条件不论是当判断条件不论是“真真”是是“假假”,均均给同一变量赋值时给同一变量赋值时,怎样简洁方便?,怎样简洁方便?
21、条件条件运算符运算符是是?:属三目运算符。属三目运算符。答案答案:使用条件使用条件运算符运算符。4.3 条件运算符条件运算符执行过程执行过程:先求解表达式先求解表达式1,若非若非0(真真),则值为表达式则值为表达式2的值的值,否则,为表达式否则,为表达式3的值。的值。一般形式:一般形式:表达式表达式1?表达式表达式2:表达式表达式3例如:例如:max=ab?a:b;当当ab时时 max a,否则否则maxb条件运算符条件运算符表达式表达式1取取表达式表达式2值值取取表达式表达式3值值非0=0注意注意:1.条件运算符条件运算符优先于优先于赋值运算符。赋值运算符。例如例如:max=(ab?a:b)
22、可去掉可去掉()2.条件运算符条件运算符低于低于逻辑运算符、关系运算符和算术运算符。逻辑运算符、关系运算符和算术运算符。例如例如:max=ab?a:b+1 max=ab?a:(b+1)而不是而不是max=(ab?a:b)+1条件运算符条件运算符3.条件运算符结合性为条件运算符结合性为从右至左从右至左。例如例如:ab?a:cd?c:d 相当于相当于 ab?a:(cd?c:d)4.条件表达式不能取代一般的条件表达式不能取代一般的if语句语句,只有当只有当if 的两的两 个分支为个分支为给给同一变量同一变量赋值时才可替代赋值时才可替代if.例如例如:求求 y=a+|b|y=b=0?a+b:a-b;p
23、rintf(y=%dn,y);5.表达式表达式1、表达式、表达式2、表达式、表达式3的类型可以不同。的类型可以不同。例如例如:xy?1:1.5注意注意:条件运算符条件运算符条件运算符条件运算符例例8 输入一个字符,判别它是否大写字母输入一个字符,判别它是否大写字母。如果是,将它转换成小写字母;如果是,将它转换成小写字母;如果不是,不转换。如果不是,不转换。然后输出最后得到的字符。然后输出最后得到的字符。main()char ch;scanf(%c,&ch);ch=(ch=A&ch=Z)?(ch+32):ch;printf(%c,ch)switchswitch语句是语句是多分支选择语句多分支选择
24、语句,也叫,也叫开关语句开关语句一般形式:一般形式:switch(表达式表达式)case常量表达式常量表达式1:语句语句 1 break;case常量表达式常量表达式2:语句语句 2 break;case常量表达式常量表达式n:语句语句 n break;default:语句语句 n+1 4.5 switch语句语句switch表达式语句1语句2语句n语句n+1式 1式2式ndefaultcase 执行过程:执行过程:当表达式的值与某一个当表达式的值与某一个 case 后面的常量表达式的值后面的常量表达式的值相等时,就执行此相等时,就执行此 case 后面的语句。若所有的后面的语句。若所有的 c
25、ase 中的常量表达式的中的常量表达式的值都没有与表达式的值匹配,则执行值都没有与表达式的值匹配,则执行 default 后面的语句。后面的语句。例例9 9 根据成绩等级,打印出成绩范围。根据成绩等级,打印出成绩范围。4.4 switch语句语句main()char grade;printf(Enter your graden);scanf(%c,&grade);switch(grade)case A:printf(90100n);break;case B:printf(8089n);break;case C:printf(7079n);break;case D:printf(6069 n);
26、break;case E:printf(60n);break;default:printf(errorn);没有没有breakbreak将是将是错误的。错误的。例如输入例如输入B B,打,打印出:印出:80897079606960error 例例10 10 根据成绩范围,打印出成绩等级。根据成绩范围,打印出成绩等级。4.5 switch语句语句main()int score,num;char grade;scanf(%d,&score);num=score/10;switch(num)case 10:case 9:grade=A;break;case 8:grade=B;break;case
27、7:grade=C;break;case 6:grade=D;break;default:grade=E;printf(%d%c,score,grade);2个或多个个或多个case可以共用可以共用一组执行语句一组执行语句1.表达式的类型和常量表达式的类型表达式的类型和常量表达式的类型必须一致;必须一致;switchswitch后面的表达式一般后面的表达式一般情况下是情况下是整型整型或或字符型字符型。2.每一个每一个 case 的常量表达式的值必须互不相同。的常量表达式的值必须互不相同。3.多个多个case和和default的出现次序不影响执行结果。的出现次序不影响执行结果。4.case常量表
28、达式只起语句标号作用常量表达式只起语句标号作用;必须用必须用break语句终止多个语句终止多个case连续执行,连续执行,否则只要有一个否则只要有一个case满足后满足后,以下的语句全部无条件执行。以下的语句全部无条件执行。说明:说明:4.5 switch语句语句main()int score,num;char grade;scanf(%d,&score);num=score/10;switch(num)case 10:case 9:grade=A;break;case 8:grade=B;break;case 7:grade=C;break;case 6:grade=D;break;defa
29、ult:grade=E;printf(%d%c,score,grade);main()int x=1,y=0,a=0,b=0;switch(x)case 1:switch(y)case 0:a+;break;case 1:b+;break;case 2:a+;b+;break;case 3:a+;b+;printf(na=%d,b=%d,a,b);switch的嵌套的嵌套4.5 switch语句语句4.6 程序举例程序举例 例例11 11 求一元二次方程求一元二次方程ax2+bx+c=0的解的解。aacbbx242#include /*求绝对值和平方根,需要求绝对值和平方根,需要math.h*
30、/#include main()float a,b,c,disc,x1,x2,rpart,ipart;printf(nnplease input a,b,c:);scanf(%f,%f,%f,&a,&b,&c);/*输入方程的系数输入方程的系数*/printf(The equation);if(fabs(a)=1e-6)/*若若a等于等于0,则不是一元二次方程,则不是一元二次方程*/printf(is not quadratic);exit(0);else disc=b*b-4*a*c;if(fabs(disc)1e-6)/*0,有两个不等实根,有两个不等实根*/4.4 程序举例程序举例 aa
31、cbbx242 x1=(-b+sqrt(disc)/(2*a);x2=(-b-sqrt(disc)/(2*a);printf(has two distinct real roots:%8.4f,%8.4f,x1,x2);else /*0,有两个共厄复根,有两个共厄复根*/rpart=-b/(2*a);ipart=sqrt(-disc)/(2*a);printf(has two complex roots:);printf(n%8.4f+%8.4fi,rpart,ipart);printf(n%8.4f-%8.4fi,rpart,ipart);4.4 程序举例程序举例 例例12 12 从键盘输入
32、年号和月号,计算这一年的这一从键盘输入年号和月号,计算这一年的这一月共有多少天。月共有多少天。注意:注意:编写该程序需要考虑闰年问题,因为二月份的天数与闰年编写该程序需要考虑闰年问题,因为二月份的天数与闰年有关。有关。闰年的判断依据是:若某年能被闰年的判断依据是:若某年能被4整除,但不能被整除,但不能被100整除,整除,则这一年是闰年;或者这一年号能被则这一年是闰年;或者这一年号能被400整除,也是闰年。整除,也是闰年。闰年:闰年:2月为月为29天;非闰年:天;非闰年:2月为月为28天。天。(设(设:年号年号:year、月份:、月份:month,天数:天数:days)#include main
33、()int year,month,days;scanf(%d%d,&year,&month);switch(month)case 1:case 3:case 5:case 7:case 8:case 10:case 12:days=31;break;/*处理处理“大大”月月*/case 4:case 6:case 9:case 11:days=30;break;/*处理处理“小小”月月*/case 2:if(year%4=0&year%100!=0|year%400=0)days=29;/*如果是闰年如果是闰年*/else days=28;/*不是闰年不是闰年 */break;default:
34、printf(Input error!nn);days=0;/*月份错误月份错误*/if(days!=0)printf(%d,%d is%d daysnn,year,month,days);1.逻辑运算符两侧运算对象的数据类型(逻辑运算符两侧运算对象的数据类型()A)只能是只能是0或或1 B)只能是只能是0或非或非0正数正数 C)只能是整型或字符型数据只能是整型或字符型数据 D)可以是任何类型的数据可以是任何类型的数据讨讨 论论2.能正确表示当能正确表示当x 的取值在的取值在1,10和和200,210范围内为范围内为”真真”,否则为否则为”假假“的表达式是(的表达式是()A)(x=1)&(x=
35、200)&(x=1)|(x=200)|(x=1)&(x=200)&(x=1)|(x=200)|(x=210)讨讨 论论4.分析输出结果分析输出结果main()int x=2,y=-1,z=2;if(xy)if(y 5)printf(%dn,m);else printf(%dn,m-);1.编写一个程序,模拟四则运算。编写一个程序,模拟四则运算。形式如下:形式如下:num1 operator num2 其中,其中,num1 与与num2表示要进行运算的两个数,表示要进行运算的两个数,operator表示运算规则(即可以是表示运算规则(即可以是“+”、“-”、“*”、“/”之一),运算的结果保留两
36、位小数。之一),运算的结果保留两位小数。思思 考考 题题2.WHO对成年人的身体是否肥胖有一标准。对成年人的身体是否肥胖有一标准。K=体重体重(kg)/身高的平方身高的平方(m*m)如果如果k=18.5,则意味着偏瘦则意味着偏瘦 如果如果k=23.5,则意味着肥胖(则意味着肥胖(fat cat)编写一程序,输入体重和身高,判断身材是否正常。编写一程序,输入体重和身高,判断身材是否正常。思思 考考 题题 3.商场促销,购物商场促销,购物500元以上,元以上,8折折;购物购物300元以上,元以上,85折折;购物购物100元以上,元以上,9折折;购物购物50元以上,元以上,95折折;购物购物50元以下,不打折。根据消费量,计算优惠率。元以下,不打折。根据消费量,计算优惠率。设:消费量为设:消费量为 money;折扣为折扣为 cost;实际花费实际花费 price思思 考考 题题小小 结结v 关系运算符和关系表达式的特点关系运算符和关系表达式的特点v 逻辑运算符和逻辑表达式的特点逻辑运算符和逻辑表达式的特点v ifif语句语句 的的3 3种形式种形式(应用范围应用范围单分支、两分支、多单分支、两分支、多分支分支)、嵌套、条件表达式、嵌套、条件表达式(?:?:)v switch switch语句语句(多分支多分支)v 选择结构程序设计举例选择结构程序设计举例作业和上机实验