第4章选择结构程序设计21世纪高等学校精品规划教材掌握关系表达式和逻辑表达式的组成及运算理解选择结构(分支结构)程序设计的概念掌握if语句、switch语句的基本结构及执行过程学会简单的选择结构程序设计4.1关系运算符与关系表达式4.1.1关系运算符关系运算符、=、、===、!=优先级==、!=、=、、=算术运算符结合性左结合abc等价于(ab)ca!=bc等价于a!=(bc)4.1关系运算符与关系表达式关系表达式ab'a'+1!='b'3.1415==3.1416345a=100a994.2逻辑运算符与逻辑表达式4.2.1逻辑运算符逻辑运算符!(逻辑非)、&&(逻辑与)、||(逻辑或)4.2逻辑运算符与逻辑表达式优先级逻辑或运算符(||)逻辑与运算符(&&)关系运算符双目算术运算符(+、-、*、/、%等)逻辑非运算符(!)、单目算术运算符(++、--等)结合性非运算符(!)的结合性为右结合;与运算符(&&)和或运算符(||)的结合性为左结合。【例4-1】分析下面程序段的运行结果#includestdio.hvoidmain(){charc;inta,b;c='A';a=1;b=2;printf(c\'B\'=%d\n,c'B');printf(ab2=%d\n,ab2);}逻辑运算符的“短路”现象若&&运算符左边的表达式为假(或0),则其右边的表达式将不再运算,整个表达式的值必然为假若||运算符左边的表达式为真(或非0值),则其右边的表达式将不再运算,整个表达式的值必然为真35||++b【例4-2】测试短路现象#includestdio.hvoidmain(){inta,b;a=b=0;a||++b;printf(%d,%d\n,a,b);a=b=1;a||++b;printf(%d,%d\n,a,b);a=b=0;a&&++b;printf(%d,%d\n,a,b);a=b=1;a&&++b;printf(%d,%d\n,a,b);}*【例4-3】测试短路现象#includestdio.hintshow(intn,inta){printf((%d,%d),n,a);returna;}voidmain(){inta;a=show(1,1)||show(2,2)&&show(3,3);printf(a=%d\n,a);a=show(1,0)||show(2,0)&&show(3,1);printf(a=%d\n,a);a=show(1,0)||show(2,1)&&show(3,2);printf(a=%d\n,a);}4.3if语句4.3.1单分支if语句if(表达式)语句;【例4-4】从键盘输入一个整数,判断是否是偶数,若是,则输出“Yes”。#includestdio.hvoidmain(){inta;printf(Pleaseinputa:);scanf(%d,&a);if(a%2==0)printf(Yes\n);}4.3if语句4.3.2双分支if语句形式为:if(表达式)语句1;else语句2;【例4-5】从键盘输入一个整数,判断是否是偶数,若是,则输出“Yes”,否则输出“No”#includestdio.hvoidmain(){inta;printf(Pleaseinputa:);scanf(%d,&a);if(a%2==0)printf(Yes\n);elseprintf(No\n);}【例4-6】从键盘输入两个整数,输出其中最大者#includestdio.hvoidmain(){inta,b;printf(Pleaseinputa,b:);scanf(%d,%d,&a,&b);if(ab)printf(max=%d\n,a);elseprintf(max=%d\n,b);}4.3.3多分支选择结构多分支选择结构的if语句一般形式为:if(表达式1)语句1;elseif(表达式2)语句2;…elseif(表达式n)语句n;else语句n+1;【例4-7】输入出租车类型和里程,计算打车的费用。计算方式为:3公里以内8元;3公里以上0车型每公里1.5元,1车型每公里2元。#includestdio.hvoidmain(){inttaxiType;floats;floatmoney;printf(Inputtaxitype(0,1):);scanf(%d,&taxiType);printf(Inputs:);scanf(%f,&s);if(s3)money=8;elseif(taxiType==0)money=8+(s-3)*1.5;elsemoney=8+(s-3)*2;printf(money=%.2f\n,money);}4.3.4if语句的嵌套if(表达式)if(表达式)语句1;else语句2;elseif(表达式)语句3;else语句4;C语言规定else总是和其前面最近的没有else配对的if配对。【例4-8】输入一个正整数作为年份,编程判断该年是不是闰年。若是输出“YES”,否则输出“NO”。【分析】满足下面条件之一即为闰年:能被4整除,但不能被100整除。能被400整除。#includestdio.hvoidmain(){intyear;scanf(%d,&year);if(year%400==0)printf(Yes\n);elseif(year%4==0&&year%100!=0)printf(Yes\n);elseprintf(NO\n);}year%400==0||(year%4==0&&year%100!=0)4.3.5条件运算符和条件表达式?:表达式1?表达式2:表达式3if(xy)max=x;elsemax=y;max=xy?x:y优先级右结合性:ab?a:cd?c:d等价于ab?a:(cd?c:d)【例4-9】用条件运算符输出3个整数中的最大者#includestdio.hvoidmain(){inta,b,c,max;printf(inputa,b,c:);scanf(%d,%d,%d,&a,&b,&c);max=ab?a:b;max=cmax?c:max;printf(max=%d\n,max);}4.4switch语句switch(表达式){case常量表达式1:语句1;case常量表达式2:语句2;…case常量表达式n:语句n;default:语句n+1;}【例4-10】输入一个十进制数,根据输入的数输出所对应的英文星期单词,若所输入的数小于1或大于7,则输出“Error”。#includestdio.hvoidmain(){inta;printf(Inputa:);scanf(%d,&a);switch(a){case1:printf(Monday\n);case2:printf(Tuesday\n);case3:printf(Wednesday\n);case4:printf(Thursday\n);case5:printf(Friday\n);case6:printf(Saturday\n);case7:printf(Sunday\n);default:printf(Error\n);}}4.4switch语句switch(表达式){case常量表达式1:语句1;break;case常量表达式2:语句2;break;…case常量表达式n:语句n;break;default:语句n+1;}修改后的例4-10程序#includestdio.hvoidmain(){inta;printf(Inputa:);scanf(%d,&a);switch(a){case1:printf(Monday\n);break;case2:printf(Tuesday\n);break;case3:printf(Wednesday\n);break;case4:printf(Thursday\n);break;case5:printf(Friday\n);break;case6:printf(Saturday\n);break;case7:printf(Sunday\n);break;default:printf(Error\n);break;}}【注意】switch后跟的“表达式”允许为任何类型的表达式,其数据类型和case后面的常量表达式的数据类型一致。每一个case后的各常量表达式的值不允许重复,否则会报错。每一个case后允许有多条语句,可以不用花括号“{}”括起来。case和default子句出现的先后顺序可以变动,不会影响程序的执行结果。default子句也可以省略不用。多个case可以共用一组执行语句。例如:…case'A':case'B':case'C':printf(Pass\n);break;4.5程序举例【例4-11】输入一个100以内的十进制正整数,判断该数是否包含数字字符“6”。若是输出“Yes!”,否则输出“No!”。#includestdio.hvoidmain(){inta;printf(Inputa:);scanf(%d,&a);if(a==6||(a%10==6||a/10==6))printf(Yes!\n);elseprintf(No!\n);}【例4-12】输入3个数,按从小到大的顺序输出。#includestdio.hvoidmain(){inta,b,c,t;printf(Inputa,b,c:);scanf(%d,%d,%d,&a,&b,&c);if(ab){t=a;a=b;b=t;}if(bc){t=b;b=c;c=t;}if(ab){t=a;a=b;b=t;}printf(%d=%d=%d\n,a,b,c);}【例4-13】将一个百分制的成绩(设是整数)转化成5个等级90分以上为‘A’,80~89分为‘B’,70~79分为‘C’,60~69分为‘D’,60分以下为‘E’。例如,输入75,则显示C。【分析】先判断输入的数据是否在合理的分数范围(0~100)内,然后再判断是哪个分数段:90分以上输出A,80~89分输出B,70~79分输出C,60~69分输出D,否则显示E。【例4-13】将一个百分制的成绩(设是整数)转化成5个等级#includestdio.hvoidmain(){inta;printf(Inputa:);scanf(%d,&a);if(a0||a100)printf(Inputdataerror\n);elseif(a=90)printf(A\n);elseif(a=80)printf(B\n);elseif(a=70)printf(C\n);elseif(a=60)printf(D\n);elseprintf(E\n);}【分析】使用switch语句,当然最笨的办法是每一个分数一个case分支,将需要101个分支,显然这种程序不值得推荐。那么有没有简化的办法呢?其实,任何好的算法都是对问题分析和提炼的结果。题目中60分以上都是每10分一个层次,60分以下是一个层次。只要把每个层次的共性找到就容易找到简化程序的办法了。以60~69为例。每个分数的十位数都是6,对于该层次的成绩,整除10的结果都是6。同样对于70~79、80~89、90~99都是一样。而69分以下的成绩整除10的结果都小于6。【例4-13】将一个百分制的成绩(设是整数)转化成5个等级(用switch语句完成)#includestdio.hvoidmain(){inta;printf(Inputa:);scanf(%d,&a);if(a0||a100)printf(Inputdataerror\n);elseswitch(a/10){case10:case9: