1、5.1关系运算符和关系表达式关系运算符和关系表达式5.2逻辑运算符和逻辑表达式逻辑运算符和逻辑表达式5.3if语句语句5.4switch语句语句5.5程序举例程序举例习题习题第第5 5章章 选择结构程序设计选择结构程序设计在第在第3章中已介绍了选择结构,它是三种基本章中已介绍了选择结构,它是三种基本结构之一。在大多数程序中都会包含选择结结构之一。在大多数程序中都会包含选择结构。它的作用是,根据所指定的条件是否满构。它的作用是,根据所指定的条件是否满足,决定从给定的两组操作选择其一。在本足,决定从给定的两组操作选择其一。在本章中介绍如何用章中介绍如何用c语言实现选择结构。在语言实现选择结构。在c
2、语语言中选择结构是用言中选择结构是用if语句实现的。语句实现的。if语句最常语句最常用的形式是用的形式是if(关系表达式关系表达式)语句语句1 else 语句语句2例如:例如:if(x0)y=1;else y=-1;其中其中x0是一个关系表达式。是一个关系表达式。“”是一个关系是一个关系运算符。运算符。5.1 关系运算符和关系表达式关系运算符和关系表达式关系运算是逻辑运算中比较简单的一种。所谓关系运算是逻辑运算中比较简单的一种。所谓“关关系运算系运算”实际上是实际上是“比较运算比较运算”。将两个值进行比。将两个值进行比较,判断其比较的结果是否符合给定的条件。例如,较,判断其比较的结果是否符合给
3、定的条件。例如,a3是一个关系表达式,大于号是一个关系表达式,大于号()是一个关系运是一个关系运算符,如果算符,如果a的值为的值为5,则满足给定的,则满足给定的“a3”条件,条件,因此关系表达式的值为因此关系表达式的值为“真真”(即即“条件满足条件满足”);如果如果a的值为的值为2,不满足,不满足“a3”条件,则称关系表条件,则称关系表达式的值为达式的值为“假假”。5.1.1 关系运算符及其优先次序关系运算符及其优先次序C语言提供语言提供6种关系运算符:种关系运算符:优先级相同优先级相同(高高):(小于小于)=(小于或等于小于或等于)(大于大于)=(大于或等于大于或等于)优先级相同优先级相同(
4、低低):=(等于等于)!=(不等于不等于)关于优先次序:关于优先次序:(1)前前4种关系运算符种关系运算符(,=,=)的优先级别相同,后的优先级别相同,后两种也相同。前两种也相同。前4种高于后种高于后2种。例如,种。例如,“”优先于优先于“=”。而而“”与与“”优先级相同。优先级相同。(2)关系运算符的优先级低于算术运关系运算符的优先级低于算术运算符。算符。(3)关系运算符的优先级高于赋值运关系运算符的优先级高于赋值运算符。算符。以上关系见图以上关系见图5.1。例如:例如:cab等效于等效于 c(ab)ab=c 等效于等效于(ab)=c a=bc 等效于等效于a=(bc)a=bc 等效于等效于
5、a=(bc)图图5.15.1.2 关系表达式关系表达式用关系运算符将两个表达式用关系运算符将两个表达式(可以是算术表达式或关可以是算术表达式或关系表达式、逻辑表达式、赋值表达系表达式、逻辑表达式、赋值表达式、字符表达式式、字符表达式)连接起来的式子,称关系表达式。连接起来的式子,称关系表达式。例如,下面都是合法的关系表达式:例如,下面都是合法的关系表达式:ab,abbc,(a=3)(b=5),ab,(ab)(bc)关系表达式的值是一个逻辑值,即关系表达式的值是一个逻辑值,即“真真”或或“假假”。例如,关系表达式。例如,关系表达式“5=3”的值为的值为“假假”,“5=0”的值为的值为“真真”。c
6、语言没有逻辑型数据语言没有逻辑型数据(Pascal语言以语言以True表示表示“真真”,以,以false表示表示“假假”。PascaL和和FORTRAN等语言都有逻辑型等语言都有逻辑型变量和逻辑型常变量和逻辑型常量量),以,以1代表代表“真真”,以,以“0”代表代表“假假”。例如,。例如,a=3,b=2,c=1,则:,则:关系表达式关系表达式“ab”的值为的值为“真真”,表达式的值为,表达式的值为1。关系表达式关系表达式“(ab)=c”的值为的值为“真真”(因为因为ab的的值为值为1,等于,等于c的值的值),表达式的值为,表达式的值为1。关系表达式关系表达式“bca”的值为的值为“假假”,表达
7、式的值,表达式的值为为0。如果有以下赋值表达式:如果有以下赋值表达式:d=abd的值为的值为1。f=abcf的值为的值为0(因为因为“”运算符是自左至右运算符是自左至右的结合方向,先执行的结合方向,先执行“ab”得值为得值为1,再执行关再执行关系运算系运算“1c”,得值,得值0,赋给,赋给f)。用逻辑运算符将关系表达式或逻辑量连接起来用逻辑运算符将关系表达式或逻辑量连接起来的式子就是逻辑表达式。在的式子就是逻辑表达式。在basic和和Pascal语言语言中有以下形式的逻辑表达式中有以下形式的逻辑表达式(AND是逻辑运算是逻辑运算符符):(ab)AND(xy)如果如果ab且且xy,则上述逻辑表达
8、式的值为,则上述逻辑表达式的值为“真真”。下面介绍。下面介绍c语言中的逻辑运算符和逻语言中的逻辑运算符和逻辑运算。辑运算。5.2.1 逻辑运算符及其优先次序逻辑运算符及其优先次序C语言提供三种逻辑运算符:语言提供三种逻辑运算符:5.2 逻辑运算符和逻辑表达式逻辑运算符和逻辑表达式(1)&逻辑与逻辑与(相当于其他语言中的相当于其他语言中的aND)(2)|逻辑或逻辑或(相当于其他语言中的相当于其他语言中的)(3)!逻辑非逻辑非(相当于其他语言中的相当于其他语言中的NT)“&”和和“|”是是“双目双目(元元)运算符运算符”,它要求有两个,它要求有两个运算量运算量(操作数操作数),如,如(ab)&(x
9、y),(ab)|(xy)。“!”是是“一目一目(元元)运算符运算符”,只要求有一个运,只要求有一个运算量,如算量,如(ab)。逻辑运算举例如下:逻辑运算举例如下:a&b若若a、b为真,则为真,则a&b为真。为真。a|b 若若a、b之一为真,则之一为真,则a|b为真。为真。!a 若若a为真,则为真,则!a为假。为假。在一个逻辑表达式中如果包含多个逻辑运算符,如在一个逻辑表达式中如果包含多个逻辑运算符,如!a&b|xy&c按以下的优先次序:按以下的优先次序:(1)!(非非)&(与与)(或或),即即“!”为三者中最高的。为三者中最高的。(2)逻辑运算符中的逻辑运算符中的“&”和和“|”低于关系运算符
10、,低于关系运算符,“!”高于算术运算符。见图高于算术运算符。见图5.2。图图5.2例如:例如:(ab)&(xy)可写成可写成ab&xy (a=b)|(x=y)可写成可写成a=b|x=y (!a)|(ab)可写成可写成!a|ab5.2.2 逻辑表达式逻辑表达式如前所述,逻辑表达式的值应该是一个逻辑量如前所述,逻辑表达式的值应该是一个逻辑量“真真”或或“假假”。c语言编译系统在给出逻辑运算结果时,语言编译系统在给出逻辑运算结果时,以数值以数值1代表代表“真真”,以,以0代表代表“假假”,但在判断,但在判断一个量是否为一个量是否为“真真”时,以时,以0代表代表“假假”,以非,以非0代表代表“真真”。
11、即将一个非零的数值认作为。即将一个非零的数值认作为“真真”。例如:例如:(1)若若a=4,则,则!a的值为的值为0。因为。因为a的值为非的值为非0,被认作,被认作“真真”,对它进行,对它进行“非非”运算,得运算,得“假假”,“假假”以以0代表。代表。(2)若若a=4,b=5,则,则a&b的值为的值为1。因为。因为a和和b均为均为非非0,被认为是,被认为是“真真”,因此,因此a&b的值也为的值也为“真真”,值为,值为1。(3)a、b值同前,值同前,a|b的值为的值为1。(4)a、b值同前,值同前,!a|b的值为的值为1。(5)4&0|2的值为的值为1。通过这几个例子可以看出,由系统给出的逻辑运算
12、通过这几个例子可以看出,由系统给出的逻辑运算结果不是结果不是0就是就是1,不可能是其他数值。而在逻辑,不可能是其他数值。而在逻辑表达式中作为参加逻辑运算的运算对象表达式中作为参加逻辑运算的运算对象(操作数操作数)可以是可以是0(“假假”)或任何非或任何非0的数值的数值(按按“真真”对待对待)。如。如果在一个表达式中不同位置上出现数值,应区分哪些果在一个表达式中不同位置上出现数值,应区分哪些是作为数值运算或关系运算的对象,哪些作为逻辑运是作为数值运算或关系运算的对象,哪些作为逻辑运算的对象。例如算的对象。例如:53&84-!0表达式自左至右扫描求解。首先处理表达式自左至右扫描求解。首先处理“53
13、”(因为关系因为关系运算符优先于运算符优先于&)。在关系运算符两侧的。在关系运算符两侧的5和和3作为数作为数值参加关系运算,值参加关系运算,“53”的值为的值为1。再进行。再进行“1&84-!0”的运算,的运算,8的左侧为的左侧为“&”,右侧为,右侧为“”运算符,根据优先规则,应先进行运算符,根据优先规则,应先进行“”的运算,即先的运算,即先进行进行“84-!0”的运算。现在的运算。现在4的左侧为的左侧为“”,右侧为,右侧为“-”运算符,而运算符,而“-”优先于优先于“”,因此应先进行,因此应先进行“4-!0”的运算,由于的运算,由于“!”的级别最高,因此先进行的级别最高,因此先进行“!0”的
14、运的运算,得到结果算,得到结果1。然后进行。然后进行“4-1”的运算,得结果的运算,得结果3,再进行再进行“8500)cost=0.15;else if(number300)cost=0.10;else if(number100)cost=0.075;else if(number50)cost=0.05;elsecost=0;说明:说明:(1)三种形式的三种形式的if语句中在语句中在if后面都有后面都有“表达式表达式”,一般为逻,一般为逻辑表达式或关系表达式。例如,辑表达式或关系表达式。例如,if(a=b&x=y)printf(“a=b,x=y”);在执行;在执行if语句时先对表达式求解,语句
15、时先对表达式求解,若表达式的值为若表达式的值为0,按,按“假假”处理,若表达式的值为非处理,若表达式的值为非0,按按“真真”处理,执行指定的语句。假如有以下处理,执行指定的语句。假如有以下if语句:语句:if(3)printf(k);是合法的,执行结果输出是合法的,执行结果输出“k”,因为表达式,因为表达式的值为的值为3,按,按“真真”处理。由此可见,表达式的类处理。由此可见,表达式的类型不限于逻辑表达式,可以是任意的数值类型型不限于逻辑表达式,可以是任意的数值类型(包包括整型、实型、字符型、指针型数据括整型、实型、字符型、指针型数据)。例如,下。例如,下面的面的if语句也是合法的:语句也是合
16、法的:if(a)printf(d,a);执行结果:输出执行结果:输出a的的ASCII码码97。(2)第二、第三种形式的第二、第三种形式的if语句中,在每个语句中,在每个else前面有前面有一分号,整个语句结束处有一分号。例如:一分号,整个语句结束处有一分号。例如:if(x0)Print(%f,x);else 各有一个分号各有一个分号printf(%f,-x);这是由于分号是这是由于分号是c语句中不可缺少的部分,这个分号语句中不可缺少的部分,这个分号是是if语句中的内嵌语句所要求的。如果无此分号,语句中的内嵌语句所要求的。如果无此分号,则出现语法错误。但应注意,不要误认为上面是两则出现语法错误。
17、但应注意,不要误认为上面是两个语句个语句(if语句和语句和else语句语句)。它们都属于同一个。它们都属于同一个if语语句。句。else子句不能作为语句单独使用,它必须是子句不能作为语句单独使用,它必须是if语句的一部分,与语句的一部分,与if配对使用。配对使用。(3)在在if和和else后面可以只含一个内嵌的操作语句后面可以只含一个内嵌的操作语句(如如上例上例),也可以有多个操作语句,此时用花括号,也可以有多个操作语句,此时用花括号“”将几个语句括起来成为一个复合语句。将几个语句括起来成为一个复合语句。如:如:if(abc&bca&cab)s=0.5*(a+b+c);area=sqrt(S*
18、(S-a)*(S-b)*(S-c);printf(area=62f,area);else printf(it is not a trilateral);注意在第注意在第3行的花括号行的花括号“”外面不需要再加分号。外面不需要再加分号。因为内是一个完整的复合语句,不需另附加因为内是一个完整的复合语句,不需另附加分号。分号。例例5.1输入两个实数,按代数值由小到大的次序输出输入两个实数,按代数值由小到大的次序输出这两个数。这两个数。这个问题的算法很简单,只需要作一次比较即可。这个问题的算法很简单,只需要作一次比较即可。对类似这样简单的问题可以不必先写出算法或画对类似这样简单的问题可以不必先写出算法
19、或画流程图,而直接编写程序。或者说,算法在编程流程图,而直接编写程序。或者说,算法在编程者的脑子里,相当于在算术运算中对简单的问题者的脑子里,相当于在算术运算中对简单的问题可以可以“心算心算”而不必在纸上写出来一样。而不必在纸上写出来一样。程序如下:程序如下:main()float a,b,t;scanf(f,f,&a,&b);if(ab)t=a;a=b;b=t;printf(52f,52f,a,b);运行情况如下:运行情况如下:3.6,-3.2 -3.20,3.60例例5.2输入输入3个数个数a,b,c,要求按由小到大的顺序输,要求按由小到大的顺序输出。解此题的算法比上一题稍复杂一些。可以用
20、出。解此题的算法比上一题稍复杂一些。可以用伪代码写出算法:伪代码写出算法:if a b 将将a和和b对换对换 (a是是a,b中的小者中的小者)if a c 将将a和和c对换对换 (a是是a,c中的小者,因中的小者,因此此a是三者中最小者是三者中最小者)if b c 将将b和和c对换对换 (b是是b,c中的小者,也中的小者,也是三者中次小者是三者中次小者)然后顺序输出然后顺序输出a,b,c即可。即可。按此算法编写程序:按此算法编写程序:main()float a,b,c,t;scanf(f,f,f,&a,&b,&c);if(ab)t=a;a=b;b=t;/*实现实现a和和b的互换的互换*/if(
21、ac)t=a;a=c;c=t;/*实现实现a和和c的互换的互换*/if(bc)t=b;b=c;c=t;/*实现实现b和和c的互换的互换*/printf(52f,52f,52f,a,b,c);运行情况如下:运行情况如下:3,7,1 1.00,3.00,7.005.3.2 if语句的嵌套语句的嵌套在在if语句中又包含一个或多个语句中又包含一个或多个if语句称为语句称为if语句语句的嵌套。一般形式如下:的嵌套。一般形式如下:if()if()语句语句1else语句语句2内嵌内嵌ifelseif()语句语句3else语句语句4内嵌内嵌if应当注意应当注意if与与else的配对关系。的配对关系。else总
22、是与它上面的最近总是与它上面的最近的的if配对。假如写成配对。假如写成:if()if()语句语句1elseif()语句语句2else 语句语句3内嵌内嵌if编程序者把编程序者把else写在与第一个写在与第一个if(外层外层if)同一列上同一列上,希望希望else与第一个与第一个if对应对应,但实际上但实际上else是与第二个是与第二个if配对配对,因为它因为它们相距最近。因此最好使内嵌们相距最近。因此最好使内嵌if语句也包含语句也包含else部分部分(如如本节本节(5.3.2节节)最早列出的形式最早列出的形式),这样这样if的数目和的数目和else的数的数目相同目相同,从内层到外层一一对应从内
23、层到外层一一对应,不致出错。不致出错。如果如果if与与else的数目不一样的数目不一样,为实现程序设计者的企图为实现程序设计者的企图,可以加花括弧来确定配对关系。例如可以加花括弧来确定配对关系。例如:if()if()语句语句1 else语句语句2(内嵌内嵌if)这时这时 限定了内嵌限定了内嵌if语句的范围语句的范围,因此因此else与第一个与第一个if配对。配对。例例5.3有一函数有一函数:y=-1(x0)编一程序编一程序,输入一个输入一个x值值,输出输出y值。值。可以先写出算法:可以先写出算法:输入输入x若若 x 0y=1输出输出y或输入或输入x若若 x 0y=1输出输出y。也可以用流程图表
24、示,见图。也可以用流程图表示,见图5.7。图图5.7有以下几个程序,请读者判断哪个是正确的?有以下几个程序,请读者判断哪个是正确的?程序程序1:main()int x,y;scanf(d,&x);if(x0)y=-1;else if(x=0)y=0;else y=1;printf(x=d,y=dn,x,y);程序程序2:将上面程序的:将上面程序的if语句语句(第第46行行)改为:改为:if(x=0)if(x0)y=1;else y=0;else y=-1;程序程序3:将上述:将上述if语句改为:语句改为:y=-1;if(x!=0)if(x0)y=1;else y=0;程序程序4:y=0;if(
25、x=0)if(x0)y=1;else y=-1;图图5.85.8只有程序只有程序1和程序和程序2是正确的。程序是正确的。程序1体现了图体现了图5.7的的流程,显然它是正确的。程序流程,显然它是正确的。程序2的流程图见图的流程图见图5.8。它也能实现题目的要求。程序它也能实现题目的要求。程序3的流程图见图的流程图见图5.9。程序程序4的流程图见图的流程图见图5.10。它们不能实现题目的要。它们不能实现题目的要求。请注意程序中的求。请注意程序中的else与与if的配对关系。例如程的配对关系。例如程序序3中的中的else子句是和它上一行的内嵌的子句是和它上一行的内嵌的if语句配对,语句配对,而不与笫
26、而不与笫2行的行的if语句配对。为了使逻辑关系清晰,语句配对。为了使逻辑关系清晰,避免出错,一般把内嵌的避免出错,一般把内嵌的if语句放在外层的语句放在外层的else子子句中句中(如程序如程序1那样那样),这样由于有外层的,这样由于有外层的else相隔,相隔,内嵌的内嵌的else不会被误认为和外层的不会被误认为和外层的if配对,而只能配对,而只能与内嵌的与内嵌的if配对,这样就不会搞混,如像程序配对,这样就不会搞混,如像程序3和和程序程序4那样写就很容易出错。那样写就很容易出错。图图5.9 图图5.105.105.3.3 条件运算符条件运算符若若if语句中,在表达式为语句中,在表达式为“真真”
27、和和“假假”时,且都只时,且都只执行一个赋值语句给同一个变量赋值时,可以用执行一个赋值语句给同一个变量赋值时,可以用简单的条件运算符来处理。例如,若有以下简单的条件运算符来处理。例如,若有以下if语句:语句:if(ab)max=a;elsemax=b;可以用下面的条件运算符来处理:可以用下面的条件运算符来处理:max=(ab)?a b;其中其中“(ab)?a b”是一个是一个“条件表达式条件表达式”。它是。它是这样执行的:如果这样执行的:如果(ab)条件为真,则条件表达式条件为真,则条件表达式取值取值a,否则取值,否则取值b。条件运算符要求有条件运算符要求有3个操作对象,称三目个操作对象,称三
28、目(元元)运算符,运算符,它是它是c语言中唯一的一个三目运算符。条件表达式语言中唯一的一个三目运算符。条件表达式的一般形式为图的一般形式为图5.11表达式表达式1?表达式?表达式2 表达式表达式3。它的执行过程见图它的执行过程见图5.11。图图5.11说明:说明:(1)条件运算符的执行顺序:先求解表达式条件运算符的执行顺序:先求解表达式1,若为,若为非非0(真真)则求解表达式则求解表达式2,此时表达式,此时表达式2的值就作为的值就作为整个条件表达式的值。若表达式整个条件表达式的值。若表达式1的值为的值为0(假假),则,则求解表达式求解表达式3,表达式,表达式3的值就是整个条件表达式的值就是整个
29、条件表达式的值。的值。max=(ab)?a b执行结果就是将条件表达式的值赋给执行结果就是将条件表达式的值赋给max。也就是。也就是将将a和和b二者中大者赋给二者中大者赋给max。(2)条件运算符优先于赋值运算符,因此上面赋值表条件运算符优先于赋值运算符,因此上面赋值表达式的求解过程是先求解条件表达式,再将它的达式的求解过程是先求解条件表达式,再将它的值赋给值赋给max。条件运算符的优先级别比关系运算符和算术运算符条件运算符的优先级别比关系运算符和算术运算符都低。因此都低。因此max=(ab)?a b括号可以不要,可写成括号可以不要,可写成max=ab?a b如果有如果有ab?a b1相当于相
30、当于ab?a (b1),而不相当于,而不相当于(ab?a b)1。(3)条件运算符的结合方向为条件运算符的结合方向为“自右至左自右至左”。如果有。如果有以下条件表达式:以下条件表达式:ab?a cd?c d相当于相当于ab?a (cd?c d)如果如果a=1,b=2,c=3,d=4,则条件表达式的值等于,则条件表达式的值等于4。(4)条件表达式不能取代一般的条件表达式不能取代一般的if语句,只有在语句,只有在if语句语句中内嵌的语句为赋值语句中内嵌的语句为赋值语句(且两个分支都给同一个且两个分支都给同一个变量赋值变量赋值)时才能代替时才能代替if语句。像下面的语句。像下面的if语句就无语句就无
31、法用一个条件表达式代替。法用一个条件表达式代替。if(ab)printf(d,a);else printf(d,b);但可以用下面语句代替:但可以用下面语句代替:printf(d,ab?a b);即将条件表达式的值输出。即将条件表达式的值输出。(5)条件表达式中,表达式条件表达式中,表达式1的类型可以与表达式的类型可以与表达式2和和表达式表达式3的类型不同。如的类型不同。如x?a bx是整型变量,若是整型变量,若x=0,则条件表达式的值为,则条件表达式的值为b。表。表达式达式2和表达式和表达式3的类型也可以不同,此时条件表的类型也可以不同,此时条件表达式的值的类型为二者中较高的类型。如达式的值
32、的类型为二者中较高的类型。如xy?1 15如果如果xy,则条件表达式的值为,则条件表达式的值为15,若,若xy,值应,值应为为1,由于,由于15是实型,比整型高是实型,比整型高(见第见第3章章37),因此,将因此,将1转换成实型值转换成实型值1.0。例例5.4输入一个字符,判别它是否大写字母,如果是,输入一个字符,判别它是否大写字母,如果是,将它转换成小写字母;如果不是,不转换。然后将它转换成小写字母;如果不是,不转换。然后输出最后得到的字符。输出最后得到的字符。关于大小写字母之间的转换方法,在本书例关于大小写字母之间的转换方法,在本书例3.7中已中已做了介绍,因此可直接编写程序:做了介绍,因
33、此可直接编写程序:main()charch;scanf(c,&ch);ch=(ch=a&ch=Z)?(ch32)ch;printf(c,ch)运行结果如下:运行结果如下:a a条件表达式中的条件表达式中的(ch32),其中,其中32是小写字母和大写是小写字母和大写字母字母ASCII码的差值。码的差值。5.4 Switch 语语 句句Switch语句是多分支选择语句。用来实现如图语句是多分支选择语句。用来实现如图3.6所所表示的多分支选择结构。表示的多分支选择结构。if语句只有两个分支可供语句只有两个分支可供选择,而实际问题中常常需要用到多分支的选择。选择,而实际问题中常常需要用到多分支的选择。
34、例如,学生成绩分类例如,学生成绩分类(90分以上为分以上为a等,等,8089分为分为b等,等,7079分为分为c等等);人口统计;人口统计分类分类(按年龄分为老、中、青、少、儿童按年龄分为老、中、青、少、儿童);工资统;工资统计分类;银行存款分类计分类;银行存款分类。当然这些都可以用嵌套的当然这些都可以用嵌套的if语句来处理,但如果分支语句来处理,但如果分支较多,则嵌套的较多,则嵌套的if语句层数多,程序冗长而且可读语句层数多,程序冗长而且可读性降低。性降低。c语言提供语言提供Switch语句直接处理多分支选语句直接处理多分支选择,它相当于择,它相当于Pascal语言中的语言中的case语句。
35、它的一般语句。它的一般形式如下:形式如下:switch(表达式表达式)case常量表达式常量表达式1:语句:语句1 case常量表达式常量表达式2:语句:语句2 case常量表达式常量表达式n:语句:语句n default :语句:语句n1 例如,要求按照考试成绩的等级打印出百分制分数例如,要求按照考试成绩的等级打印出百分制分数段,可以用段,可以用Switch语句实现:语句实现:Switch(grade)casea printf(85100n);caseb printf(7084n);casec printf(6069n);caseD printf(60n);default printf(er
36、rorn);说明:说明:(1)switch后面括弧内的后面括弧内的“表达式表达式”,ANSI标准允标准允许它为任何类型。许它为任何类型。(2)当表达式的值与某一个当表达式的值与某一个case后面的常量表达式的后面的常量表达式的值相等时,就执行此值相等时,就执行此case后面的语句,若所有的后面的语句,若所有的case中的常量表达式的值都没有与表达式的值匹配的,中的常量表达式的值都没有与表达式的值匹配的,就执行就执行default后面的语句。后面的语句。(3)每一个每一个case的常量表达式的值必须互不相同,否的常量表达式的值必须互不相同,否则就会出现互相矛盾的现象则就会出现互相矛盾的现象(对表
37、达式的同一个值,对表达式的同一个值,有两种或多种执行方案有两种或多种执行方案)。(4)各个各个case和和default的出现次序不影响执行结果。的出现次序不影响执行结果。例如,可以先出现例如,可以先出现“default:”,再出现,再出现“case D:”,然后是,然后是“case a:”。(5)执行完一个执行完一个case后面的语句后,流程控制转移到后面的语句后,流程控制转移到下一个下一个case继续执行。继续执行。“case常量表达式常量表达式”只是起只是起语句标号作用,并不是在该处进行条件判断。在语句标号作用,并不是在该处进行条件判断。在执行执行Switch语句时,根据语句时,根据Sw
38、itch后面表达式的值找后面表达式的值找到匹配的入口标号,就从此标号开始执行下去,到匹配的入口标号,就从此标号开始执行下去,不再进行判断。例如,上面的例子中,若不再进行判断。例如,上面的例子中,若grade的的值等于值等于a,则将连续输出:,则将连续输出:85100 7084 6069 60 error因此,应该在执行一个因此,应该在执行一个case分支后,使流程跳出分支后,使流程跳出Switch结构,即终止结构,即终止Switch语句的执行。可以用一语句的执行。可以用一个个break语句来达到此目的。将上面的语句来达到此目的。将上面的Switch结构结构改写如下:改写如下:Switch(gr
39、ade)casea printf(85100n);break;caseb printf(7084n);break;casec printf(6069n);break;caseD printf(60n);break;default printf(errorn);最后一个分支最后一个分支(default)可以不加可以不加break语句。语句。如果如果grade的值为的值为b,则只输出,则只输出“7084”。流程图。流程图见图见图5.12。图图5.125.12在在case后面中虽然包含一个以上执行语句,但可以后面中虽然包含一个以上执行语句,但可以不必用花括弧括起来,会自动顺序执行本不必用花括弧括起来
40、,会自动顺序执行本case后后面所有的执行语句。当然加上花括弧也可以。面所有的执行语句。当然加上花括弧也可以。(6)多个多个case可以共用一组执行语句,如:可以共用一组执行语句,如:casea caseb casec printf(60n);break;grade的值为的值为a、b或或c时都执行同一组语句。时都执行同一组语句。5.5 程序举例程序举例例例5.5写程序,判断某一年是否闰年。写程序,判断某一年是否闰年。我们用图我们用图5.13来表示判别闰年的算法。以变量来表示判别闰年的算法。以变量leap代表是否闰年的信息。若某年为闰年,则令代表是否闰年的信息。若某年为闰年,则令leap=1;若
41、为非闰年,令;若为非闰年,令leap=0。最后判断。最后判断leap是是否为否为1(真真),若是,则输出,若是,则输出“闰年闰年”信息。信息。图图5.13据此编写程序如下:据此编写程序如下:main()int year,leap;scanf(d,&year);if(year4=0)if(year100=0)if(year400=0)leap=1;else leap=0;else leap=1;else leap=0;if(leap)printf(d is,year);else printf(d is not,year);printf(a leap year.n);运行情况如下:运行情况如下:1
42、989 1989 is not a leap year.2000 2000 is a leap year.也可以将程序中第也可以将程序中第513行改写成以下的行改写成以下的if语句:语句:if(year4!=0)leap=0;else if(year100!=0)leap=1;else if(year400!=0)leap=0;else leap=1;也可以用一个逻辑表达式包含所有的闰年条件,将也可以用一个逻辑表达式包含所有的闰年条件,将上述上述if语句用下面的语句用下面的if语句代替:语句代替:if(year%4=0&year%100!=0)|(year%400=0)leap=1;elsel
43、eap=0;例例5.6求求ax2bxc=0方程的解。方程的解。例例4.12曾介绍过基本的算法,实际上应该有以下几曾介绍过基本的算法,实际上应该有以下几种可能:种可能:a=0,不是二次方程。,不是二次方程。b2-4ac=0,有两个相等实根。,有两个相等实根。b2-4ac0,有两个不等实根。,有两个不等实根。b2-4ac0,有两个共轭复根。,有两个共轭复根。画出画出NS流程图表示算法流程图表示算法(图图5.14)。图图5.145.14据此编写程序如下:据此编写程序如下:#include main()float a,b,c,d,disc,x1,x2,realpart,imagpart;scanf(f
44、,f,f,&a,&b,&c);printf(The equation);if(fabs(a)=le-6)printf(is not a quadratic);else disc=b*b-4*a*c;if(fabs(disc)=le-6)printf(has two equal roots:%8.4n,-b(2*a);else if(discle-6)x1=(-bsqrt(disc)(2*a);x2=(-b-sqrt(disc)(2*a);printf(has distinct real roots:%8.4f and%8.4fn,x1,x2);else realpart=-b(2*a);ima
45、gpart=sqrt(-disc)(2*a);printf(has comPlex roots n);printf(%8.4f+%8.4fin,realpart,imagpart);printf(%8.4f-%8.4fin,realpart,imagpart);程序中用程序中用disc代表代表b2-4ac,先计算,先计算disc的值,以减少的值,以减少以后的重复计算。对于判断以后的重复计算。对于判断b2-4ac是否等于是否等于0时,时,要注意一个问题:由于要注意一个问题:由于disc(即即b2-4ac)是是实数,而实数在计算和存储时会有一些微小的误差,实数,而实数在计算和存储时会有一些微小的误
46、差,因此不能直接进行如下判断:因此不能直接进行如下判断:if(disc=0)因为因为这样可能会出现本来是零的量,由于上述误差而这样可能会出现本来是零的量,由于上述误差而被判别为不等于零而导致结果错误。所以采取的被判别为不等于零而导致结果错误。所以采取的办法是判别办法是判别disc的绝对值的绝对值(fabs(disc)是否小于一个是否小于一个很小的数很小的数(例如例如10-6),如果小于此数,就认为,如果小于此数,就认为disc=0。程序中以。程序中以realpart代表实部代表实部P,以,以imagpart代表虚部代表虚部q,以增加可读性。,以增加可读性。运行结果如下:运行结果如下:1,2,1
47、 The equation has two equalroots -10000 1,2,2 The equation has complex roots:-1000010000i -10000-10000i 2,6,1 The equation has distinct real roots:-0.1771 and=2.8229例例5.7运输公司对用户计算运费。路程运输公司对用户计算运费。路程(S)越远,每公越远,每公里运费越低。标准如下:里运费越低。标准如下:s250km没有折扣没有折扣 250S500 2折扣折扣 500S1000 5折扣折扣 1000S2000 8折扣折扣 2000S30
48、00 10折扣折扣 3000S 15折扣折扣设每公里每吨货物的基本运费为设每公里每吨货物的基本运费为P(Price的缩写的缩写),货,货物重为物重为w(weight的缩写的缩写),距离为,距离为S,折扣为,折扣为d(discount的缩写的缩写),则总运费,则总运费f(freight的缩写的缩写)的计的计算公式为算公式为f=P*w*S*(1-d)分析此问题,折扣的变化分析此问题,折扣的变化是有规律的:从图是有规律的:从图5.15可以看到,折扣的可以看到,折扣的“变化变化点点”都是都是250的倍数的倍数(250,500,1000,2000,3000)。利用这一特点,可以在横轴上加一种坐标。利用这
49、一特点,可以在横轴上加一种坐标c,c的值为的值为S/250。c代表代表250的倍数。当的倍数。当c1时,表时,表示示S250,无折扣;,无折扣;1c2时,表示时,表示250S500,折扣折扣d=2;2c4时,时,d=5;4c8时,时,d=8;8c12时,时,d=10;c12时,时,d=15。图图5.155.15据此写出程序如下:据此写出程序如下:main()int c,S;float P,w,d,f;scanf(f,f,d,&P,&w,&S);if(S=3000)c=12;elsec=S250;switch(c)case0 d=0;break;case1 d=2;break;case2 cas
50、e3 d=5;break;case4 case5 case6 case7 d=8;break;case8 case9 case10 case11 d=10;break;case12 d=15;break;f=P*w*S*(1-d1000);printf(freight=154f,f);运行情况如下:运行情况如下:100,20,300freight=588000.0000请注意:请注意:c、S是整型变量,因此是整型变量,因此c=S250为整数。为整数。当当S3000时,令时,令c=12,而不使,而不使c随随S增大,这是为了增大,这是为了在在Switch语句中便于处理,用一个语句中便于处理,用一个