560 likes | 721 Views
C 程 序 设 计. 江南大学控制科学与工程研究中心 张正道 (wxzzd@hotmail.com). 第 5 章 选择结构程序设计. §5.1 关系运算符和关系表达式 §5.2 逻辑运算符和逻辑表达式 §5.3 if 语句 §5.4 switch 语句 §5.5 程序举例. §5.1 关系运算符 和 关系表达式. 关系运算实际上是比较运算 , 两个值进行比较 , 判断比较的结果是否符合给定的条件 , 如果符合比较的结果为 真 , 否则结果为 假 。
E N D
C 程 序 设 计 江南大学控制科学与工程研究中心 张正道(wxzzd@hotmail.com)
第5章 选择结构程序设计 §5.1 关系运算符和关系表达式 §5.2 逻辑运算符和逻辑表达式 §5.3 if语句 §5.4 switch语句 §5.5 程序举例
§5.1 关系运算符和关系表达式 • 关系运算实际上是比较运算,两个值进行比较,判断比较的结果是否符合给定的条件,如果符合比较的结果为真,否则结果为假。 • 用 将两个表达式(可以是算术表达式、关系表达式、逻辑表达式、赋值表达式、字符表达式)连接起来的式子叫 。 • 关系运算符与其它运算符的 。 关系运算符 关系表达式 优先次序
§5.2 逻辑运算符和逻辑表达式 逻辑运算符 • 用 将关系表达式或逻辑量连接起来就是 。 • 逻辑运算符与其它运算符的 。 • 在逻辑表达式的求解中,并不是所有的逻辑运算都被执行. • 逻辑运算规律: 逻辑表达式 优先次序 例如
问题提出: 解题的步骤: 输入x 计算分段函数: 3-x x≤0 x≤0 否 y= 2/x x>0 是 y=3-x y=2/x C语言用来设计条件选择结构程序的选择语句有两种: if语句、switch语句。 输出y的值 §5.3 if 语句
if语句是用来判定所给定的条件是否满足,根据判定的结果(真或假)决定执行给出的两种操作之一.if语句是用来判定所给定的条件是否满足,根据判定的结果(真或假)决定执行给出的两种操作之一. • if语句的三种形式: ①if (表达式) 语句 ②if (表达式) 语句1 else语句2 ③ if (表达式1) 语句1 else if (表达式2) 语句2 else if (表达式3) 语句3 ... ... else if (表达式n) 语句n else语句n+1 例如 例如 例如
if语句的嵌套 语句含义: 当if语句中又包含若干个if语句时,则构成了if 语句嵌套的情形。 语句形式: if ( 表达式1) if ( 表达式2) 语句1; else 语句2; if ( 表达式1) if ( 表达式2) 语句1;
表达式1 假(0) 真(非0) 表达式3 假(0) 表达式2 假(0) 真(非0) 真(非0) 语句3 语句4 语句1 语句2 语句执行流程: else与if的配对原则: 就近一致原则: else与同一层最接近它,而又没有其它else语句与之相匹配的if语句配对。
内嵌if • if ( ) if ( ) 语句1 else 语句2else if ( ) 语句3 else 语句4 • if ( ) if ( ) 语句1else if ( ) 语句2 else 语句3 内嵌if 内嵌if if ( ) { if ( ) 语句1 } else { if ( ) 语句2 else 语句3 }
x>=0 x>0 y=1 y=0 y= -1 { -1 (x<0) 例如 y= 0 (x=0) 1 (x>0) 假 x<0 假 真 X= =0 1. main (){int x, y; scanf(“%d” ,&x) ;if (x<0) y= - 1;else if (x= =0) y=0; else y=1;printf(“x=%d ,y=%d\n”,x ,y);} 2.if (x>=0) if (x>0) y=1; else y=0; else y= -1; 真 Y=0 Y=1 Y=-1 真 假 假 真
y= -1 y= 0 假 x>=0 X!=0 真 假 x>0 x>0 y=0 真 y=1 y=1 假 真 假 y=- 1 真 3 . y= - 1; if (x!=0)if (x>0) y=1; else y=0; 4. y=0; if (x>=0) if (x>0) y=1; else y= - 1;
5.3.3 条件运算符 ? : 表达式1 ?表达式2 : 表达式3条件表达式 max= (a>b)? a:b 相当于 if (a>b) max=a; else max=b; 说明: • 条件运算符的执行顺序 • 条件运算符的优先级别,仅高于赋值运算 • 条件运算符的结合方向为右结合性 • 条件表达式不能取代if语句 • 条件表达式中的表达式类型可以不同
§5.4 switch语句 根据表达式的不同值,选择不同的程序分支,又称开关语句。 千万不能接(;)号 1、语句形式: switch (表达式) { case 常量1: 语句1; case 常量2: 语句2; case 常量3: 语句3; ....... case 常量n: 语句n; default : 语句n+1; } 数值型 或 字符型 常量表达式的值必须互不相同,否则执行时将出现矛盾,即同一个开关值,将对应多种执行方案。
计算表达式 值 = = = = = 常量1 常量2 … 常量n 其它 语句1 语句2 语句n 语句n+1 无 无 无 break break break 有 有 有 2、语句执行流程: 简单语句或复合语句 case语句出 现的次序并 不影响执行 结果。 指语句的最后一条是否为break
表达式 常量表达式 例如:switch (grade){case ‘A’:printf(“85~100\n”);case ‘B’:printf(“70~84\n”);case ‘C’:printf(“60~79\n”);case ‘D’:printf(“<60\n”);default :printf(“error\n”);} 执行语句
在“switch”语句中,“case 常量表达式”只相当于一个语句标号,表达式的值和某标号相等则转向该标号执行,但不能在执行完该标号的语句后自动跳出整个switch 语句,因此会继续执行所有后面语句的情况。 为此,C语言提供了一种break语句,其功能是可以跳出它所在的switch语句。
改为 • switch (grade){case ‘A’:printf(“85~100\n”);break; case ‘B’:printf(“70~84\n”);break; case ‘C’:printf(“60~79\n”);break; case ‘D’:printf(“<60\n”);break; default :printf(“error\n”);}
例:假设用0、1、2......6分别表示星期日、星期一......星期六。现输入一个数字,输出对应的星期几的英文单词。如果输入3,输出“Wednesday”。 #include "stdio.h" void main() {int n; scanf("%d",&n); switch(n) {case 0: printf("Sunday\n"); case 1: printf("Monday\n"); case 2: printf("Tuesday\n"); case 3: printf("Wednesday\n"); case 4: printf("Thursday\n"); case 5: printf("Friday\n"); case 6: printf("Saturday\n"); default: printf("Error"); } } 程序运行情况如下: 3↙ Wednesday Thursday Friday Saturday error
程序运行情况如下: 3↙ Wednesday 将上面的例子修改如下: #include "stdio.h" void main() {int n; scanf("%d",&n); switch(n) {case 0: printf("Sunday\n"); break; case 1: printf("Monday\n"); break; case 2: printf("Tuesday\n"); break; case 3: printf("Wednesday\n"); break; case 4: printf("Thursday\n"); break; case 5: printf("Friday\n"); break; case 6: printf("Saturday\n"); break; default: printf("Error"); } }
3、说明 多个case语句可以共用一组执行语句。 switch(grade) { case 'A': case 'B': case 'C':printf("grade>=60\n");break; default:printf("grade<60"); } 各case和default子句的先后顺序可以变动,而不会影响程序执行结果。
default语句可以省略不用。 case和default与其后面的常量表达式间至少有一个空格。 switch语句可以嵌套,break语句只跳出它所在的switch语句。
例 企业发放的奖金根据利润提成。从键盘输入当月利润,求应发放奖金总数?
常量 0,1 1,2 2,3,4 4,5,6 6,7,8,9,10 10以上 利润x x<=10 10<x≤20 20<x≤40 40<x≤60 60<x≤100 100<x 使用switch解题的关键,通过分析找到表达式,将问题分成几种情况。 (int )x/10 用这种方法转换后,n出现了在不同区域有重复数字的情况。解决的方法有很多,其中一种是可以采用当x为10的整数倍时,将计算出的n值减1。
程序如下: #include "stdio.h" void main() {float x,y; int n; scanf("%f",&x); n=(int)x/10; if((int)x/10==x/10) n--; switch(n) {case 0:y=x*0.1;break; case 1:y=x*0.12;break; case 2:case 3:y=x*0.14;break; case 4:case 5:y=x*0.16;break; case 6:case 7:case 8:case 9:y=x*0.18;break; default:y=x*0.2; } printf("y=%.2f\n",y); }
Year被4整除 Y N Year被100整除 Y N leap=1 leap=0 Y Year被 400整除 N leap=1 leap=0 leap Y N 输出闰年 输出非闰年 §5.5 程序举例 例5.5 main() { int year, leap; 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 (“%d is ”,year); else printf (“%d is not ”,year); printf (“a leap year.\n”); }
例5.7 计算运费。 C=s/250 c<1 无折扣 1<c<2 2% 2<c<4 5% 4<c<8 8% 8<c<12 10% c>12 15% S<250km 没有折扣 250<=s<500 2%折扣 500<=s<1000 5%折扣 1000<=s<2000 8%折扣 2000<=s<3000 10%折扣 3000<=s 15%折扣 p(price),w(weight),s(distance),d(discount) f=p*w*s*(1-d) 250 1000 2000 3000
例5.7 main( ) {int c,s;float p,w,t,f; scanf(“%f,%f%d”,&p,&w,&s); if (s> =3000) c = 12 ;else c = s /250 ; switch(c) { csae 0: d = 0 ;break;csae 1: d = 2 ;break;csae 2: csae 3: d = 5;break;csae 4: csae 5: csae 6: csae 7: d = 8;break;csae 8: csae 9: csae 10: csae 11: d = 10; break;csae 12 : d = 15 ; break;}f = p*w*s*(1- d/100.0); printf(“freight=%15.4f”,f);}
a=0 N Y 输出 “非二次 方程 b2-4ac=0 N Y 输出 两相 等实根 -b/2a b2-4ac>0 Y N x1= x2= 实部 p= 虚部q= 输出两个实根 输出两个复根 p+qi p-qi 例5.6 解一元二次方程 Y
#include <math.h> main() { float a,b,c,d,disc,x1,x2,realpart,imagpart; scanf(“%f,%f,%f”,&a,&b,&c); printf(“The equation”); if(fabs(a)<=1e-6) printf (“is not a quadratic”); else {disc=b*b-4*a*c; if (fabs(disc)<=1e-6) printf(“has two equal roots: %8.4\n”,-b/(2*a)); else if (disc>1e -6) { x1=(-b+sqrt(disc))/(2*a); x2=(-b-sqrt(disc))/(2*a); printf (“has distinct real roots: %8.4f and %8.4f\n”,x1,x2); }
else {realpart=-b/(2*a); imagpart=sqrt(-disc)/(2*a); printf (“has complex roots:\n”); printf (%8.4f+%8.4fi\n”,realpart,imagpart); printf (%8.4f+%8.4fi\n”,realpart,imagpart); } } }
C语言提供六种关系运算符 ① < 小于 ② <= 小于等于 ③ > 大于 ④ >= 大于等于 ⑤ == 等于 ⑥ != 不等于 双目运算,左结合性.如: a>b,(a+b)>(b+c),(a=3)>(b=5), (a>b)>c, a>b>c,
关系表达式的值是一个逻辑值,即真或假。 运算时以1代表真,以0代表假。 例如:若a=3,b=2,c=1,则 赋值表达式: x=a>b y=a>b>c a>b 的值为真,表达式的值为1 (a>b)= =c 的值为真,表达式的值为1, b+c<a 的值为假,表达式的值为0,
优先次序: 1.前四种的优先级相同,后两种的优先级相同,且前高后低. 2.关系运算符低于算术运算符. 3.关系运算符高于赋值运算符. 如:c>a+b 算术运算符 高 a>b!=c a= =b<c 关系运算符 a=b>c 赋值运算符 低
逻辑运算符: &&逻辑与 ¦ ¦逻辑或 ! 逻辑非 ①&&和¦ ¦ 是双目运算符,!是单目运算符. 如:(a>b) && (x>y)(a>b)¦ ¦ (x>y) !(a>b) ②左结合性.
!(非)高 算术运算符 关系运算符 && ¦ ¦ 赋值运算符低 优先次序如图所示: 如: !a&&b ¦ ¦ x>y&&c 等效 ((! a)&&b) ¦ ¦ ((x>y)&&c) (a>b)&&(x>y) 等效 a>b&&x>y (a= =b) ¦ ¦ (x= =y) 等效 a= =b¦ ¦ x= =y (!a) ¦ ¦ (a>b) 等效 !a¦ ¦ a>b
逻辑表达式 • 逻辑表达式的值应该是一个逻辑量“真”或“假”,以数值“1”或“0”表示.而在判断一个量是否为“真”时,以“0”代表假,以非“0”代表真. • 如:若a= 4,则!a等于0 若a=4,b=5,则a&&b等于1 若a=0,b=5,则a ¦ ¦b等于1 若a=4,b=5,则!a ¦ ¦b等于1 4&&0 ¦ ¦2,等于1 5>3&&2 ¦ ¦8<4- !0, 值等于1
a&&b&&c 只有前一个量非0时,才需要判断下一个量. a¦ ¦b ¦ ¦ c 只要前一个量为真,就不必判断下一个量. a=1,b=2,c=3,d=4 m=1,n=1; (m=a>b)&&(n=c>d) n的值不是 0,仍为1 满足下列一个条件即为闰年:①能被4整除,不能被100整除②能被4整除,又能被400整除. (year%4= =0&&year%100!=0) ¦ ¦ year%400= =0 !((year%4= =0&&year%100!=0) ¦ ¦year%400= =0) (year%4!=0) ¦ ¦(year%100= =0&&year%400!=0)
1、单分支选择if语句 假(0) 语句形式: 表达式 if (表达式) 语句; 真(非0) 语句 语句执行流程:
一般为逻辑 表达式或关 系表达式. 理论上可以 是任意数值 类型 x>y 可以是一个语句也 可以是复合语句 print(“%d”,x); 例如:if (x>y) printf (“%d”,x); 这种if语句的执行过程见图: 假 真 If (a) printf(“Hello, world”);
例:从键盘输入两个整数a和b,如果a大于b则交换两数,最后输出两个数。 输入a,b 假 a>b #include <stdio.h> void main() {int a,b,t; scanf("%d,%d",&a,&b); 真 交换a、b if(a>b) {t=a;a=b;b=t;} 输出 printf("a=%d,b=%d\n",a,b); } 结束
注意: (1)if语句自动结合一个语句,当满足条件需要执行多个语句时,应用一对大括号{}将需要执行的多个语句括起,形成一个复合语句。 (2)if语句中表达式形式很灵活,可以是常量、变量、任何类型表达式、函数、指针等。只要表达式的值为非零值,条件就为真,反之条件为假。
2、双分支选择if语句 语句形式: if (表达式) 语句1; else 语句2 ; 语句执行流程: 假(0) 表达式 真(非0) 语句1 语句2
x>y 真 假 printf(“%d”,x); printf(“%d”,y) • 例如: if(x > y) printf(“%d”,x); else printf(“%d”,y); 注意 注意
例 输入两个整数,输出其中较大的数。 输入x,y #include <stdio.h> #include <math.h> 假 x>y 真 void main() {int x,y,max; scanf("%d,%d",&x,&y); max=x max=y if(x>y) max=x; else max=y; 输出最大值 printf("max=%d\n",max); } 结束
注意 if和else语句之间只能有一个语句,当if~else之间的语句不只一句时,应用一对{}将语句括起。 if(a>b) {a++;b++;} else { a=0;b=10;}
3、多分支选择if语句 语句形式: if (表达式1) 语句1; else if (表达式2)语句2; … … else if (表达式n)语句n; else 语句n+1;
假(0) 表达式2 真(非0) 假(0) 表达式2 语句2 语句n 语句n+1 语句执行流程: 假(0) 表达式1 真(非0) 语句1
输入x 假 X<=1 假 X<10 真 真 y=x+5 y=2x y=3/(x-10) 例:计算分段函数。
#include <stdio.h> 计算分段函数程序 void main() {float x,y; printf("enter x:"); scanf(" %f ",&x); if(x==10) printf("not define x.\n"); else {if (x<=1) y=x+5; else if (x<10) y=2*x; else y=3/(x-10); printf("x=%.2f,y=%.2f\n",x,y); } }