配色: 字号:
第4章选择结构程序设计
2022-05-20 | 阅:  转:  |  分享 
  
4第章选择结构程序设计选择结构和条件判断条件C语言有两种选择语句if语句,用来实现两个分支的选择结构switch语句,用来实现多分支的选择结
构ABif语句例题【例4.1】在例3.5的基础上对程序进行改进。题目要求解得ax2+bx+c=0方程的根。由键盘输入a,b,c。假
设a,b,c的值任意,并不保证b2-4ac≥0。需要在程序中进行判别,如果b2-4ac≥0,就计算并输出方程的两个实根,如果b2-
4ac<0,就输出“此方程无实根”的信息。输入a,b,c计算disc=b2-4acYN#include#incl
ude //程序中要调用求平方根函数sqrtintmain(){ doublea,b,c,disc,x1,x
2,p,q; //disc是判别式sqrt(bb-4ac) scanf("%lf%lf%lf",&a,&b,&c); //输
入双精度浮点型变量的值要用格式声明"%lf" disc=bb-4ac; if(disc<0)//若bb-4ac<0 p
rintf("Thisequationhasn''trealroots\n"); //输出“此方程无实根” else//b
b-4ac≥0 { p=-b/(2.0a); q=sqrt(disc)/(2.0a); x1=p+q;x2=p-q; //求
出方程的两个根 printf("realroots:\nx1=%7.2f\nx2=%7.2f\n",x1,x2); //输出
方程的两个根 } return0;}disc<0计算x1,x2输出“此方程无根”输出x1,x2结束用if语句实现选择结构【例
4.2】输入两个实数,按由小到大的顺序输出这两个数。解题思路:只要做一次比较,然后进行一次交换即可。用if语句实现条件判断。#
includeintmain(){ floata,b,t; scanf("%f,%f",&a,&b); i
f(a>b) {//将a和b的值互换 t=a; a=b; b=t; } printf("%5.2f,%5.2f\n",a,b);
return0;}a=b;//把变量b的值赋给变量a,a的值等于b的值b=a;//再把变量a的值赋给变量b,变量b值没有
改变两个变量值的互换因此,为了实现互换,必须借助于第三个变量用if语句实现选择结构【例4.3】输入3个数a,b,c,要求按由小到大
的顺序输出。#includeintmain(){ floata,b,c,t; scanf("%f,%f,%
f",&a,&b,&c); if(a>b) { t=a; //借助变量t,实现变量a和变量b互换值 a=b; b=t; }//互
换后,a小于或等于b if(a>c) { t=a; //借助变量t,实现变量a和变量c互换值 a=c; c=t; }//互换后,
a小于或等于c if(b>c) //还要 { t=b; //借助变量t,实现变量b和变量c互换值 b=c; c=t; }//互
换后,b小于或等于c printf("%5.2f,%5.2f,%5.2f\n",a,b,c); //顺序输出a,b,c的值 re
turn0;}算法步骤S1:ifa>b,将a和b对换(交换后,a是a、b中的小者)S2:ifa>c,将a和c对换(交换后
,a是a、c中的小者,因此a是三者中最小者)S3:ifb>c,将b和c对换(交换后,b是b、c中的小者,也是三者中次小者)S4
:顺序输出a,b,c在经过第1次互换值后,a≤b,经过第2次互换值后a≤c,这样a已是三者中最小的(或最小者之一),但是b和c谁
大还未解决,还需要进行比较和互换。经过第3次互换值后,a≤b≤c。if语句的一般形式if(表达式)语句1[else语句2
]“表达式”可以是关系表达式、逻辑表达式,甚至是数值表达式方括号内的部分(即else子句)为可选的,既可以有,也可以没有语句1和
语句2可以是一个简单的语句,也可以是一个复合语句,还可以是另一个if语句形式2 有else子句部分形式1 没有else子句部分形式
3 在else部分又嵌套了多层的if语句if(表达式) 语句1else 语句2?if(表达式1) 语句1elseif(表
达式2) 语句2elseif(表达式3) 语句3elseif(表达式m) 语句melse语句m+1if(表达式)
语句1关系运算符和关系表达式在C语言中,比较符(或称比较运算符)称为关系运算符。所谓“关系运算”就是“比较运算”,将两个数值进行比
较,判断其比较的结果是否符合给定的条件。关系运算符及其优先次序高优先级低算术运算符前4种关系运算符的优先级别相同,后2种也相同。前
4种高于后2种。关系运算符的优先级低于算术运算符。关系运算符的优先级高于赋值运算符。1< (小于)2<= (小于等于)关系运算符3
> (大于)4>= (大于等于)c>a+b等效于c>(a+b)(关系运算符的优先级低于算术运算符)a>b==c等效于(a>b)=
=c(大于运算符>的优先级高于相等运算符==)a==b
c等效于a=(b>c)(关系运算符的优先级高于赋值运算符)5== (等于)赋值运算符6!= (不等于)关系表达式用关系运算符将两个
数值或数值表达式连接起来的式子,称为关系表达式。关系表达式的值是一个逻辑值,即“真”或“假”。在C的逻辑运算中,以“1”代表“真”
,以“0”代表“假”。若a=3,b=2,c=1,则:d=a>b,由于a>b为真,因此关系表达式a>b的值为1,所以赋值后d的值为1
。f=a>b>c,则f的值为0。因为“>”运算符是自左至右的结合方向,先执行“a>b”得值为1,再执行关系运算“1>c”,得值0
,赋给f,所以f的值为0逻辑运算符和逻辑表达式用逻辑运算符将关系表达式或其他逻辑量连接起来的式子就是逻辑表达式。逻辑运算符及其优先
次序运算符含义举例说明!逻辑非(NOT)!a如果a为假,则!a为真;如果a为真,则!a为假&&逻辑与(AND)a&&b如果a和
b都为真,则结果为真,否则为假||逻辑或(OR)a||b如果a和b有一个以上为真,则结果为真,二者都为假时,结果为假ab!a!
ba&&ba||b真(非0)真(非0)假(0)假(0)真(1)真(1)真(非0)假(0)假(0)真(1)假(0)真(1)假
(0)真(非0)真(1)假(0)假(0)真(1)假(0)假(0)真(1)真(1)假(0)假(0)“&&”和“‖”是双目运算符,要求
有两个运算对象(操作数);“!”是单目运算符,只要有一个运算对象优先次序:!(非)→&&(与)→‖(或),即“!”为三者中最高
的;逻辑运算符中的“&&”和“‖”低于关系运算符,“!”高于算术运算符逻辑运算结果不是0就是1,不可能是其他数值。而在逻辑表达式
中作为参加逻辑运算的运算对象可以是0(“假”)或任何非0的数值(按“真”对待)在逻辑表达式的求解中,并不是所有的逻辑运算符都被执行
,只是在必须执行下一个逻辑运算符才能求出表达式的解时,才执行该运算符。a&&b&&c。只有a为真(非0)时,才需要判别b的
值。只有当a和b都为真时才需要判别c的值。a‖b‖c。只要a为真(非0),就不必判断b和c。只有a为假,才判别b。a和b都
为假才判别c。逻辑表达式 非0(真) 0(假) 非0(真) 0(假) 非0(真) 0(假)0(假) 1(真) 0(假) 非0
(真) 0(假) 非0(真) 0(假) 非0(真)1(真) 0(假)aabbcc既然关系表达式和逻辑表达式的值是0和1,而且
在判断一个量是否为“真”时,以0代表“假”,以非0代表“真”。那么就可以理解为什么在if语句中表达式可以是任何数值表达式。if(
x!=0)语句1//括号内的表达式是关系表达式,如果x不等于0,执行语句1if(x>0&&y>0)语句2 //表达式是逻
辑表达式,如果x和y都大于0,执行语句2if(x)语句3//表达式是变量,如果x不等于0,则条件判断结果为真,执行语句3if
(1)语句4//表达式是非0整数,条件判断结果为真,执行语句4if(0)语句5//表达式是整数0,条件判断结果为假,不执行
语句5,接着执行下一语句if(x+3.5)语句6//表达式是实数表达式,若x+3.5不等于0,则条件判断结果为真,执行语句6小例
子判别用year表示的某一年是否闰年,可以用一个逻辑表达式来表示。闰年的条件是符合下面二者之一:①能被4整除,但不能被100整除
,如2008。②能被400整除,如2000。(year%4==0&&year%100!=0)‖year%
400==0条件运算符和条件表达式if(a>b) max=a;else max=b;max=(a>b)?a:b
;a>b?(max=a):(max=b);//表达式2和表达式3是赋值表达式或表达式1?表达式2:表达式3真(
非0)假(0)表达式1条件运算符由两个符号(?和:)组成,必须一起使用。要求有3个操作对象,称为三目(元)运算符,它是C语言中唯一
的一个三目运算符。条件运算符的执行顺序:先求解表达式1,若为非0(真)则求解表达式2,此时表达式2的值就作为整个条件表达式的值。
若表达式1的值为0(假),则求解表达式3,表达式3的值就是整个条件表达式的值。条件表达式取表达式2的值条件表达式取表达式3的值条件
运算符和条件表达式【例4.4】输入一个字符,判别它是否为大写字母,如果是,将它转换成小写字母;如果不是,不转换。然后输出最后得
到的字符。解题思路:用条件表达式来处理,当字母是大写时,转换成小写字母,否则不转换。#includeint
main(){ charch; scanf("%c",&ch); ch=(ch>=''A''&&ch<=''Z'')?(ch+32):
ch; printf("%c\n",ch); return0;}条件表达式“(ch>=''A''&&ch<=''Z'')?(ch+32)
:ch”的作用是:如果字符变量ch的值为大写字母,则条件表达式的值为(ch+32),即相应的小写字母,32是小写字母和大写字母A
SCII的差值。如果ch的值不是大写字母,则条件表达式的值为ch,即不进行转换。选择结构的嵌套if与else的配对关系。else总
是与它上面的最近的未配对的if配对。如果if与else的数目不一样,为实现程序设计者的思想,可以加花括号来确定配对关系。注意if(
) if()语句1 else语句2else if()语句3 else语句4内嵌ifif() if() 语句1els
e if() 语句2else 语句3编程序者把else写在与第1个if(外层if)同一列上,意图是使else与第1个if对应,但
实际上else是与第2个if配对,因为它们相距最近。内嵌ifif(){ if() 语句1 内嵌if}else 语句2条件运算符
和条件表达式y10 x-1【例4.5】有一阶跃函数:编一程序,输入一个x值,要求输出相应的y值。?算法步骤算法步骤先后用3
个独立的if语句处理S1:输入xS2:若x<0,则y=-1S3:若x=0,则y=0S4:若x>0,则y=1S5:输出y用一个嵌套
的if语句处理S1:输入xS2:若x<0,则y=-1S3:否则S4:若x=0,则y=0S5:否则(即x>0),则y=1S6:输出
y#includeintmain(){ intx,y; scanf("%d",&x); if(x<0) y
=-1; else if(x==0)y=0; elsey=1; printf("x=%d,y=%d\n",x,y); ret
urn0;}#includeintmain(){ intx,y; scanf("%d",&x); if(
x>=0)// if(x>0)y=1; elsey=0; else y=-1; printf("x=%d,y=%d\
n",x,y); return0;}用switch语句实现多分支选择结构【例4.6】要求按照考试成绩的等级输出百分制分数段,A等
为85分以上,B等为70~84分,C等为60~69分,D等为60分以下。成绩的等级由键盘输入。#include>intmain(){ chargrade; scanf("%c",&grade); printf("Yourscore:"
); switch(grade) { case''A'':printf("85~100\n");break; case''B'':
printf("70~84\n");break; case''C'':printf("60~69\n");break; case
''D'':printf("<60\n");break; default:printf("enterdataerror!\n
"); } return0;}等级grade定义为字符变量,从键盘输入一个大写字母,赋给变量grade,switch得到grad
e的值并把它和各case中给定的值(′A′,′B′,′C′,′D′之一)相比较,如果和其中之一相同(称为匹配),则执行该case后
面的语句(即printf语句)。如果输入的字符与′A′,′B′,′C′,′D′都不相同,就执行default后面的语句,注意在每个
case后面后的语句中,最后都有一个break语句,它的作用是使流程转到switch语句的末尾(即右花括号处)。用switch语句
实现多分支选择结构?switch(表达式){case 常量1:语句1case 常量2:语句2 case 常量n:语
句ndefault:语句n+1}(1)括号内的“表达式”,其值的类型应为整数类型(包括字符型)。(2)花括号内是一个复合语句
,内包含多个以关键字case开头的语句行和最多一个以default开头的行。case后面跟一个常量(或常量表达式),它们和defa
ult都是起标号作用,用来标志一个位置。执行switch语句时,先计算switch后面的“表达式”的值,然后将它与各case标号比
较,如果与某一个case标号中的常量相同,流程就转到此case标号后面的语句。如果没有与switch表达式相匹配的case常量,流
程转去执行default标号后面的语句。(3)可以没有default标号,此时如果没有与switch表达式相匹配的case常量,
则不执行任何语句。(4)各个case标号出现次序不影响执行结果。(5)每一个case常量必须互不相同;否则就会出现互相矛盾的现
象。(6)case标号只起标记的作用。在执行switch语句时,根据switch表达式的值找到匹配的入口标号,在执行完一个cas
e标号后面的语句后,就从此标号开始执行下去,不再进行判断。因此,一般情况下,在执行一个case子句后,应当用break语句使流程跳
出switch结构。最后一个case子句(今为default子句)中可不加break语句。(7)在case子句中虽然包含了一个以
上执行语句,但可以不必用花括号括起来,会自动顺序执行本case标号后面所有的语句。当然加上花括号也可以。(8)多个case标号可
以共用一组执行语句。用switch语句实现多分支选择结构【例4.7】用switch语句处理菜单命令。在许多应用程序中,用菜单对流程
进行控制,例如从键盘输入一个′A′或′a′字符,就会执行A操作,输入一个′B′或′b′字符,就会执行B操作。#includetdio.h>intmain(){ voidaction1(int,int),action2(int,int); //函数声明
charch; inta=15,b=23; ch=getchar(); switch(ch) { case''a'': ca
se''A'':action1(a,b);break; //调用action1函数,执行A操作 case''b'': case''
B'':action2(a,b);break; //调用action2函数,执行B操作 default:putchar(
''\a'');//如果输入其他字符,发出警告 } return0;}?voidaction1(intx,inty) //执
行加法的函数{ printf("x+y=%d\n",x+y);}voidaction2(intx,inty) //执行乘法
的函数{ printf("xy=%d\n",xy);}选择结构程序综合举例#includeintmain
() { intyear,leap; printf("enteryear:"); scanf("%d",&year); if(
year%4==0) { if(year%100==0) { if(year%400==0) leap=1; else leap=
0; } else leap=1; } else leap=0; if(leap) printf("%dis",year);
else printf("%disnot",year); printf("aleapyear.\n"); return
0;}【例4.8】写一程序,判断某一年是否为闰年。year被4整除真假真假leap=0真假leap=1leap=1leap=0真l
eap假输出“闰年”输出“非闰年”year被100整除 if(year%4!=0) leap=0; elseif(year%1
00!=0) leap=1; elseif(year%400!=0) leap=0; else leap=1;year被400整
除 if((year%4==0&&year%100!=0)||(year%400==0))leap=1; elsele
ap=0;选择结构程序综合举例#include#includeintmain(){ dou
blea,b,c,disc,x1,x2,realpart,imagpart; scanf("%lf,%lf,%lf",&a,&b
,&c); printf("Theequation"); if(fabs(a)<=1e-6) printf("isnota
quadratic\n"); else { disc=bb-4ac; if(fabs(disc)<=1e-6) print
f("hastwoequalroots:%8.4f\n",-b/(2a)); else if(disc>1e-6) { x
1=(-b+sqrt(disc))/(2a); x2=(-b-sqrt(disc))/(2a); printf("hasdi
stinctrealroots:%8.4fand%8.4f\n",x1,x2); } else { realpart=-b
/(2a); //realpart是复根的实部 imagpart=sqrt(-disc)/(2a); //imagpart
是复根的虚部 printf("hascomplexroots:\n"); printf("%8.4f+%8.4fi\n",re
alpart,imagpart); //输出一个复数 printf("%8.4f-%8.4fi\n",realpart,imagp
art); //输出另一个复数 } } return0;}【例4.9】求ax2+bx+c=0方程的解。输入a,b,cTa=0F
输出不是“二次方程”Tb2-4ac=0F计算和输出两个相等的实根TF计算和输出两个不等实根计算和输出两个共轭复根b2-4ac>0
选择结构程序综合举例#includeintmain(){ intc,s; floatp,w,d,f;
printf("pleaseenterprice,weight,discount:");//提示输入的数据 scanf("%
f,%f,%d",&p,&w,&s); //输入单价、重量、距离 if(s>=3000)c=12;//3000km以上为
同一折扣 elsec=s/250;//3000km以下各段折扣不同,c的值不相同 switch(c) { case0:d=0;break;//c=0,代表250km以下,折扣d=0 case1:d=2;break;//c=1,代表250~500km以下,折扣d=2% case2: case3:d=5;break;//c=2和3,代表500~1000km,折扣d=5% case4: case5: case6: case7:d=8;break;//c=4~7,代表1000~2000km,折扣d=8% case8: case9: case10: case11:d=10;break; //c=8~11,代表2000~3000km,折扣d=10% case12:d=15;break; //c12,代表3000km以上,折扣d=15% } f=pws(1-d/100);//计算总运费 printf("freight=%10.2f\n",f); //输出总运费,取两位小数 return0;}【例4.10】运输公司对用户计算运输费用。路程越远,运费越低。标准如下:s<250没有折扣250≤s<5002%折扣500≤s<10005%折扣1000≤s<20008%折扣2000≤s<300010%折扣3000≤s15%折扣p:每吨每千米货物的基本运费w:货物重量s:运输距离d:折扣f:总运费f=pws(1-d)
献花(0)
+1
(本文系太好学原创)