计算机C语言-第五章(附上机问题汇总).ppt
答疑时间,每周三下午2:30-5:30信息中心810自愿,第5章 选择结构程序设计选择结构是三种基本结构之一,特点是:根据给定条件:成立时执行一组操作,不成立时执行另一组操作。C中选择结构利用if语句实现。5.1 关系运算符和关系表达式 关系运算是比较运算,结果为逻辑值“真”或“假”。(前已讨论算术、赋值、逗号。现讨论关系、逻辑表达式、条件,前两者的值域为真或假,即1或0)。5.1.1 关系运算符及其优先级 关系运算符有6种:、=:优先级为6级=、!=:优先级为7级 结合性为从左到右,关系运算符和其它运算符优先级的比较:高 逻辑运算符:!(2)算术运算符:*、/、%(3)+、-(4)关系运算符:、=(6)=、!=(7)逻辑运算符:&(11)|(12)低 赋值运算符:=、+=、-=、*=、/=、%=(14)由于存在优先级,因此下面表达式是等价的:,关系表达式关系表达式:用关系运算符将两个表达式(算术、关系、逻辑、赋值、字符)连接起来的式子。如:a b、a+b b+c、(a=3)(b=5)a b)(c b 真 a b=c 真 b+c b d的为1 f=a b c f 值为0思考:能否用一般意义的2x 8?返回,5.2 逻辑运算符和逻辑表达式逻辑表达式:用逻辑运算符将表达式连接起来的式子。4.2.1 逻辑运算符及其优先次序在 c 语言中,逻辑运算符有:1.逻辑与:&优先级11 2.逻辑或:|优先级12 3.逻辑非:!优先级2,有如下逻辑表达式:a&b:当 a,b 都为真时,结果为真,否则结果为假 a|b:当 a,b 都为假时,结果为假,否则结果为真!a:当 a 为真时,结果为假,当a为假时,结果为 真。见表5.1,在一个逻辑表达式中,若包含多个逻辑运算符时,则运算顺序按运算符优先级的高低进行。如:下面表达式是逻辑还是关系表达式?所以(ab)&(xy)可写成ab&xy(a=b)|(x=y)可写成a=b|x=y(!a)|(ab)可写成!a|ab,5.2.2 逻辑表达式 在逻辑表达式中参加运算的数据可以是常量、变量、表达式。见P89下及表5.2例:T5-0-1.cmain()int a=-5,i,j,k,l,m;float b=0.01;i=!a;j=a&b;k=a|b;l=(5 3&2|8 9;printf(“i=%d,j=%d,k=%d,l=%d,m=%dn”,i,j,k,l,m);,运行结果:i=0,j=1,k=1,l=1,m=0,在逻辑表达式求解过程中,所有逻辑运算符并不一定都被执行。只有在必须执行下一个逻辑运算符才能求出表达式的解时,才执行该运算符。1.逻辑与运算符:&如有逻辑表达式:a&b&c执行过程是:当a为0时,b和c不用再判断了,逻辑与运算符将不再执行,结果为0,否则还要继续后边的运算。,2.逻辑或运算符:|如有逻辑表达式:a|b|c执行过程是:当a为非0时,b和c不用再判断了,逻辑或运算符将不再执行,其结果为1,否则继续执行后面的运算。,例:T5-0-2.cmain()int a,b=0,c=0,d=0;scanf(“%d”,例T5-0-3.cmain()int a,b=0,c=0,d=0;scanf(“%d”,在C中,巧妙地使用逻辑表达式,可以表示一个复杂的问题如:关于闰年问题:符合下列条件之一,均为闰年。(1)能被4整除并且不能被100整除(2)能被4整除并且能被400整除其逻辑表达式为:(year%4=0&year%100!=0)|(year%400=0&year%4=0)由于能被400 整除的年份一定能被4 整除,所以可省去了后一部分,即:(year%4=0&year%100!=0)|(year%400=0)若判断非闰年,只在闰年表达式前加!即:!(year%4=0&year%100!=0)|(year%400=0),5.3 if 语句选择结构中使用的一种语句。根据给定的条件判别是否满足,以决定执行哪种操作。5.3.1 if 语句的三种形式1.第一种形式的条件语句if(表达式)语句 表达式一般为逻辑或关系,先对其求值,根据结果决定下一步该如何执行,但也可以是常量、变量、各种表达式。其类型可以是整、实、字符型。语句可以是一句或复合语句.。,例T5-0-4.cmain()int x=0;float y=-5.6;if(x)printf(“x=%dn”,x);if(y)printf(“y=%fn”,y);if(0)printf(“0=%dn”,0);if(xy)printf(“x-y=%fn”,x-y);if(y-100)x+;y+;printf(“x=%d,y=%fn”,x,y);,运行结果:y=-5.6000000=48x-y=5.600000 x=1,y=-4.600000,2.第二种形式的条件语句if(表达式)语句1 else 语句2例T5-0-5.cmain()int x,y;printf(“please input x,yn”);scanf(“%d%d”,运行结果:please input x,y 2 _ 5 输出:y=5 34 _ 28 x=34,3.第三种形式的条件语句 if(表达式1)语句1 else if(表达式2)语句2 else if(表达式3)语句3 else if(表达式m)语句m else 语句 n右图为:m=4n=5,例:商店售货按购物的款数分别给予不同的优惠折扣。设变量:n:购物金额,c:优惠折扣百分比,a:优惠后的实际款数T5-0-6.cmain()float n,c,a;scanf(“%f”,输入:输出:800 680.000000480 432.000000200 185.00000080 76.00000030 30.000000,说明:1.执行if语句时,先判断表达式的值,为真时(非0),执行其后语句,为假(0)时不执行其后的语句,表达式可以是常量、变量、各种表达式。2.if的各内嵌语句用“;”号结束,但仍然是一个语句而非2个。3.if和else后面的内嵌语句若有多句,用 括起构成复合语句。例T5-1.c 输入两个实数,按代数值由小到大输出。main()float a,b,t;scanf(“%f,%f”,输入:输出:3.6,-3.2-3.20,3.602.5,8.9 2.50,8.90,例T5-2.c输入三个数,按从小到大的顺序输出(请同学们自己思考)main()float a,b,c,t;scanf(“%f,%f,%f”,t a b c 7 5 3 5 7 3 3 7 57 3 5 7,输入:输出:7,5,3 3.00,5.00,7.001,8,6 1.00,6.00,8.00,5.3.2 if 语句的嵌套嵌套:在if语句中,又包含1到多个if 语句一般形式:if()if()语句1 else 语句2 else if()语句3 else 语句4,总体上是哪种形式?,使用内嵌的if语句时,应区分表面形式与实际对应关系如:if()if()语句1 else if()语句2 else 语句3编程者希望把中间的else与第一行的if匹配,虽然书写上是对齐的,但编译系统并非如此执行(总体上是形式几?几层嵌套?)。,在C语言中,if与else 的配对原则是:从最内层开始,else总是与它上面最近的,未曾配对的if配对。因此,上述问题在编译时的真正效果是:if()等价于下述表示:当条件成立时执行下面虚框中的内容,总体上是哪种形式?嵌套的是形式几?,为了使程序清晰,不至出错,采取的方法是:(1)使内嵌的if也包含else,如上面的问题可进行如下描述:if()if()else else if()else.,(2)若if和else数目不等,为实现设计者的企图,可用 实现,如上述问题可进行如下描述:if()if()语句1 else if()语句2 else 语句3,如此一来,else不是和复合语句匹配而是与其前面的if匹配,总体上是哪种形式?去掉后属于哪种形式?,有一符号函数 例T5-3.cmain()int x,y;scanf(“%d”,输入:-1234 0 756 输出:x=-1234,y=-1 x=0,y=0 x=756,y=1,例T5-3-1.cmain()int x,y;scanf(“%d”,输入:12-24 0 输出:x=12,y=1 x=-24,y=-1 x=0,y=0,例T5-3-2.cmain()int x,y;scanf(%d”,怎么改?,输入:输出:-5 x=-5,y=0 0 x=0,y=-1 8 x=8,y=1,例T5-3-3.c(请同学们自己思考)main()int x,y;scanf(%d”,输入:输出:-5 x=-5,y=00 x=0,y=-18 x=8,y=1,5.3.3 条件运算符有时,在判断了if后的表达式以后,都执行一个赋值表达式且给同一个变量赋值,如max条件表达式的一般形式:其中:?:是条件运算符号,是唯一的3目运算符max=(ab)?a:b;,(表达式1)?(表达式2):(表达式3),条件表达式的执行过程是:,x=(ab)?a:b 当 a=9,b=5时,x=9,说明如下几点:,max=a b?a:b(思考:这是一个什么表达式?)1.条件运算符?:的优先级为13级 max=(a b)?a:b max=a b?a:b(=为14级)max=a b?a:(b+1)max=ab?a:b+1(+为4级),总结:条件运算符的优先级 高于赋值,低于其他,2.条件运算符的结合方向:从右向左如有表达式:a b?a:c d?c:da,b,c,d的取值如下:表达式值如下:a b c d 1 2 3 4 45 8 6 2 63 2 20 30 3,if(y0)x=-y;elsex=y;,(y0)?x=-y:x=y;,等价,等价,x=(y0)?-y:y;,说明:if else可以完成与条件 运算符(?:)完全相同 的任务,并且可以进行 相应的转换。,3.若if语句内嵌的是赋值语句,且两分支给同一变量赋值时,才可用条件表达式代替 但if(a b)printf(“%d”,a);else printf(“%d”,b)可写成 Printf(“%d”,a b?a:b);,条件运算要求有三个运算分量,并且不论条件是否成立,都必须是为同一个变量赋值,再一个例子,main()int a,b;scanf(“%d%d”,输入:3 5 输出:max=5友情提示:表达式2,3还可以是一个函数,表达式1一般为逻辑或关系,但也可以是其他的,如算术,如将ab换成3,总结一下,if(cans=1)printf(”You need 1 can of paint.”);else printf(”You need 2 cans of paint.”);,条件运算符的形式比较简单,有较强的灵活性,可以替代部分if语句。,例,转换:(cans=1)?printf(”You need 1 can of paint.”):printf(”You need 2 cans of paint.”);,转换:printf(cans=1?”You need 1 can of paint.”:”You need 2 cans of paint.”);,main()int x=-1,y=5,z=6;printf(“%cn”,x?a:b);printf(“%f n”,yz?1:1.5);思考一下:是这样的吗?,输出:a 1,友情提示:数据类型可以不同,低类型向高类型转换,例T5-4.c 输入一字符,若是大写字母,则将其转换为小写字母main()char ch;scanf(“%c”,A的ASCII码值是65 Z的ASCII码值是90去看看,输入:A 输出:a a a,输入其它字符输出的是什么?,如1,看个例子:假设用0、1、2.6分别表示星期日、星期一.星期六。现输入一个数字,输出对应的星期几的英文单词。如果输入3,输出“Wednesday”。,main()int n;scanf(%d,再去看看规范,程序运行情况如下:3Wednesday ThursdayFridaySaturdayerror,switch语句,1、语句形式:,switch(表达式)case 常量1:语句1;case 常量2:语句2;case 常量3:语句3;.case 常量n:语句n;default:语句n+1;继续,根据表达式的不同值,选择不同的程序分支,又称开关语句。,数值型或字符型,常量表达式的值必须互不相同,否则执行时将出现矛盾,即同一个开关值,将对应多种执行方案。,再去看看那个例子,将上面的例4-4修改如下:,main()int n;scanf(%d,程序运行情况如下:3Wednesday,常用的,switch(表达式)case E1:语句组 1;break;case E2:语句组 2;break;.case En:语句组 n;break;default:语句组n+1;break;,2、语句执行流程:,指语句的最后一条是否为break,简单语句或复合语句,case语句出现的次序并不影响执行结果。,3、说明,多个case语句可以共用一组执行语句。,switch(grade)case A:case B:case C:printf(grade=60n);break;default:printf(“grade60”);/*这里可以不必加break*/,各case后如果有多个语句,可以不必加,当然,加上也可以,case和default与其后面的常量表达式间至少有一个空格。,Switch能实现的结构用if一定能实现,但反之未必,switch语句可以嵌套,break语句只跳出它所在的switch语句。,企业发放的奖金根据利润提成。从键盘输入当月利润,求应发放奖金总数?,利润xx=1010 x2020 x4040 x6060 x100100 x,(int)x/10取整,常量0,11,22,3,44,5,66,7,8,9,1010以上,用这种方法转换后,n出现了在不同区域有重复数字的情况。解决的方法有很多,其中一种是可以采用当x为10的整数倍时,将计算出的n值减1。,使用switch解题的关键,通过分析找到表达式,将问题分成几种情况。,#include stdio.hvoid main()float x,y;int n;scanf(%f,程序如下:,5.5 程序举例(留给同学们自己思考)例T5-5 判某年是否是闰年main()int year,leap;scanf(“%d”,输入:1999 2000 1972 输出:1999 is not a leap year 2000 is a leap year1972 is a leap year,例T5-6.c 求ax2+bx+c=0 方程的解几种可能的情况:a=0:不是二次方程;b2-4ac=0:有两个相等的实根 b2-4ac0:有两个不等的实根 b2-4ac 0:有两个共轭复根,X1,2=,T5-6.c#inlude“math.h”main()float a,b,c,disc,x1,x2,re,im;scanf(“%f,%f,%f”,输入:0,2,1 1,2,1 2,6,1 1,2,2 输出:The equation is not quadraticThe equation has two equal roots:-1.0000The equation has distinct real roots:-0.1771 and-2.8229The equation has complex roots:-1.0000+1.0000 i-1.0000-1.0000 i,例T5-7.c 运输费的计算 设:s:距离 w:货物重量 d:折扣 p:基本运费 f:总运费 f=p*w*s*(1-d)s=3000 15%折扣,T5-7.cmain()int c,s;float p,w,d,f;scanf(“%f,%f,%d”,C:公里数/250,以确定表达式的值s:距离p:基本运费w:货物重量d:折扣总运费f:p*w*s*(1-d),输入:100,20,300 输出:freight=_ _ _588000.0000,s250km 没有折扣 250=s500 2%折扣 500=s1000 5%折扣 1000=s2000 8%折扣 2000=s3000 10%折扣3000=s 15%折扣,任意输入三个数,判断能否构成三角形?若能构成三角形,是等边三角形、等腰三角形还是其它三角形?,#include stdio.hvoid main()float a,b,c;scanf(%f,%f,%f,(回顾一下,这是第几类的if语句?),课堂练习,程序填空:以下程序判断输入的整数能否被3或7整除.main()int x,f=0;scanf(“%d”,家庭作业,课后练习,上机以后的问题汇总,1、复合语句后不需要再加;号了2、有同学提出幻灯P38,为何不做表达式3,还是会自动向高类型转换?main()int a,b=1;a=1;1?a+:+b;printf(%d,%d,a,b);2 1/*可见确实是没做表达式3*/因为:类型转换是在编译的时候做的而非在运行时,只有运行再决定只做表达式几,而编译的时候是不知道最后到底做表达式几,而编译时有个很重要的工作就是要准备好空房间,所以只能尽量准备大房间,因此一定要低类型向高类型转换,继续,3、%e double型的依旧是指数占4列而非5列?4、|键 输入 在上面5、习题4.7 注意Aa之间不能空格,否则会将空格当成字符读入6、变量定义一定要在最前面都定义完,不能想用的时候就在程序当前位置定义7、printf(“%s”,”china/n”),字符串常量里也能加入转义字符8、问个问题(i+)+(i+)+(i+);3 3 3i+,i+,i+;3 4 5,最后再来一个例子,计算1+2+3+4+5 int sum=a=1,i=2;if i=2 sum=sum+i;i+;;if i=3 sum=sum+i;i+;;if i=4 sum=sum+i;i+;;if i=5 sum=sum+i;i+;;,