第4章 选择结构程序设计 4.1 选择结构和条件判断 4.2 用if语句实现选择结构 4.3关系运算符和关系表达式 4.4 逻辑运算符和逻辑表达式 4.5 条件运算符和条件表达式 4.6 选择结构的嵌套 4.7 用switch语句实现多分支选择结构 4.8选择结构程序综合举例
4.1 选择结构和条件判断 C语言有两种选择语句: (1)if语句,实现两个分支的选择结构 (2)switch语句,实现多分支的选择结构
4.1 选择结构和条件判断 例4.1 在例3.5的基础上对程序进行改进。题目要求是求 方程的根。 例4.1 在例3.5的基础上对程序进行改进。题目要求是求 方程的根。 由键盘输入a,b,c。假设a,b,c的值任意,并不保证 。需要在程序中进行判别,如果 ,就计算并输出方程的两个实根,否则就输出“方程无实根”的信息。
解题思路: 输入a,b,c 计算disc 假 真 disc>=0 计算x1,x2 输出无实根 输出x1,x2
计算b2-4ac,disc的值变为-15 #include <stdio.h> #include <math.h> int main ( ) { double a,b,c,disc,x1,x2,p,q; scanf("%lf%lf%lf",&a,&b,&c); disc=b*b-4*a*c; 计算b2-4ac,disc的值变为-15
-15<0为真 if (disc<0) printf(“has not real roots\n”); else { p=-b/(2.0*a); q=sqrt(disc)/(2.0*a); x1=p+q; x2=p-q; printf(“real roots:\nx1=%7.2f\n x2=%7.2f\n”,x1,x2); } return 0;
计算b2-4ac,disc的值变为8 #include <stdio.h> #include <math.h> int main ( ) { double a,b,c,disc,x1,x2,p,q; scanf("%lf%lf%lf",&a,&b,&c); disc=b*b-4*a*c; 计算b2-4ac,disc的值变为8
8<0为假 if (disc<0) printf(“has not real roots\n”); else { p=-b/(2.0*a); q=sqrt(disc)/(2.0*a); x1=p+q; x2=p-q; printf(“real roots:\nx1=%7.2f\n x2=%7.2f\n”,x1,x2); } return 0; p的值变为-1 q的值变为0.71 x1的值变为-0.29 x2的值变为-1.71
选择结构,用if语句实现的 if (disc<0) printf(“has not real roots\n”); else { p=-b/(2.0*a); q=sqrt(disc)/(2.0*a); x1=p+q; x2=p-q; printf(“real roots:\nx1=%7.2f\n x2=%7.2f\n”,x1,x2); } return 0; 选择结构,用if语句实现的
复合语句 if (disc<0) printf(“has not real roots\n”); else { p=-b/(2.0*a); q=sqrt(disc)/(2.0*a); x1=p+q; x2=p-q; printf(“real roots:\nx1=%7.2f\n x2=%7.2f\n”,x1,x2); } return 0; 复合语句
4.2 用if语句实现选择结构 4.2.1 用if语句处理选择结构举例 4.2.2 if语句的一般形式
4.2.1 用if语句处理选择结构举例 例4.2 输入两个实数,按代数值由小到大的顺序输出这两个数。
4.2.1 用if语句处理选择结构举例 ★ ● ● ★ 解题思路: 互换前 A B 互换后 A B 只需要做一次比较,然后进行一次交换即可 关键是怎样实现两个变量值的互换 ★ ● 互换前 A B ● ★ 互换后 A B
4.2.1 用if语句处理选择结构举例 C ★ ★ ● A B
4.2.1 用if语句处理选择结构举例 C ★ ★ ● A ● B
4.2.1 用if语句处理选择结构举例 C ★ ● A ● B ★
如果a>b 将a和b的值互换 #include <stdio.h> int main() { float a,b,t; scanf("%f,%f",&a,&b); if(a>b) { t=a; a=b; b=t; } printf("%5.2f,%5.2f\n",a,b); return 0; 如果a>b 将a和b的值互换
选择结构,用if语句实现的 #include <stdio.h> int main() { float a,b,t; scanf("%f,%f",&a,&b); if(a>b) { t=a; a=b; b=t; } printf("%5.2f,%5.2f\n",a,b); return 0; 选择结构,用if语句实现的
解法二: #include <stdio.h> int main() { float a,b,t; scanf("%f,%f",&a,&b); if(a>b) printf("%5.2f,%5.2f\n",b,a); else printf("%5.2f,%5.2f\n",a,b); return 0; } 解法二:
4.2.2 if语句的一般形式 关系表达式 逻辑表达式 数值表达式 if (表达式) 语句1 [ else 语句2 ] 方括号内的部分为可选的
4.2.2 if语句的一般形式 if (表达式) 语句1 [ else 语句2 ] 简单的语句 复合语句 另一个if语句等
最常用的3种if语句形式: 1. if (表达式) 语句1 (没有else子句) 2. if (表达式) 语句1 else 语句2 (有else子句) 3. if(表达式1) 语句1 else if(表达式2) 语句2 else if(表达式3) 语句3 ┆ else if(表达式m) 语句m else 语句m+1 (在else部分又嵌套了多层的if语句)
printf(“%s”,”It is too expensive!”); } …… 表达式 语句1 真(非0) 假 (0) (1)if(表达式)语句1 例: if(price>=500) { printf(“%s”,”It is too expensive!”); } ……
printf(“%s”,”It is too expensive!”); else 条件 语句1 语句2 Y N (2)if(表达式) {语句1} else {语句2} 例: if (price>=500) printf(“%s”,”It is too expensive!”); else printf(“%s”,”It is a good gift!”);
(3)if(表达式1)语句1 else if(表达式2)语句2 else if(表达式3)语句3 …… else if(表达式m)语句m else 语句n
if(price >= 1000) printf(“%s”,”It is too expensive!”); else if (price >= 500) printf(“%s”,”Let me think about it……”); else if (price >= 300) printf(“%s”,”It is a good gift for me!”); else printf(“%s”,”It is a good gift for my mother!”);
练习 有3个整数a,b,c,由键盘输入,输出其中最大的数。
#include <stdio.h> int main() { int a,b,c,t; scanf(“%f,%f,%f ”,&a,&b,&c); if(a>b) t=a; else t=b; if(t<c) t=c; printf(“max=%d\n",t); return 0; }
#include <stdio.h> int main() { int a,b,c,t; scanf(“%f,%f,%f ”,&a,&b,&c); if (a>b) t=a; else if (b>c) t=b; else t=c; printf(“max=%d\n",t); return 0; }
4.3关系运算符和关系表达式 4.3.1关系运算符及其优先次序 4.3.2 关系表达式
4.3.1关系运算符及其优先次序 关系运算符: C语言提供6种关系运算符: 用来对两个数值进行比较的比较运算符 ① < (小于) ② <= (小于或等于) ③ > (大于) ④ >= (大于或等于) ⑤ == (等于) ⑥ != (不等于) 优先级相同 (高) 优先级相同 (低)
4.3.1关系运算符及其优先次序 关系、算术、赋值运算符的优先级 算术运算符 (高) 赋值运算符 (低) 关系运算符
4.3.2 关系表达式 关系表达式 用关系运算符将两个数值或数值表达式连接起来的式子 关系表达式的值是一个逻辑值,即“真”或“假” 在C的逻辑运算中,以“1”代表“真”,以“0”代表“假”
4.4 逻辑运算符和逻辑表达式 4.4.1 逻辑运算符及其优先次序 4.4.2 逻辑表达式 4.4.3 逻辑型变量
4.4.1 逻辑运算符及其优先次序 3种逻辑运算符: &&(逻辑与) ||(逻辑或) !(逻辑非)
4.4.1 逻辑运算符及其优先次序 逻辑运算符的优先次序 ! → && → || (!为三者中最高) 与其他运算符的优先次序 ! (高) ! → && → || (!为三者中最高) 与其他运算符的优先次序 ! (高) 算术运算符 关系运算符 && 和 || 赋值运算符 (低)
4.4.2 逻辑表达式 逻辑表达式的值应该是逻辑量“真”或“假” 编译系统在表示逻辑运算结果时 以数值1代表“真”,以0代表“假” 但在判断一个量是否为“真”时 以0代表“假”,以非0代表“真” 注意:将一个非零的数值认作为“真”
4.4.2 逻辑表达式 判别某一年是否闰年,用逻辑表达式表示 闰年的条件是符合下面二者之一: || year % 400 == 0 ①能被4整除,但不能被100整除,如2008 ②能被400整除,如2000 (year % 4 == 0 && year %100 !=0) || year % 400 == 0 如果表达式值为1,则闰年;否则为非闰年
4.4.3 逻辑型变量 这是C99所增加的一种数据类型 可以将关系运算和逻辑运算的结果存到一个逻辑型变量中,以便于分析和运算 例如 _Bool a; a=5>4;
4.5 条件运算符和条件表达式 有一种if语句,当被判别的表达式的值为“真”或“假” 时,都执行一个赋值语句且向同一个变量赋值 如:if (a>b) max=a; else max=b; 条件运算符 max = (a > b) ? a : b;
4.5 条件运算符和条件表达式 有一种if语句,当被判别的表达式的值为“真”或“假” 时,都执行一个赋值语句且向同一个变量赋值 如:if (a>b) max=a; else max=b; max = (a > b) ? a : b; 条件表达式
4.5 条件运算符和条件表达式 条件表达式的一般形式为 表达式1?表达式2: 表达式3
4.5 条件运算符和条件表达式 条件运算符优先于赋值运算符 条件运算符的结合方向为“自右至左” 以下为合法的使用方法: 如: a?b:c?d:e 以下为合法的使用方法: a>b ? (max=a):(max=b); a>b ? printf(“%d”,a): printf(“%d”,b);
4.6 选择结构的嵌套 在if语句中又包含一个或多个if语句称为if语句的嵌套 一般形式: else 语句2 else if( ) 语句3 else 语句4 在同一个花括号内,else总是与它上面最近的未配对的if配对 内嵌if
4.6 选择结构的嵌套 在if语句中又包含一个或多个if语句称为if语句的嵌套 内嵌if { }限定了内嵌if范围 if () { else语句2 内嵌if { }限定了内嵌if范围
4.6 选择结构的嵌套 #include <stdio.h> int main() { int x,y; 例:输入两个数并判断其大小关系 #include <stdio.h> int main() { int x,y; printf("Enter integer x,y:"); scanf("%d,%d",&x,&y); if(x!=y) if(x>y) printf("X>Y\n"); else printf("X<Y\n"); else printf("X==Y\n"); } Enter integer x,y:12,23 X<Y Enter integer x,y:12,6 X>Y Enter integer x,y:12,12 X==Y
练习 用嵌套if语句输出3个整数中最大的那个。 if (a>b) if (a>c) printf(“max=%d”,a); else printf(“max=%d”,c); else if (b>c) printf(“max=%d”,b);
4.7 用switch语句实现多分支选择结构 switch语句用来实现多分支选择结构 学生成绩分类 85分以上为’A’等 70~84分为’B’等 60~69分为’C’等 …… 人口统计分类 按年龄分为老、中、青、少、儿童
switch语句的作用是根据表达式的值,使流程跳转到不同的语句 switch语句的一般形式: { case 常量1 :语句1 case 常量2 :语句2 ┇ ┇ ┇ case 常量n :语句n default : 语句n+1 } 整数类型(包括字符型)
scanf("%c",&grade); printf("Your score:"); 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("enter data error!\n"); }
scanf("%c",&grade); printf("Your score:"); switch(grade) { case 'A‘: case 'B‘: case 'C': printf("60~69\n");break; case 'D': printf("<60\n");break; default: printf("enter data error!\n"); }
练习 根据输入的字母输出相应的字符串。m- Good morning! n- Good night! h- Hello! 其余-???????? #include <stdio.h> int main() { int c; printf("Enter m or n or h or other:"); c=getchar(); switch(c) { case 'm': printf(" Good morning!\n");break; case 'n': printf(" Good night!\n"); break; case 'h': printf(" Hello!\n"); break; default : printf(" ????????\n"); } return 0;
4.7 用switch语句实现多分支选择结构 例4.6 要求按照考试成绩的等级输出百分制分数段,A等为85分以上,B等为70~84分,C等为60~69分 ,D等为 60分以下 。成绩的等级由键盘输入。
4.7 用switch语句实现多分支选择结构 解题思路: 判断出这是一个多分支选择问题 根据百分制分数将学生成绩分为4个等级 如果用if语句,至少要用3层嵌套的if,进行3次检查判断 用switch语句进行一次检查即可得到结果
#include <stdio.h> int main() { char grade; scanf("%c",&grade); printf("Your score:"); 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("enter data error!\n"); } return 0; 值为A
#include <stdio.h> int main() { char grade; scanf("%c",&grade); printf("Your score:"); 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("enter data error!\n"); } return 0; 不能少
#include <stdio.h> int main() { char grade; scanf("%c",&grade); printf("Your score:"); 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("enter data error!\n"); } return 0; 值为C
#include <stdio.h> int main() { char grade; scanf("%c",&grade); printf("Your score:"); 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("enter data error!\n"); } return 0; 值为F
#include <stdio.h> int main() { char grade; scanf("%c",&grade); printf("Your score:"); 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("enter data error!\n"); } return 0; 此行位置有问题,应如何修改?
例:给出一个百分制成绩,要求输出成绩等级’A’,’B’,’C’,’D’,’E’。90分以上为’A’,80分~89分为’B’,70~79分为’C’,60~69分为’D’,60分以下为’E’。
#include <stdio.h> int main( ) { float score; char grade; printf("请输入学生成绩:"); scanf("%f",&score);
switch((int)(score/10)) { case 10: case 9: grade='A'; break; case 8: grade='B'; break; case 7: grade='C';break; case 6: grade='D';break; default: grade='E';break; }
printf("成绩为%.1f,相应的等级是%c\n",score,grade); return 0; }
4.8选择结构程序综合举例 例4.8 写一程序,判断某一年是否闰年。 解题思路:在前面已介绍过判别闰年的规则 用变量leap代表是否闰年的信息。若闰年,令leap=1;非闰年,leap=0。最后判断leap是否为1(真),若是,则输出“闰年”信息
4.8选择结构程序综合举例
#include <stdio.h> int main() {int year,leap; printf("enter year:"); scanf("%d",&year); if (year%4==0) if(year%100==0) if(year%400==0) leap=1; else leap=0; else leap=1; if (leap) printf("%d is ",year); else printf("%d is not ",year); printf("a leap year.\n"); return 0; } 标志变量 与if (leap!=0)含义相同
#include <stdio.h> int main() {int year,leap; printf("enter year:"); scanf("%d",&year); if (year%4==0) if(year%100==0) if(year%400==0) leap=1; else leap=0; else leap=1; if (leap) printf("%d is ",year); else printf("%d is not ",year); printf("a leap year.\n"); return 0; } 采取锯齿形式
#include <stdio.h> int main() {int year,leap; printf("enter year:"); scanf("%d",&year); if (year%4==0) if(year%100==0) if(year%400==0) leap=1; else leap=0; else leap=1; if (leap) printf("%d is ",year); else printf("%d is not ",year); printf("a leap year.\n"); return 0; } if(year%4!=0) leap=0; else if (year%100!=0) leap=1; else if(year%400!=0) leap=0; else leap=1;
#include <stdio.h> int main() {int year,leap; printf("enter year:"); scanf("%d",&year); if (year%4==0) if(year%100==0) if(year%400==0) leap=1; else leap=0; else leap=1; if (leap) printf("%d is ",year); else printf("%d is not ",year); printf("a leap year.\n"); return 0; } if((year%4==0 && year%100!=0) || (year%400==0)) leap=1; else leap=0;
例4.9 求 方程的解。 解题思路:处理以下各情况 ① a=0,不是二次方程 ② ,有两个相等实根 ③ ,有两个不等实根。 例4.9 求 方程的解。 解题思路:处理以下各情况 ① a=0,不是二次方程 ② ,有两个相等实根 ③ ,有两个不等实根。 ④ ,有两个共轭复根。 应当以p+qi和p-qi的形式输出复根 其中,p=-b/2a,q=( )/2a 参见教材图4.14
#include <stdio.h> #include <math.h> int main() { double a,b,c,disc,x1,x2,realpart, imagpart; scanf("%lf,%lf,%lf",&a,&b,&c); printf("The equation "); if(fabs(a)<=1e-6) printf("is not a quadratic\n"); 实型不能用if (a==0)
else {disc=b*b-4*a*c; if(fabs(disc)<=1e-6) printf("has two equal roots:%8.4f\n", -b/(2*a)); 先算disc,以减少重复计算 不能用if (disc==0)
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); } return 0;
{ 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); } return 0;
{ 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); } return 0;