第五章 选择结构程序设计 一、关系运算符和表达式 1、关系运算符 在程序中经常需要比较两个量的大小关系, 以决定程序下一步 的工作。比较两个量的运算符称为关系运算符。 在C语言中有以下关系运算符: < 小于 <= 小于或等于 > 大于 >= 大于或等于 == 等于 != 不等于 关系运算符都是双目运算符,其结合性均为左结合。 关系运算符的优先级低于算术运算符,高于赋值运算符。 在六个关系运算符中,<,<=,>,>=的优先级相同,高于==和!=,==和!=的优先级相同。
2、关系表达式 关系表达式的一般形式为: 表达式 关系运算符 表达式 表达式 关系运算符 表达式 例如:a+b>c-d,x>3/2 ‘a’+1<c -i-5*j==k+1 由于表达式也可以又是关系表达式。 因此也允许出现嵌套 的情况,例如:a>(b>c),a!=(c==d)等。关系表达式的值是“真” 和“假”,用“1”和“0”表示。 如: 5>0的值为“真”,即为1。 (a=3)>(b=5)由于3>5不成立,故其值为假,即为0。
#include<stdio.h> main() { char c='k'; int i=1,j=2,k=3; float x=3e+5,y=0.85; printf("%d,%d\n",'a'+5<c,-i-2*j>=k+1); printf("%d,%d\n",1<j<5,x-5.25<=x+y); printf("%d,%d\n",i+j+k==-2*j,k==j==i+5); } 在本例中求出了各种关系运算符的值。 字符变量是以它对应 的ASCII码参与运算的。对于含多个关系运算符的表达式,如 k==j==i+5, 根据运算符的左结合性,先计算k==j,该式不成立,其值为0,再 计算0==i+5,也不成立,故表达式值为0。
二、逻辑运算符和表达式 1、 逻辑运算符 C语言中提供了三种逻辑运算符 && 与运算 || 或运算 ! 非运算 1、 逻辑运算符 C语言中提供了三种逻辑运算符 && 与运算 || 或运算 ! 非运算 与运算符&&和或运算符||均为双目运算符。具有左结合性。 非运算符!为单目运算符,具有右结合性。逻辑运算符和其它运 算符优先级的关系可表示如课本中,图5-2所示: 按照运算符的优先顺序可以得出: a>b && c>d等价于(a>b) && (c>d) !b==c||d<a等价于((!b)==c)||(d<a) a+b>c && x+y<b等价于((a+b)>c) && ((x+y)<b)
2、逻辑运算的值 逻辑运算的值也为“真”和“假”两种,用“1”和“0 ”来表 示。其求值规则如下: 1.与运算&& 参与运算的两个量都为真时,结果才为真,否则为假。 例如:5>0 && 4>2 由于5>0为真,4>2也为真,&&结果为真。 加速法则:若0&&x,则x不进行运算。 2.或运算|| 参与运算的两个量只要有一个为真,结果就为真。 两个量都 为假时,结果为假。 例如:5>0||5>8,由于5>0为真,||结果也就为真。 加速法则:若1||x,则x不进行运算。
3.非运算! 参与运算量为真时,结果为假;参与运算量为假时,结果为 真。例如:!(5>0)的结果为假。 虽然C编译在给出逻辑运算值时,以“1”代表“真”,“0 ” 代表“假”。 但反过来在判断一个量是为“真”还是为“假”时, 以“0”代表“假”,以非“0”的数值作为“真”。 例如:由于5和3均为非“0”因此5&&3的值为“真”,即为1。 又如:5||0的值为“真”,即为1。
3、逻辑表达式 逻辑表达式的一般形式为: 表达式 逻辑运算符 表达式 其中的表达式可以又是逻辑表达式,从而组成了嵌套的情形。例如: 表达式 逻辑运算符 表达式 其中的表达式可以又是逻辑表达式,从而组成了嵌套的情形。例如: (a&&b)&&c 根据逻辑运算符的左结合性,上式也可写为: a&&b&&c 逻辑表达式的值是式中各种逻辑运算的最后值,以“1”和“0” 分别代表“真”和“假”。
#include<stdio.h> main(){ char c='k'; int i=1,j=2,k=3; float x=3e+5,y=0.85; printf("%d,%d\n",!x*!y,!!!x); printf("%d,%d\n",x||i&&j-3,i<j&&x<y); printf("%d,%d\n",i==5&&c&&(j=8),x+y||i+j+k); } 本例中!x和!y分别为0,!x*!y也为0,故其输出值为0。由于 x为非0,故!!!x的逻辑值为0。对x|| i && j-3式,先计算j-3的值 为非0,再求i && j-3的逻辑值为1,故x||i&&j-3的逻辑值为 1。 对i<j&&x<y式,由于i<j的值为1,而x<y为0.故表达式的值为1,0 相与,最后为0,对i==5&&c&&(j=8)式,由于i==5为假,即值为0, 该表达式由两个与运算组成,所以整个表达式的值为0。对于式 x+ y||i+j+k由于x+y的值为非0,故整个或表达式的值为1。
三、if条件语句 用if语句可以构成分支结构。它根据给定的条件进行判断, 以 决定执行某个分支程序段。C语言的if语句有三种基本形式。 1.第一种形式为基本形式 if(表达式) 语句; 其语义是:如果表达式的值为真,则执行其后的语句, 否则不执 行该语句。 #include<stdio.h> main(){ int a,b,max; printf("\n input two numbers:"); scanf("%d%d",&a,&b); max=a; if (max<b) max=b; printf("max=%d",max); } 例:
2.第二种形式为if-else形式 if(表达式) 语句1; else 语句2; 其语义是:如果表达式的值为真,则执行语句1,否则执行语句2 。 main() { int a, b; printf("input two numbers:"); scanf("%d%d",&a,&b); if(a>b) printf("max=%d\n",a); else printf("max=%d\n",b); } 例:
3.第三种形式为if-else-if形式 前二种形式的if语句一般都用于两个分支的情况。 当有多个分 支选择时,可采用if-else-if语句,其一般形式为: if(表达式1) 语句1; else if(表达式2) 语句2; else if(表达式3) 语句3; … else if(表达式m) 语句m; else 语句n; 其语义是:依次判断表达式的值,当出现某个值为真时, 则执行其对应的语句。然后跳到整个if语句之外继续执行程序。 如果所有的表达式均为假,则执行语句n 。 然后继续执行后续程序。
#include<stdio.h> main(){ char c; printf("input a character:"); c=getchar(); if(c<32) printf("This is a control character\n"); else if(c>= ’0' &&c<= ’9') printf("This is a digit\n"); else if(c>='A'&&c<='Z') printf("This is a capital letter\n"); else if(c>='a'&&c<='z') printf("This is a small letter\n"); else printf("This is an other character\n");} 根据输入字符的ASCII码来判别键盘输入字符的类别。由 ASCII码表可知ASCII值小于32的为控制字符。 在‘0’和‘9’之 间的为数字,在‘A’和‘Z’之间为大写字母, 在‘a’和‘z’之间 为小写字母,其余则为其它字符。
4.在使用if语句中还应注意以下问题 (1) 在三种形式的if语句中,在if关键字之后均为表达式。 该表达 式通常是逻辑表达式或关系表达式, 但也可以是其它表达式, 如赋值表达式等,甚至也可以是一个变量。例如: if(a=5) 语句; if(b) 语句; 都是允许的。只要表达式的值为非0,即为“真”。如在if(a=5) …;中表达式的值永远为非0,所以其后的语句总是要执行的,当 然这种情况在程序中不一定会出现,但在语法上是合法的。
又如,有程序段: if(a=b) printf("%d",a); else printf("a=0"); 本语句的语义是,把b值赋予a,如为非0则输出该值,否则 输出“a=0”字符串。这种用法在程序中是经常出现的。 (2) 在if语句中,条件判断表达式必须用括号括起来, 在语句 之后必须加分号。
3) 在if语句的三种形式中,所有的语句应为单个语句,如果要想 在满足条件时执行一组(多个)语句,则必须把这一组语句用{} 括 起来组成一个复合语句。但要注意的是在}之后不能再加分号。 例如: if(a>b){ a++; b++; } else{ a=0; b=10;
5、if语句的嵌套 当if语句中的执行语句又是if语句时,则构成了if 语句嵌套的情形。其一般形式可表示如下: if(表达式) if语句; 或者为 else
在嵌套内的if语句可能又是if-else型的,这将会出现多个if 和多个else重叠的情况,这时要特别注意if和else的配对问题。例 如: if(表达式1) if(表达式2) 语句1; else 语句2; 应该理解为: 还是应理解为: if(表达式1) if(表达式1) if(表达式2) if(表达式2) 语句1; 语句1; else 语句2; else 语句2; 为了避免这种二义性,C语言规定,else 总是与它前面最 近的if配对,因此对上述例子应按前一种情况理解。
#include<stdio.h> main(){ int a,b; printf("please input A,B:"); scanf("%d%d",&a,&b); if(a!=b) if(a>b) printf("A>B\n"); else printf("A<B\n"); else printf("A=B\n"); } 本例中用了if语句的嵌套结构。 采用嵌套结构实质上是为了 进行多分支选择,实际上有三种选择即A>B、A<B或A=B。这种问 题用if-else-if语句也可以完成。而且程序更加清晰。因此,在 一般情况下较少使用if语句的嵌套结构。 以使程序更便于阅读理 解.
小结 if 条件语句 一. 条件语句的一般形式为: 真 if (表达式) 语句1; else 语句2; 假 表达式 语句1 语句2
例:求任一实数的绝对值 #include "stdio.h" main( ) { double x, xabs; printf("input a data :"); scanf("%lf",&x); if(x<0) xabs=-x; else xabs=x; printf("x=%f,|x|=%f\n",x,xabs); }
注意: 1. if 语句中 “else 语句2;” 部分可以缺省, 此时, if 语句变成: if (表达式) 语句1; 2. 如果语句1或语句2有多于一条语句要执行时, 必须使用“{”和“}” 把这些语句括起来成为一个复合语句. 3.所谓表达式一般是关系表达式和逻辑表达式的结合 式, 也可为任意类型表达式.
4. if 语句可以嵌套 例如: if (x>20||x<-10) if (y<=100&&y>x) printf("Good"); else printf("Bad"); C规定: else语句与它最近的一个if配对. 若为了使else与if(x>20||x<-10)相匹配, 必须用 花括号。即: if (x>20||x<-10) { if (y<=100&&y>x) printf("Good");}
5. 可用阶梯式if-else-if结构来实现多种条件的选择 阶梯式结构的一般形式为: if (表达式1) 语句1; else if (表达式2) 语句2; else if (表达式3) 语句3; . else 语句n; 这种结构是从上到下逐个对条件进行判断, 一旦发现条件 满足就执行与它有关的语句, 并跳过其它剩余阶梯; 若没有一个条件满足, 则执行最后一个else语句n。 最后这个else常起着"缺省条件"的作用。
四. 条件运算符和条件表达式 1. 条件运算符 ? : 是 C语言唯一的一个三目运算符, 其功能为:若在 If 语句中,无论条件表达式为 1. 条件运算符 ? : 是 C语言唯一的一个三目运算符, 其功能为:若在 If 语句中,无论条件表达式为 真或为假,均是用赋值语句对同一个变量赋值时,可用 条件运算符处理。 即? if (a>b) max = a ; else max = b ; 等价于 max = (a>b) ? a: b ;
2.条件表达式 一般形式是: <表达式1> ? <表达式2> : <表达式3> 求值过程是: 先求表达式1的值, 若为真, 则求表达式2 的值并把它作为整个表达式 的值; 若表达式1 的值为假, 则求表达式3 的值并把它作为 整个表达式的值。
3.说明: 算术运算符 (高) 关系运算符 条件运算符 赋值运算符 (低) 1) 条件运算符的优先级 1) 条件运算符的优先级 算术运算符 关系运算符 条件运算符 赋值运算符 (高) (低) max = (a>b) ? a : b ; 与 max = a>b ? a : b ; 等价. y= a>b ? a : (b+1) ; 与 y = a>b ? a : b+1 ; 等价. 2) 条件运算符的结合性: 自右向左 例: a=1 , b=2 ,c=3 ,d=4, 则条件表达式 a > b ? a : c > d ? c: d 的值为4
3) 条件表达式不能取代一般的 if 语句,只能取代if 语句中特殊的一种. 例: if (a > b) printf ("%d", a); else printf ("%d", b); 可用 printf("%d", a> b ? a: b ); 取代. 4) 条件表达式中,表达式1的类型可与表达式2及3 不同,表达式2和 表达式3的类型也可不同,而 条件表达式值的类型取表达式2和3中的较高者. 例: int x, y; x ? 'a':'b' 值为字符型 x > y ? 1 : 1.5 值为实型
例:求a,b,c中的绝对值最大的数 #include <stdio.h> #include <math.h> main() {float a,b,c,max; printf(“input three data:\n”); scanf(“%f%f%f ”,&a,&b,&c); if(fabs(a)>fabs(b)) max = fabs(a)>fabs(c)? a : c ; else max = fabs(b)>fabs(c)? b : c ; printf(“a=%.2f,b=%.2f,c=%.2f,max=%.2f”,a,b,c,max); }
五、 switch语句 一般形式为: switch(表达式) { case 常量表达式1: 语句1或空; . case 常量表达式n: 语句n或空; default: 语句n+1或空; } 说明: 1.执行switch语句时, 将表达式的值逐个与case后的常量 进行比较, 若与其中一个相等, 则执行该常量下的语句, 若不与任何一个常量相等, 则执行default 后面的语句。
2. switch中表达式与case后的常量可为任何类型. 则出现矛盾。 4. 每个case或default后的语句可以是复合语句, 但不需要使用"{"和"}"括起来。 5.执行完一个case后面语句后,流程控制转移到下一 个case 继续执行.因此,若想在不同情况下执行不同的 语句,必须使用break语句。 break语句的功能:将程序流程控制跳出整个switch语句, 执行switch语句的下一条语句.
例: 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("Error\n"); } 6.多个 case 可共用一组执行语句.例: case 'A': case 'B': case 'C': printf(">60\n"); break;
选择结构程序设计举例 例: 将任意三个整数按从大到小的顺序输出。 #include "stdio.h" void main() 例: 将任意三个整数按从大到小的顺序输出。 #include "stdio.h" void main() {int x,y,z,t; scanf("%d,%d,%d",&x,&y,&z); if(x<y) {t=x;x=y;y=t;} /*交换x,y的值*/ if(x<z) {t=x;x=z;z=t;} /*交换x,z的值*/ if(y<z) {t=y;y=z;z=t;} /*交换y,z的值*/ printf("%d,%d,%d\n",x,y,z); }
例: 给一个不多于4位的正整数,求出它是几位数,逆序打印出各位数字。 例: 给一个不多于4位的正整数,求出它是几位数,逆序打印出各位数字。 #include "stdio.h" void main() {int x,a,b,c,d; /*a,b,c,d代表千位、百位、十位、个位*/ scanf("%d",&x); a=x/1000; b=x%1000/100; c=x%100/10; d=x%10; /*分解出千位、百位、十位、个位*/ if(a!=0) printf("4:%d%d%d%d\n",d,c,b,a); else if(b!=0) printf("3:%d%d%d\n",d,c,b); else if(c!=0) printf("2:%d%d\n",d,c); else if(d!=0) printf("1:%d\n",d); }
例: 任意输入三个数,判断能否构成三角形?若能构成三角形,是等边三角形、等腰三角形还是其它三角形? #include "stdio.h" void main() {float a,b,c; scanf("%f,%f,%f",&a,&b,&c); if(a+b>c&&a+c>b&&b+c>a) {if(a==b&&b==c) printf("equalateral triangle.\n"); else if(a==b||a==c||b==c) printf("isoscelestriangle.\n"); else printf("other triangle.\n"); } else printf("can not\n");
例: 从键盘输入一个年份,判断是否是闰年。 #include "stdio.h" void main() {int year; scanf("%d",&year); if(year%400==0||(year%4==0&&year%100!=0)) printf("%d is a leap year\n",year); else printf("%d is not a leap year\n",year); }
课堂练习 1.main() { int x=1,y=0,a=0,b=0; switch(x) {case 1: switch(y) {case 0: a++;break; case 1:b++;break; } case 2: a++;b++;break; case 3:a++;b++; printf(“a=%d,b=%d\n”,a,b); 结果: a=2,b=1
2.程序填空: 以下程序判断输入的整数能否被3或7整除. main() {int x,f=0; scanf( “%d”,&x ); if( 1 ) ( 2 ) if(f==1) printf(“YES\n”); else printf(“NO\n”); }