c4第四章 选择结构程序设计(2011).ppt
第四章第四章选择结构程序设计选择结构程序设计 n教学目的教学目的:掌握选择结构的形式,掌握典型算法。n教学要求教学要求:掌握关系表达式和逻辑表达式以及在选择结构中的使用。学会把现实问题通过表达式的形式表示。关系运算符和关系表达式RelationalOperatorsandExpressions逻辑运算符和逻辑表达式LogicalOperatorsandExpressions条件表达式ConditionalExpressionsif语句switch语句关系运算符和以关系运算符组成的关系表达式关系运算符和以关系运算符组成的关系表达式l关系运算符关系运算符种类:种类:=!=结合方向:自左向右结合方向:自左向右优先级别:优先级别:=!=优先级6(高)优先级7(低)l关系表达式:以关系符连起来的式子关系表达式:以关系符连起来的式子q关系表达式的值:是逻辑值关系表达式的值:是逻辑值“真真”或或“假假”,用用1和和0表示;表示;q1表示逻辑真,表示逻辑真,0表示逻辑假(非零为真)表示逻辑假(非零为真)例 int a=3,b=2,c=1,d,f;ab (ab)=c b+cb f=abc/表达式值表达式值1/表达式值表达式值1/表达式值表达式值0/d=1/f=0因为a=x值为1,所以x=b的值为0关系运算表达式使用中要注意各步骤的逻辑值:关系运算表达式使用中要注意各步骤的逻辑值:例例 若若a=0;x=0.3;b=0.5;则则 a=x278在C中是允许的,值为0例inti=1,j=7,a;a=i+(j%4!=0);则a=2例a0结果为A100结果为10因为上式运算步骤是左结合左结合(52)7)8所以5278的值为0关系运算注意:关系运算注意:2.注意区分注意区分=与与=main()int a=0,b=1;printf(%dn,a=b);printf(%dn,a=b);getch();1.避免对避免对实数实数作相等或不等的判断作相等或不等的判断如1.0/0.00001*0.00001=1.0;结果为一般而言,对于实型量a,b作相等或不等的判断应当用:fabs(a-b)1e-6001关系运算注意:关系运算注意:2.注意区分注意区分=与与=main()int a=0,b=1;printf(%dn,a=b);printf(%dn,a=b);getch();1.避免对避免对实数实数作相等或不等的判断作相等或不等的判断如1.0/0.00001*0.00001=1.0;结果为一般而言,对于实型量a,b作相等或不等的判断应当用:fabs(a-b)1e-6001关系运算注意:关系运算注意:2.注意区分注意区分=与与=main()int a=0,b=1;printf(%dn,a=b);printf(%dn,a=b);getch();1.避免对避免对实数实数作相等或不等的判断作相等或不等的判断如1.0/0.00001*0.00001=1.0;结果为一般而言,对于实型量a,b作相等或不等的判断应当用:fabs(a-b)1e-6001补补充充知知识识:例如:对于例如:对于 float a,b;n不要用不要用 if(a=b)进行比较,进行比较,n而要用而要用 if(fabs(a-b)=epsilon*fabs(a)进行比较进行比较,(其中要确保(其中要确保a不会为不会为0)epsilon是一个控制接近度的值。是一个控制接近度的值。n用绝对阈值的方法是许多书上推荐的:用绝对阈值的方法是许多书上推荐的:if(fabs(a-b)0.000001)但这种使用固定阈值但这种使用固定阈值0.000001的方法难以持续有效。因为,的方法难以持续有效。因为,有可能两个较小的本应不相等的数正好相差小于有可能两个较小的本应不相等的数正好相差小于0.000001,而两个本应看做相等的大数却相差大于而两个本应看做相等的大数却相差大于0.000001。nDoug Gwyn推荐使用推荐使用“相对差相对差”比较浮点数:比较浮点数:if(fabs(a-b)/max(fabs(a)-fabs(b)x等价于等价于y0,它们的逻辑结果都是,它们的逻辑结果都是true。但从计算机而言,当。但从计算机而言,当x与与y的绝对值相差很大时,这个值就有可能是的绝对值相差很大时,这个值就有可能是false#include main()double x=1e20,y=10;printf(%d,x+yx);getch();/*输出是输出是0*/ab!a!ba&ba|b真假真假假假真真逻辑运算符和以逻辑运算符组成的逻辑表达式逻辑运算符和以逻辑运算符组成的逻辑表达式l逻辑运算符逻辑运算符种类:种类:&|!(与与 或或 非非 )逻辑运算真值表逻辑运算真值表nC C语言中语言中,逻辑逻辑量量的值的值:0 0表示表示“假假”,非,非0 0表示表示“真真”,”,nC C语言中语言中,逻辑表达式的逻辑表达式的结果结果:0:0表示表示“假假”,1 1表示表示“真真”,”,n&(与运算与运算)就是求交集的运算就是求交集的运算|(或运算或运算)就是求并集的运算就是求并集的运算真假假假假假真真假假真真真假真真!(2)&(11)|(12)高高低低例例 a=x&xb&xy a=b|x=y !a|abl优先级:l结合方向:!:从右向左从右向左&:从左向右从左向右|:从左向右从左向右 (a=x)&(xb)&(xy)(a=b)|(x=y)(!a)|(ab)例例 a=4;b=5;!a a&b a|b !a|b 4&0|2 53&2|83)&2|(8b)&(n=cd)/结果结果m=0,n=1,表达式表达式=0(假)假)条件运算符条件运算符(The Comma Operator)?:一般形式:一般形式:expr1?expr2 :expr3l执行过程执行过程:如果如果 expr1成立成立,则执行则执行expr2,否则执行否则执行expr3l功能:相当于条件语句,但不能取代一般功能:相当于条件语句,但不能取代一般if语句语句expr1取expr2值取expr3值非0=0nexpr1?expr2:expr3 中中 expr1、expr2、expr3类型可不同,表达式值取较高的类型n条件运算符可嵌套 如 x0?1:(xb?a:cd?c:d ab?a:(cd?c:d)例 x?a:b x0,表达式值为表达式值为a;x=0,表达式值为表达式值为b xy?1.0:1.5 xy ,值为值为1.0;x0?a+b:a-b a+|b|例 (a=b)?Y:N a等于等于b为为Y,否则为,否则为N (x%2=1)?1:0 10进制整数转为进制整数转为2进制进制 (x=0)?x:-x x的绝对值的绝对值 (c=a&c0?1:(xb&ac)?a:(bc?b:c)max(a,b,c)a(bc?b:c)?a:(bc?b:c)max(a,b,c)怎样取整:怎样取整:最直接方法:最直接方法:(int)(x+0.5)(要求要求x0)改进的方法:改进的方法:(int)(xy)max=x;elsemax=y;exprstatement非0=0形式二:u格式:if(expression)statement1elsestatement2u执行过程:例:if(xy)printf(“%d”,x);exprstatement1statement2非0=0形式三:格式:if(expr1)statement1elseif(expr2)statement2elseif(expr3)statement3.elsestatementnexpr1statemnt1非0=0expr2expr3statemntnstatemnt3statemnt2非0非0=0=0u执行过程:if(salary10000)index=0.4;elseif(salary8000)index=0.3;elseif(salary4000)index=0.2;elseif(salary2000)index=0.1;elseindex=0;如:if(a=b&x=y)printf(a=b,x=y);if(3)printf(OK);if(a)printf(%d,a);ustatement可以是一条语句或复合语句uif(x)if(x!=0)例例:if(3)if(3!=0)恒成立恒成立 if(0)if(0!=0)恒不成立恒不成立 if(!x)if(x=0)例例:if(!3)if(3=0)恒不成立恒不成立 if(!0)if(0=0)恒成立恒成立l说明:uif后面的表达式类型任意uif 后面的表达式的值按逻辑值处理(0或非0)。例下面程序正确吗?#include main()int x,y;printf(x=);scanf(%d,&x);printf(y=);scanf(%d,&y);if(xy)x+;y-;elsex-;y+;printf(%d,%dn,x,y);getch();illegalelsewithoutmatchingifmain()int x,y;printf(输入一个整数输入一个整数:);scanf(%d,&x);y=x;if(y0)y=-y;printf(整数整数%d的绝对值是的绝对值是%d。,x,y);getch();例:求一个数的绝对值运行:输入一个整数运行:输入一个整数:-12 整数整数-12的绝对值是的绝对值是12。main()int a,b;printf(a=);scanf(%d,&a);printf(b=);scanf(%d,&b);if(a=b)printf(a=b);else printf(ab);getch();例 输入两个数并判断两数相等否运行:a=12b=12a=b运行:a=12b=9ab例如:已知三角形的三条边求面积例如:已知三角形的三条边求面积 计算并显示结果计算并显示结果显示出错提示显示出错提示结束结束两边和大于第两边和大于第3边边?开始开始输入数据输入数据程序#include#include main()float a,b,c,s,area;printf(Side a=);scanf(%f,&a);printf(Side b=);scanf(%f,&b);printf(Side c=);scanf(%f,&c);if(a+bc&a+cb&b+ca)s=0.5*(a+b+c);area=sqrt(s*(s-a)*(s-b)*(s-c);printf(area=%6.2fn,area);else printf(“Sorry,reentry please.);getch();运行时输入:运行时输入:3 4 5输出:输出:area=6.00运行时输入:运行时输入:1 3 3输出:输出:Sorry,reentry pleasevif语句嵌套l一般形式if(expr1)if(expr2)statement1elsestatement2elseif(expr3)statement3elsestatement4内嵌if内嵌ifif(expr1)if(expr2)statement1elsestatement2内嵌ifif(expr1)if(expr2)statement1elsestatement3内嵌ifif(expr1)statement1elseif(expr3)statement3elsestatement4内嵌if例例:输入两数并判断其大小关系输入两数并判断其大小关系 main()int x,y;printf(x=);scanf(%d,&x);printf(y=);scanf(%d,&y);if(x!=y)if(xy)printf(xyn);elseprintf(xyn);elseprintf(xyn);getch();运行:运行:x=12y=15 xyx=6y=6 x yif else 配对原则:配对原则:缺省缺省 时,时,else总是和它上面离它最近总是和它上面离它最近的未配对的的未配对的if 配对配对if()if()if()else.else.else.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”);实现ifelse正确配对方法:加题目:题目:从从a是否等于是否等于b开始,判断开始,判断a、b、c三值是否相等三值是否相等 A code fragment is to be used to separate integer values into five ranges.For example:0.29,30.49,50.59,60.69,70.100.What is the fewest number of if.else selection statements needed to do this?Note,all data presented will already have been validated to ensure they are in the range 0.100.breakbreak语句(中断语句)语句(中断语句)n语句形式:break;n作用:中止switch结构或循环结构的执行,转去执行相应结构的下一条语句。n说明:break语句只能用于switch结构或者循 环结构之中。switch statementsn使用使用if语句嵌套层次太多,容易发生错误,因此在多分支结语句嵌套层次太多,容易发生错误,因此在多分支结构中,通常使用构中,通常使用switch语句语句。nSuppose we had an integer variable j,and wanted to execute different statements depending on the value of j.Lets suppose we wanted to print j is one if j had value 1,j is two if j has the value 2,otherwise we want to print j is neither 1 nor 2.We could write the following code:if(j=1)printf(“j is one”);else if(j=2)printf(“j is two”);else printf(“j is neither 1 nor 2”);n OR we could use a switch statement.switch statement exampleswitch(j)case 1:printf(“j is one”);break;case 2:printf(“j is two”);break;default:printf(“j is neither 1 nor 2”);nWhen used in a switch statement,the break statement causes control to pass to the statement following the closing brace.switch statement switch语句的一般形式语句的一般形式 switch(expr)case constant1:statement1;break;case constant2:statement2;break;:default:default statement;expr mustbeoftypeint.Each case labelmustbefollowedbyaconstant.Firstexpr isevaluated,controlthenpassestothecaselabelhavingmatchingconstantvalue,otherwise,controlpassestothedefaultlabel.Youusuallywanttousebreakstatementsinsideswitches.Remember:moreallstatementsfollowingthematchingcaselabelwillbeexecuted.Thedefaultstatementneednotbethelastintheswitch.l 当表达式的值与某一个当表达式的值与某一个case后面的常量相后面的常量相等时,执行该等时,执行该case后面的语句。然后执行后面的语句。然后执行break语句语句switch结构。结构。l 若所有的若所有的case后面的常量都不和表达式的后面的常量都不和表达式的值相匹配,就执行值相匹配,就执行default后面的语句。后面的语句。l 每一个每一个case的常量表达式必须互不相同。的常量表达式必须互不相同。l 常量可以是整数或字符常量可以是整数或字符 switchswitch语句(开关分支语句)语句(开关分支语句)使用使用if语句嵌套层次太多,容易发生错误,因此在多分支结语句嵌套层次太多,容易发生错误,因此在多分支结构中,通常使用构中,通常使用switch语句语句。v执行过程:switch(表达式)caseE1:语句组1;break;caseE2:语句组2;break;.caseEn:语句组n;break;default:语句组n+1;v一般形式:switch表达式语句组1break;语句组2break;语句组nbreak;语句组n+1.E1E2Endefaultcasev说明:lE1,E2,EnE1,E2,En是常量表达式是常量表达式,且值必须互不相同且值必须互不相同lSwitch(Switch(表达式表达式)中的值自动取整中的值自动取整lcase En:起起语句标号的作用,如果不用语句标号的作用,如果不用break跳出,跳出,程序就顺序执行下去。程序就顺序执行下去。lcase后可包含多个可执行语句,且不必加后可包含多个可执行语句,且不必加 lswitchswitch可嵌套可嵌套l多个多个case可共用一组执行语句可共用一组执行语句如:caseA:caseB:caseC:printf(“score60n”);break;.例:当score为5时,以下程序段的输出是什么?switch(score)case5:printf(“Verygood!”);case4:printf(“Good!”);case3:printf(“Pass!”);case2:printf(“Fail!”);default:printf(“dataerror!”);运行结果:运行结果:score为为5时,输出:时,输出:Very good!Good!Pass!Fail!data error!例例 (switch(switch的嵌套使用的嵌套使用):写出程序的出结果:写出程序的出结果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);getch();运行结果:a=2,b=1选择结构程序示例选择结构程序示例 例4.3若有函数x(x2)y=2x-1(2x10)3x+10(x10)任意输入x,输出y,写此程序。方法一:方法一:用用if语句形式语句形式1编写编写 main()float x,y;scanf(%f,&x);if(x2)y=x;if(2=x&x=10)y=3*x+10;printf(%f,%fn,x,y);方法二:方法二:用用if语句形式语句形式3编写编写main()float x,y;scanf(%f,&x);if(x2)y=x;else if(2=x&x10)y=2*x-1;else y=3*x+10;printf(%f,%fn,x,y);方法三:用方法三:用switchswitch语句编写程序语句编写程序main()float x,y;int z;printf(x=);scanf(%f,&x);/Universal formulaz=1*(x2)+2*(2=x&x=10);switch(z)case 1:y=x;break;case 2:y=2*x-1;break;case 3:y=3*x+10;printf(%f,%fn,x,y);getch();例:例:以笛卡尔坐标点以笛卡尔坐标点(x,y)为输入,编程判断该点为输入,编程判断该点位于哪个象限或坐标轴上位于哪个象限或坐标轴上分析:对于点分析:对于点(x,yx,y)若x0且y0,则位于I象限;若x0,则位于II象限;若x0且y0且y0&y0)+2*(x0)+3*(x0&y0&y25&(status=S|ststus=D)取反可以写作:取反可以写作:age=25|(status!=S&ststus!=D)Single Divorce