还剩18页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
第五章程序控制流程——选择结构
5.1关系运算符和逻辑运算符
一、关系运算符和关系表达式
1.关系运算符1关系运算符的分类C语言为用户提供了6个关系运算符小于、=小于等于、大于、=大于等于、==关系相等和!=关系不等2关系运算符的优先级关系运算符内部优先级是、=、、=的优先级相等,且优先级高于==和!=在C语言所有运算符中,关系运算符的优先级要低于算术运算符和位移运算符3关系运算符的结合性所有的关系运算符的结合性都是从左至右
2.关系表达式的基本形式有值表达式1op有值表达式2,其中op代表6个关系运算符关系表达式的结果要么为0操作数不满足关系运算,要么为1操作数满足关系运算假设有以下变量定义inta=1b=-3c=2i=13;以下都是合法的关系表达式ab、i=
10、a+bb+c、a=cb=
5、a==
5、a+b==
2009、a!=b+
2、b*b=4*a*c等
3.关系运算符的使用1带有关系运算符的复杂表达式计算【例
5.1】当a=3,b=2,c=1时,表达式f=abc的值是【例
5.2】下面关系表达式中结果为假的是A0!=1B2=8Ca=2*2==2Dy=2+2==4说明在C语言中用一切非0数往往是1表示逻辑真,0表示逻辑假【课内思考题
5.1】当a=5b=4c=2时,表达式ab!=c的值是2关系运算中的隐式类型转换【例
5.3】分析下面程序的输出结果,并说明原因#includestdio.h__in{inti=-10;unsignedintj=1;printfij:%d\nij;}3怎样比较两个浮点数是否相等有些浮点数在计算机内部是无法精确表示的,这主要是由于浮点数在计算机内部特殊的存储格式引起的,例如#includestdio.h__in{doublea=1234567__.9*9b=
1111111109.1;doublec=
0.1+
0.2;printfc==
0.3%d\nc==
0.3;printfa==b%d\na==b;}【例
5.4】比较两个浮点数是否相等的正确方法#includestdio.h#include__th.h#defineYUZHI1e-6__in{doublea=1234567__.9*9b=
1111111109.1;doublec=
0.1+
0.2;printfa=%.9fb=%.9f\nab;printfa==b%d\na==b;printfa==b%d\nfabsa-b=YUZHI;printfc==
0.3%d\nc==
0.3;printfc==
0.3%d\nfabsc-
0.3=YUZHI;}说明应该避免直接比较两个浮点数是否相等,而是通过看两个浮点数差的绝对值是否小于某个很小的数来达到判断两个浮点数是否相等
二、逻辑运算符和逻辑表达式
1.逻辑运算符1逻辑运算符的分类C语言为用户提供了3个逻辑运算符!逻辑非、逻辑与和||逻辑或2逻辑运算符的优先级其中!逻辑非是单目运算符,在C语言所有运算符中优先级排第二所有的单目运算符优先级都是第二逻辑与的优先级高于||逻辑或,||的优先级高于:条件运算符3逻辑运算符的结合性其中!逻辑非的结合性是从右至左所有的单目运算符的结合性都是从右至左,和||的结合性是从左至右
2.逻辑表达式的基本形式!有值表达式1,有值表达式1有值表达式2,有值表达式1||有值表达式2逻辑表达式的结果见下表有值表达式1有值表达式2!有值表达式1有值表达式1有值表达式2有值表达式1||有值表达式2非0非0011非000010非010100100说明实际编程时,总是用逻辑运算符去连接关系表达式
3.逻辑运算符的使用1带有逻辑运算符的复杂表达式计算【例
5.5】以下程序的运行结果是#includestdio.h__in{intabd=241;a=d/100%9;b=-1-1;printf%d%dab;}A61B21C60D20【课内思考题
5.2】若a=2b=4,则表达式!x=a||y=b0的值是【课内思考题
5.3】inta=3b=4c=5;则以下表达式!a+b+c-1b+c/2的值为2短路计算对于逻辑表达式“表达式1表达式2…表达式n”而言,若在计算过程中发现表达式m的值为0,根据的特点,整个逻辑表达式的结果肯定为0,为提高计算效率,编译器不会计算从表达式m+1开始的后序表达式了,称为短路计算同样对于“表达式1||表达式2||…||表达式n”而言,只要发现某个表达式的值为1,肯定计算结果的同时也没有必要计算后面这些表达式的值短路计算在编程中有重要用途,能够为其他运算提供卫士number!=01/number
0.5,由于在做除法时,除数不能为0,所以在计算1/number是否大于
0.5之前,先判断变量number的值是不是0【例
5.6】设有说明语句inta=1b=2c=3d=4m=2n=2;,则执行m=abn=cd后n的值为【例
5.7】执行以下语句后a的值为,b的值为inta=5b=6w=1x=2y=3z=4;a=wxb=yz;
四、用关系或逻辑表达式表示条件要按照语义并使用关系或逻辑表达式去描述条件,且当条件成立时,表达式值为1;当条件不成立时,表达式值为0【例
5.8】设y为int变量,请写出描述“y是奇数”的表达式分析首先,用来描述条件的表达式中必然包含变量y其次,这个带有变量y的表达式的值只有两种结果假如y的值是奇数的话,该表达式的计算结果为1;假如y是偶数的话,该表达式的计算结果为0最后,按照语义来构造表达式——奇数的特点是被2除余1也可认为不能被2整除,不难得到y%2==1由%的优先级高于!=,所以也可写成y%2==1请思考还有没有别的写法?【课内思考题
5.4】假设x是一个int变量,怎样用表达式表示条件“x被3整除,同时被5除余3”?【课内思考题
5.5】假设x是一个double变量,怎样描述条件”2x3”也即写一个表达式能判断x∈23中,如果x∈23,表达式值为1;如果x不在23,则表达式值为0?【例
5.9】若x、y、z均为int变量,则描述“x或y中有一个小于z”的表达式是【例
5.10】判别某年year是否闰年闰年的条件是符合下面二者之一能被4整除,但不能被100整除;能被400整除可以用一个逻辑表达式来表示year%4==0year%100!=0||year%400==0,如果熟悉运算符的优先级,则表达式进一步简化为year%4==0year%100!=0||year%400==0【课内思考题
5.6】判断char型变量ch是否为大写字母的正确表达式是AA=ch=ZBch=Ach=ZCch=Ach=ZDch=AANDch=Z
5.2用if语句和if-else语句实现选择控制流程
一、if语句
1.基本语法格式if表达式语句说明1if语句的执行过程是先计算表达式的值,如果非0就执行包含在if中的语句;如果为0就不执行该语句如下图所示2if语句中的表达式可以是任意的有值表达式,实际编程时往往使用关系表达式或将多个关系表达式用逻辑运算符连接起来的逻辑表达式3if中的语句可以是除了声明语句以外的其他语句,例如各种流程控制语句if、if-else、switch、while、do-while和for、流程转移语句break、continue、return和goto、表达式语句包括函数调用语句、空语句和复合语句
2.应用示例【例
5.11】分析以下程序的执行结果#includestdio.h__in{inti=-1;ifi=0printf%d\ni++;printf%d--i;}【例
5.13】从键盘输入三个整数,计算其中的最大者并将其输出#includestdio.h__in{intabc;int__x;scanf%d%d%dabc;__x=a;/*先假定变量a的值最大*/if__xb__x=b;/*比较变量__x值和变量b值的大小如果b大就将b赋给__x*/if__xc__x=c;/*比较变量__x值和变量c值的大小如果c大就将c赋给__x*/printfthe__xnumberin%d%d%dis%d\nabc__x;}
二、if-else语句
1.基本语法格式if表达式语句1else语句2说明1if-else语句是由if子句和else子句组成的具体执行过程是先计算表达式的值,如果非0就执行语句1;如果为0就执行语句2如下图所示2表达式和语句的说明同if语句
2.应用示例【例
5.13】分析以下程序的执行结果#includestdio.h__in{inta10b=50c=30;ifa=b+cprintf*******\n;elseprintf$$$$$$$\n;}【例
5.14】输入两个实数,按代数值由小到大的次序输出这两个数#includestdio.h__in{doubleabt;scanf%lf%lfab;ifab{t=a;a=b;b=t;}printf%lf%lfab;}【课内思考题
5.7】如果将上面的if的复合语句的花括号去掉,根据输入值,结果如何?本例也可改用if-else语句实现#includestdio.h__in{doubleab;scanf%lf%lfab;ifabprintf%lf%lfab;elseprintf%lf%lfba;}【例
5.15】以下不正确的if语句形式是Aifxyx!=y;Bifx==yx+=y;Cifx!=yscanf%dx;elsescanf%dy;Difxy{x++;y++;}分析选项A中的if后面是一个空语句仅仅由;构成的语句空语句语法主要用在以下场合程序的某些地方不需要执行任何操作,但是由于语法的定义,这些地方必须要有语句,在这种情况下就不得不使用空语句
三、嵌套的if-else语句
1.if子句后面嵌套if语句或者if-else语句有四种基本形式1if表达式1if表达式2语句2if表达式1if表达式2语句1else语句23if表达式1if表达式2语句1else语句24if表达式1if表达式2语句1else语句2else语句3上面只给出一次嵌套的四种情况其实是三种,2和3是等价的,事实上if语句和if-else语句可以连续嵌套从2和3中不难发现,当if子句后面嵌套if语句或者if-else语句时,就会产生else子句究竟和哪个if子句配对的问题为了解决表达上的歧义,C语言语法规定在嵌套的if语句或者if-else语句中,else子句总是与之前离它最近的if子句配对根据这条规则,那么2和3的语句结构就是相同了【例
5.16】以下程序的输出是#includestdio.h__in{intx=2y=-1z=2;ifxyify0z=0;elsez+=1;printf%d\nz;}A3B2C1D
02.else子句后面嵌套if语句或者if-else语句有两种基本形式1if表达式语句1elseif表达式语句22if表达式语句1elseif表达式2语句2else语句3当if-else语句的else子句后面连续嵌套if-else语句时,就会出现一种非常有用编程结构——else-if结构if表达式1语句1elseif表达式2语句2else……elseif表达式n-1语句n-1else语句n说明1很多书认为else-if是C语言中的一种选择语句,这种语法观点是错误的确切地将else-if是一种编程结构,在多路条件判断时非常有用if-else语句只能对一个条件进行一次判断,而else-if能对多个条件进行多次判断2上述else-if结构是根据程序缩进的原则来书写的,一旦嵌套层次过多,就会造成程序段向右下倾斜由于空白符空格、换行和制表符等会被编译器完全忽略,所以将每个else子句左对齐后就得到更为美观的形式if表达式1语句1elseif表达式2语句2……elseif表达式n-1语句n-1else语句n3最后一个else子句后面可以嵌套一个if语句4else-if结构的含义就是从上到下依次检测每个if子句中的表达式是否为0,执行第一个表达式非0的if子句后面的语句,如下图所示【例
5.17】成绩=90分的同学成绩用A表示,80-90分的用B表示,70-80分的用C表示,60-70分的用D表示,60分以下输出FAIL!本题改编自C程序100例之15#includestdio.h__in{intscore;printfpleaseinputthescore:\n;scanf%dscore;ifscore=90printfA\n;elseifscore=80printfB\n;elseifscore=70printfC\n;elseifscore=60printfD\n;elseprintfFAIL!\n;}
四、条件运算符对一些简单的选择问题,完全可以由条件运算符:实现条件运算符是C语言中唯一的一个三目运算符,使用时必须连接三个表达式条件表达式的基本形式为有值表达式1有值表达式2:有值表达式3,执行过程如下先计算有值表达式1的值,如果非0,就执行表达式2;如果为0就执行表达式3如果表达式2和表达式3是有值表达式的话,那么整个条件表达式的值或者是表达式2的值或者是表达式3的值视表达式1的值是否为0:的优先级高于赋值运算符=和逗号运算符,排倒数第三,结合性是从右往左的【例
5.19】用条件运算符计算两个整型变量的较为大者并输出#includestdio.h__in{intab;int__x;scanf%d%dab;__x=aba:b;printf%d\n__x;}【例
5.20】分析以下程序程序的运行结果#includestdio.h__in{inta;scanf%da;printf%sa%2!=0no:yes;}【课内思考题
5.8】仿照本例程序的技法,实现以下问题输入鸡蛋数n,当输入的鸡蛋数n=1时,输出“Ih__e1egg.”;当输入的鸡蛋数n1时例如n=2009,输出“Ih__e2009eggs.”【课后作业3】1以下程序的输出是#includestdio.h__in{inta=5b=8c=3__x;__x=a;ifcbifca__x=c;elseifba__x=b;printf__x=%d\n__x;}2【同济大学99】阅读下面的程序并写出程序执行结果__in{intxyzw;z=x=-1y=-1y+=x+5:x=7y=3;w=y*a/4;printf%d%d%d%c\nxyzw;}
5.3用switch语句实现选择控制流程
一、switch语句
1.引例当处理多个选项的时候,else-if结构有些笨重,为此C语言向用户提供了switch语句为了对两者作一比较,特举例如下【例
5.21】从键盘输入一个星期的某一天,然后输出其对应的英文单词#includestdio.h__in{intday;scanf%dday;ifday==1printfMonday\n;elseifday==2printfTuesday\n;elseifday==3printfWednesday\n;elseifday==4printfThursday\n;elseifday==5printfFriday\n;elseifday==6printfSaturday;elseifday==7printfSunday\n;elseprintfthedaybetween1~7!\n;}说明本例采用else-if结构对day值进行反复判断,一旦判断次数过多就会造成程序冗长如改用switch语句实现,程序就能做到简洁易读
2.基本语法格式switch表达式{case常量表达式1语句序列1case常量表达式2语句序列2……case常量表达式n语句序列n[default语句序列n+1]}说明1switch语句的执行过程是依次比较每个case子句的常量表达式的值和switch圆括号里的表达式值是否相等,假设常量表达式k的值与switch圆括号里的表达式的值相等,就执行语句序列k,然后执行语句序列k+1直到最后一组语句序列如果所有的常量表达式的值都不等于switch后面圆括号里的表达式值,且存在default子句default子句是可选的,就执行default子句后面的语句序列;不存在default子句,则结束对switch语句的执行2switch语句圆括号里的表达式的结果类型只能是整数类型、字符类型和枚举类型,case子句中的常量表达式表达式中的操作数都是常量的结果类型要与之匹配3所有case子句中的常量表达式值都不重复改用switch语句实现例
5.21#includestdio.h__in{intday;scanf%dday;switchday{case1:printfMonday\n;case2:printfTuesday\n;case3:printfWednesday\n;case4:printfThursday\n;case5:printfFriday\n;case6:printfSaturday\n;case7:printfSunday\n;default:printfthedaybetween1~7!\n;}}说明1在每个case子句的语句序列最后要安排一条break语句,目的是退出当前的case子句避免执行后续case子句中的语句序列2case子句和default子句的出现次序是任意的,不会影响程序的结果3当把default子句提前书写时,勿忘加在语句序列的最后写上break语句【例
5.22】以下程序的输出结果是#includestdio.h__in{intxy;x=2;switchx{case1:case2:case3:case4:printfx5\n;case5:printfx=5\n;default:printfThevalueofxisunknown.\n;}}【例
5.23】计算某年某月天数#includestdio.h__in{intyearmonthdays;scanf%d-%dyearmonth;/*注意年月输入格式2009-4*/switchmonth{case1:days=31;break;case2:ifyear%4==0year%100!=0||year%400==0days=29;elsedays=28;break;case3:days=31;break;case4:days=30;break;case5:days=31;break;case6:days=30;break;case7:days=31;break;case8:days=31;break;case9:days=30;break;case10:days=31;break;case11:days=30;break;case12:days=31;break;}printf%d.%dhas%ddays\nyearmonthdays;}【课内思考题
5.9】从简化语句的角度对上述程序进行优化*【例
5.24】输入某年某月某日,判断这一天是这一年的第几天?本题改编自C程序100例之4#includestdio.h__in{intyearmonthday;intsumdays=0;printfpleaseinputthedateforanexample
2009.
4.14:\n;scanf%d.%d.%dyearmonthday;/输入格式为
2009.
4.13*/switch1{case1:ifmonth==1break;sumdays=sumdays+31;case2:ifmonth==2break;ifyear%4==0year%100!=0||year%400==0sumdays=sumdays+29;elsesumdays+=28;case3:ifmonth==3break;sumdays+=31;case4:ifmonth==4break;sumdays+=30;case5:ifmonth==5break;sumdays+=31;case6:ifmonth==6break;sumdays+=30;case7:ifmonth==7break;sumdays+=31;case8:ifmonth==8break;sumdays+=31;case9:ifmonth==9break;sumdays+=30;case10:ifmonth==10break;sumdays+=31;case11:ifmonth==11break;sumdays+=30;}sumdays+=day;printf%d.%d.%disthe%dthday\nyearmonthdaysumdays;}说明本例中的switch语句在实现时,创造性地将break语句作为if语句的内嵌语句,有条件地退出case子句,体现了用C语言语法的灵活性和自由性【例
5.25】以下程序的输出结果是#includestdio.h__in{inta=2b=7c=5;switcha0{case1:switchb0{case1:printf@;break;case2:printf!;break;}case0:switchc==5{case0:printf*;break;case1:printf#;break;default:printf#;break;}default:printf;}printf\n;}说明本例给出了在switch语句的case子句中嵌套switch语句的例子【例
5.26】有一分段函数用switch语句编一程序输入一个x的值,输出y的值分析本例说明switch语句也可以实现一般的选择结构#includestdio.h__in{doublexy;scanf%lfx;switchx=
0.0{case0:y=-
1.0;break;case1:switchx
0.0{case0:y=
0.0;break;case1:y=
1.0;}}printfy=%.1f\ny;}非00表达式语句if语句下面这条语句非00表达式语句1语句2下一条语句表达式1表达式2表达式3……表达式n-1语句1非00语句2非0语句3非0语句n-1非0000语句ny=-1x00x=01x0。