Download presentation
Presentation is loading. Please wait.
1
第四章 选择结构程序设计 计算机科学学院
2
本章内容: 4.1 关系运算及其表达式 4.2 逻辑运算及其表达式 4.3 if语句 4.4 switch语句 4.5 选择结构程序举例
4.1 关系运算及其表达式 4.2 逻辑运算及其表达式 4.3 if语句 4.4 switch语句 4.5 选择结构程序举例 请做练习
3
4.1 关系运算及其表达式 所谓“关系运算”实际上就是“比较运算”,即将两个数据进行比较,判定两个数据是否符合给定的关系。
4
4.1.1 关系运算符及其优先次序 1.关系运算符 C语言提供6种关系运算符: < <= > >= == !=
关系运算符及其优先次序 1.关系运算符 C语言提供6种关系运算符: < <= > >= == != 注意:在C语言中,“等于”关系运算符是双等号“= =”,而不是单等号“= ”(赋值运算符)。
5
< <= > >= == !=
关系运算符及其优先次序 < <= > >= == != 2.优先级 (1)在关系运算符中,前4个优先级相同,后2个也相同,且前4个高于后2个。 (2)与其它种类运算符的优先级关系 关系运算符的优先级,低于算术运算符,但高于赋值运算符。
6
4.1.2 关系表达式 1.关系表达式的概念 合法 所谓关系表达式是指,用关系运算符将两个表达式连接起来,进行关系运算的式子。
关系表达式 1.关系表达式的概念 所谓关系表达式是指,用关系运算符将两个表达式连接起来,进行关系运算的式子。 例如: 下面的关系表达式都是合法的: a>b,a+b>c-d,(a=3)<=(b=5),'a'>='b',(a>b)= =(b>c) 合法
7
2.关系表达式的值——逻辑值(非“真”即“假”)。 C语言没有逻辑型数据,用整数“1”表示“逻辑真”,用整数“0”表示“逻辑假”。
关系表达式 2.关系表达式的值——逻辑值(非“真”即“假”)。 C语言没有逻辑型数据,用整数“1”表示“逻辑真”,用整数“0”表示“逻辑假”。 由于上述原因,关系表达式的值还可以参与其它种类的运算,例如算术运算、逻辑运算等。
8
(2)(num1>num2)!=num3的值
(2)(num1>num2)!=num3的值 1 (3)num1<num2<num3的值 1 思考题:任意改变num1或num2的值,会影响整个表达式 的值吗?为什么? (4)(num1<num2)+num3 6 返回
9
4.2 逻辑运算及其表达式 用逻辑运算符将关系表达式或逻辑量连接起来的式子就是逻辑表达式。
10
(year%4==0)&&(year%100!=0)||(year%400==0)
逻辑运算及其优先次序 1.逻辑运算符及其运算规则 (1)C语言提供三种逻辑运算符: && || ! 例如,下面的表达式都是逻辑表达式: (x>=0) && (x<10) (x<1) || (x>5) ! (x= =0) (year%4==0)&&(year%100!=0)||(year%400==0)
11
例如,假定x=5,则(x>=0) && (x<10)的 值为“真”,(x<-1) || (x>5)的值为“假”。
逻辑运算及其优先次序 (2)运算规则 1)&&:当且仅当两个运算量的值都为“真”时,运算结果为“真”,否则为“假”。 2) || :当且仅当两个运算量的值都为“假”时,运算结果为“假”,否则为“真”。 3) ! :当运算量的值为“真”时,运算结果为“假”;当运算量的值为“假”时,运算结果为“真”。 例如,假定x=5,则(x>=0) && (x<10)的 值为“真”,(x<-1) || (x>5)的值为“假”。
12
逻辑运算及其优先次序 2.逻辑运算符的运算优先级 (1)逻辑非的优先级最高,逻辑与次之,逻辑或最低,即: ! → && → || (2)与其它种类运算符的优先关系 !→ 算术运算 → 关系运算 → &&→ || → 赋值运算
13
逻辑表达式 1.逻辑表达式的概念 所谓逻辑表达式是指,用逻辑运算符将关系表达式或逻辑量连接起来的式子。在C语言中,用逻辑表达式表示多个条件的组合。 逻辑表达式的值也是一个逻辑值(非“真”即“假”)。
14
num>=1 && num<=31的值为
逻辑表达式 2.逻辑量的真假判定──0和非0 C语言用整数“1”表示“逻辑真”、用“0”表示“逻辑假”。但在判断一个数据的“真”或“假”时,却以0和非0为根据:如果为0,则判定为“逻辑假”;如果为非0,则判定为“逻辑真”。 练习:假设num=12,则: !num的值为? num>=1 && num<=31的值为 1 num || num>31的值为 1
15
4.2.2 逻辑表达式 3.说明 (1)逻辑运算符两侧的操作数,除可以是0和非0的整数外,也可以是其它任何类型的数据,如实型、字符型等。
逻辑表达式 3.说明 (1)逻辑运算符两侧的操作数,除可以是0和非0的整数外,也可以是其它任何类型的数据,如实型、字符型等。 (2)在计算逻辑表达式时,并不是所有的表达式都被求解,只有在必须执行下一个表达式才能求解时,才求解该表达式。 例如,假设n1、n2、n3、n4、x、y的值分别为1、2、3、4、1、1,则求解表达式“(x=n1>n2)&&(y=n3>n4)”后,x的值变为0,而y的值不变,仍等于1! 返回
16
4.3 if语句和条件表达式 if语句 if语句的嵌套 条件运算符 返回
17
if 语句 if语句的形式 形式1:if (表达式) 语句; 表达式 N Y 语句
18
if 语句 if语句的形式 形式2:if (表达式) 语句1 else 语句2; Y 表达式 N 语句1 语句2
19
4.3.1 if语句 if语句的形式 形式3:if (表达式1) 语句1; else if (表达式2) 语句2;
…… else if (表达式m) 语句m; else 语句n;
20
N 表达式1 表达式2 N Y 表达式3 N Y N 表达式4 Y Y 语句1 语句2 语句3 语句4 语句5
21
if语句 if语句的形式 说明: (1)表达式一般为关系表达式或逻辑表达式,也允许是其它类型的数据,如,整型、实型、字符型等,若表达式的值为0,则按假来处理,若表达式的值为非0,则按真来处理。 (2)第2、3种形式的if语句,每个else前都有一个分号,else必须和if配套使用。 (3)“语句1”和“语句2”,可以只包含一个简单语句,也可以是复合语句。
22
4.3.1 if 语句 算法: 1.输入三个数。 2.从前两个数中选最大的赋值给max。
[例4-1] 输入任意三个整数n1、n2、n3,求三个数中的最大值。 算法: 1.输入三个数。 2.从前两个数中选最大的赋值给max。 3.将max与第三个数n3比较,若n3的值大于max,则将其值赋给max。 4.输出max。 请依据算法画出流程图
23
scanf("%d,%d,%d",&n1,&n2,&n3);
试写程序 给n1、n2、n3 输入数值 scanf("%d,%d,%d",&n1,&n2,&n3); if (n1>n2) max=n1; else max=n2; Y N n1>n2 max=n1 max=n2 N if (n3>max) max=n3; n3>max Y max=n3 printf("max=%d\n",max); 输出max 查看完整程序
24
4.3.1 if语句 [例4-1] 输入任意三个整数n1、n2、n3,求三个数中的最大值。 #include “stdio.h”
void main() { int n1,n2,n3,max; printf("Please input three numbers:"); scanf("%d,%d,%d",&n1,&n2,&n3); if (n1>n2) max=n1; else max=n2; if (n3>max) max=n3; printf("The three numbers are:%d,%d,%d\n",n1,n2,n3); printf("max=%d\n",max); } 演示程序
25
如果n1<n2,交换n1和n2的值,如何交换呢?
if语句 [例4-2]输入任意三个数n1、n2、n3,按从大到小的顺序排序输出。 算法: 1.输入三个数。 2.从n1和n2两个数中选较大的赋值给n1 ,较小的赋值给n2。 3.从n2和n3两个数中选较大的赋值给n2 ,较小的赋值给n3。 4.从n1和n2两个数中选较大的赋值给n1 ,较小的赋值给n2。 5.输出n1、n2、n3。 如果n1<n2,交换n1和n2的值,如何交换呢?
26
if (n2<n3) {temp=n2;n2=n3;n3=temp;}
输入数值 n1<n2 n #include “stdio.h” void main() { int n1,n2,n3,temp; printf("Please input three numbers:"); scanf("%d,%d,%d",&n1,&n2,&n3); if (n1<n2) {temp=n1;n1=n2;n2=temp;} if (n2<n3) {temp=n2;n2=n3;n3=temp;} printf("Three numbers after sorted: %d,%d,%d\n",n1,n2,n3); } scanf("%d,%d,%d",&n1,&n2,&n3); y 交换n1和n2的值 if (n1<n2) {temp=n1;n1=n2;n2=temp;} n n2<n3 交换n2和n3的值 if (n2<n3) {temp=n2;n2=n3;n3=temp;} y if (n1<n2) {temp=n1;n1=n2;n2=temp;} n1<n2 交换n1和n2的值 n printf("%d,%d,%d\n",n1,n2,n3); y 输出n1、n2、n3 演示程序 返回
27
4.3.2 if语句的嵌套 if语句的嵌套与嵌套匹配原则
if语句允许嵌套。所谓if语句的嵌套是指,在“语句1”或(和)“语句2”中,又包含有if语句的情况。 if语句嵌套时,else子句与if的匹配原则:与在它上面、距它最近、且尚未匹配的if配对。
28
4.3.2 if语句的嵌套 [例4-3] 有一个函数: 编写一个程序,输入x的值,输出y的值。 Y= -1 1 x<0 x=0
1 x<0 x=0 x>0
29
4.3.2 if语句的嵌套 算法1: 1.输入x。 2.若x<0,y=-1; 3.若x=0,y=0; 4.若x>0,y=1;
n 算法1: 1.输入x。 2.若x<0,y=-1; 3.若x=0,y=0; 4.若x>0,y=1; 5.输出y。 y Y=-1 n x=0 y=0 y x>0 y=-1 n y 请同学们自己写出程序。 输出y
30
4.3.2 if语句的嵌套 算法2: 1.输入x。 2.若x<=0, 若x<0,则y=-1; 否则, y=0; 否则,y=1;
N x<=0 Y N x<0 y=1 y=-1 y=0 输出y 请同学们写出程序……
31
4.3.2 if语句的嵌套 #include “stdio.h” 查看程序 void main( ) { int x,y;
scanf(“%d”,&x); if (x<=0) if (x<0) y=-1; else y=0; else y=1; printf(“y=%d”,y); } 查看程序 你写对了吗?请思考,本例还有哪些算法? 演示程序 返回
32
4.3.3 条件表达式 1.一般格式: 表达式1?表达式2:表达式3
条件表达式 1.一般格式: 表达式1?表达式2:表达式3 条件表达式中的“表达式1”、“表达式2”、“表达式3”的类型,可以各不相同。
33
条件表达式 2.运算规则 如果“表达式1”的值为非0(即逻辑真), 则运算结果等于“表达式2”的值;否则,运算结果等于“表达式3”的值。 3.运算符的优先级与结合性 条件运算符的优先级,高于赋值运算符,但低于关系运算符和算术运算符。其结合性为“从右到左”(即右结合性)。
34
4.3.3 条件表达式 [例4-4] 从键盘上输入一个字符,如果它是大写字母,则把它转换成小写字母输出;否则,直接输出。 输入字符ch
条件表达式 [例4-4] 从键盘上输入一个字符,如果它是大写字母,则把它转换成小写字母输出;否则,直接输出。 输入字符ch If (ch>='A' && ch<='Z') Ch=ch+32; ch=(ch>='A' && ch<='Z') ? (ch+32) : ch; y Ch为大写字母 n 转换为小写字母 输出ch
35
4.3.3 条件表达式 #include “stdio.h” void main() { char ch;
条件表达式 #include “stdio.h” void main() { char ch; printf("Input a character: "); scanf("%c",&ch); ch=(ch>='A' && ch<='Z') ? (ch+32) : ch; printf("ch=%c\n",ch); } 返回 演示程序
36
4.4 switch语句 1.switch语句的一般形式 switch(表达式) { case 常量表达式1:语句组;[break;]
...... case 常量表达式n:语句组;[break;] [default:语句组;[break; ]] }
37
4.4 switch语句 2.执行过程 (1)当switch后面“表达式”的值,与某个case后面的“常量表达式”的值相同时,就执行该case后面的语句(组);当执行到break语句时,跳出switch语句,转向执行switch语句的下一条。 (2)如果没有任何一个case后面的“常量表达式”的值,与“表达式”的值匹配,则执行default 后面的语句(组)。然后,再执行switch语句的下一条。
38
4.4 switch语句 3.说明 (1)switch后面的“表达式”,可以是int、char和枚举型中的一种。
(2)每个case后面“常量表达式”的值,必须各不相同,否则会出现相互矛盾的现象(即对表达式的同一值,有两种或两种以上的执行方案)。 (3)case后面的常量表达式仅起语句标号作用,并不进行条件判断。系统一旦找到入口标号,就从此标号开始执行,不再进行标号判断,所以必须加上break语句,以便结束switch语句。
39
4.4 switch语句 (4)各case及default子句的先后次序,不影响程序执行结果。
(5)用switch语句实现的多分支结构程序,完全可以用if语句或if语句的嵌套来实现。
40
4.4 switch语句 [例4-5] 从键盘上输入一个百分制成绩score,按下列原则输出其等级: score≥90,等级为A;
80≤score<90,等级为B; 70≤score<80,等级为C; 60≤score<70,等级为D; score<60,等级为E。 本题算法: 1.用if语句实现。(请同学们思考……) 2.用if的嵌套实现。 (请同学们思考……) 3.用switch语句实现。
41
思考:如果去掉本程序中的所有break语
4.4 switch语句 main() {int score, grade; printf(“Input a score(0~100): ”); scanf(“%d”, &score); grade = score/10; /*将成绩整除10,转化成switch语句中的case标号*/ switch (grade) {case 10: case 9: printf(“grade=A\n”); break; case 8: printf("grade=B\n"); break; case 7: printf("grade=C\n"); break; case 6: printf("grade=D\n"); break; case 5: case 4: case 3: case 2: case 1: case 0: printf(“grade=E\n”); break; default: printf(“The score is out of range!\n”); } } 思考:本语句有何作用? 演示程序 思考:如果去掉本程序中的所有break语 句,且输入的成绩为75,输出会如何? 返回
42
4.5 选择结构程序设计举例 [例4-6]写一程序,从键盘上输入1年份year(4位十进制数),判断其是否闰年。闰年的条件是:能被4整除、但不能被100整除,或者能被400整除。 [例4-7] 求一元二次方程ax2+bx+c=0的解(a≠0)。 [例4-8] 已知某公司员工的保底薪水为500,某月所接工程的利润profit(整数)与利润提成的关系如下(计量单位:元): profit≤1000 没有提成; 1000<profit≤2000 提成10%; 2000<profit≤5000 提成15%; 5000<profit≤ 提成20%; 10000<profit 提成25%。 返回
43
4.5 选择结构程序设计举例 [例4-6] 输入year 判断year是否 为闰年 Year mod 4==0
4.5 选择结构程序设计举例 [例4-6] Year mod 4==0 Year mod 100==0 Year mod 400==0 Leap=1 Leap=0 y n 输入year 判断year是否 为闰年 输出判断结果
44
4.5 选择结构程序设计举例 void main() {int year,leap=0; /* leap=0:预置为非闰年*/
4.5 选择结构程序设计举例 void main() {int year,leap=0; /* leap=0:预置为非闰年*/ printf("Please input the year:"); 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 a leap year.\n",year); else printf("%d is not a leap year.\n",year); } 注意这里的用法。 返回 演示程序
45
a=0 真 假 b2-4ac=0 假 真 b2-4ac>0 输出 两个 相等 的实 根 真 假 输出 “非二次 方程” 复根: 实部:
[例4-7] a=0 真 假 b2-4ac=0 假 真 b2-4ac>0 输出 两个 相等 的实 根 真 假 输出 “非二次 方程” 复根: 实部: 虚部: 输出两个复根: p+qi,p-qi 输出两个实根: x1,x2
46
{ float a,b,c,disc,x1,x2,p,q; scanf(“%f,%f,%f”, &a, &b, &c);
[例4-7] #include "math.h“ void main() { float a,b,c,disc,x1,x2,p,q; scanf(“%f,%f,%f”, &a, &b, &c); if (a==0) printf(“非二次方程”); else { disc=b*b-4*a*c; if (fabs(disc)<=1e-6) printf(“x1=x2=%7.2f\n”, -b/(2*a)); else { if (disc>1e-6) {x1=(-b+sqrt(disc))/(2*a); x2=(-b-sqrt(disc))/(2*a); printf("x1=%7.2f,x2=%7.2f\n", x1, x2); } else {p=-b/(2*a); q=sqrt(fabs(disc))/(2*a); printf(“x1=%7.2f + %7.2f i\n“, p, q); printf(”x2=%7.2f - %7.2f i\n“, p, q); } } } } 演示程序 返回
47
[例4-8] 演示程序 返回 void main() {long profit; int grade; float salary=500;
printf("Input profit: "); scanf("%ld", &profit); grade= (profit – 1) / 1000; switch(grade) { case 0: break; case 1: salary += profit*0.1; break; case 2: case 3: case 4: salary += profit*0.15; break; case 5: case 6: case 7: case 8: case 9: salary += profit*0.2; break; default: salary += profit*0.25; } printf("salary=%.2f\n", salary); [例4-8] 演示程序 返回
48
练习题: 1.以下程序段中不能根据x的值正确计算出y的值的是______。
A) if(x>0) y=1;else if(x==0) y=0;else y=-1; B) y=0;if(x>0) y=1;else if(x<0) y=-1; C) y=0;if(x>=0)if(x>0) y=1;else y=-1; D) if(x>=0) if(x>0) y=1;else y=0;else y=-1; C
49
练习题: 2.有以下程序 main() { int a=15,b=21,m=0; switch(a%3) {
case 0: m++;break; case 1: m++; switch(b%2) { default:m++; case 0:m++;break; } } printf(“%d\n”,m); } 程序运行后的输出结果是______。 A) 1 B) 2 C) 3 D) 4 A 返回
50
#include "stdio.h" #define N 7 int main() { int i,j,t,a[N]; for(i=0;i<=N-1;i++) scanf("%d",&a[i]); for(i=1;i<=N-1;i++) for(j=1;j<=N-i;j++) if(a[j-1]<a[j]) t=a[j-1]; a[j-1]=a[j]; a[j]=t; } printf("%d ",a[i]);
51
输入N个数 对N个数进行排序 输出N个数
52
i=1 i<=N-1 N Y 第i趟排序 i++
53
j=1 j<=N-i N Y a[j-1]>a[j] N Y 交换a[j-1]和a[j] j++
Similar presentations