第五章 选择结构程序设计
表达式
关系 表达式
逻辑 表达式
条件 表达式
语句
if语句与条件运算符
多分支语句 ( switch)
§ 5.1 关系运算符和关系表达式比较 两个量 (x,y)之间关系的 6种形式:
x < y x <= y x = = y
x > y x >= y x != y
比较的结果:
成立 如,3>1
或 不成立 如,1>3
int x=6; x>=1
int x=6; x<2
比较结果的表示结果 成立 1 不成立 0
例,int x=2,y=6;
x =( y>3) 结果,x=1
x =( x>y) x=0
§ 5.1 关系运算符和关系表达式
运算符优先级,算术运算符 高
<,<=,>,>=
= =,!=
=,+= 低
例:
2,b - 1 != a >= c = = 3
相当于 ((b - 1) != (a >= c )) = =3
该表达式结果为 0
1,d = b+2 = = 3
若 b=1 则 d=1,其他 b 则 d=0
§ 5.1 关系运算符和关系表达式
运算符优先级,算术运算符 高
<,<=,>,>=
= =,!=
=,+= 低
例:
3,x = 3 < y < 5,若 y=2,x=?
若 y=4,x=?
等价 x = ( 3<y ) < 5
= 1
关系表达式只能比较两个量之间的关系,若要表达三个量之间的关系必须使用逻辑表达式
§ 5.2 逻辑运算符和逻辑表达式
3 < x < 5
0 3 5 x
x > 3 并且 x < 5
逻辑运算符逻辑表达式逻辑表达式,用逻辑运算符连接多个关系表达式,以表示一种复杂的关系
§ 5.2 逻辑运算符和逻辑表达式
X&&Y X||Y
X Y X Y
!X X
与 或非
逻辑与 && 逻辑或 || 逻辑非 !
例 (x>1)&&(y>1) (x>1)||(y>1) !(x>1)
y y
1
x<=1
x x
– 1
§ 5.2 逻辑运算符和逻辑表达式
§ 5.2 逻辑运算符和逻辑表达式
逻辑与 && 逻辑或 || 逻辑非 !
x y x&&y x||y x !x
0 0 0 0 0 1
0 1 0 1 非 0 0
1 0 0 1
1 1 1 1
* +
同时成立 只要有一个成立并且 或者
5&&7是否合法?
0 0
0 非 0
非 0 0
非 0 非 0 ! !5 =?
(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 。
所谓逻辑表达式是指,用逻辑运算符将 1个或多个表达式连接起来,进行逻辑运算的式子。在 C语言中,用逻辑表达式表示多个条件的组合。
逻辑与&& 逻辑或 || 逻辑非 !
运算优先级:
! 算术运算符 <,<=,>,>=
= =,!= && ||
例:设 x = 1,y = 2,c = 0
x >= y = = c && !x+2 > 30 0
1 2 0
0
§ 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)
§ 5.2 逻辑运算符和逻辑表达式例:写出判断下例要求的表达式:
⑴ ch 是小写英文字母 。
ch >= 'a' && ch <= 'z'。
⑵ x 为零 。
关系表达式 x = = 0
或 逻辑表达式 !x
验证,当,x= 0 !x=1 成立当,x不等于 0 !x=0 不成立当,x= 0 x= =0 成立当,x!=0 x= =0 不成立等价
⑶ x 不为零 。
x! =0 或 x
§ 5.2 逻辑运算符和逻辑表达式例,⑷ x 和 y 不同时为零 。
x != 0 || y!=0
或 !(x = = 0 && y = = 0)
(5) year 是闰年,即 year 能被 4 整除但不能被 100
整除,或 year 能被 400 整除 。
逻辑表达式 (year % 4 = = 0 && year % 100 != 0) ||
(year % 400 = = 0)
x >1
§ 5.3 if语句
语句形式:
(1).if ( 表达式 ) 语句例,if ( x > 1 ) printf("%d",x);
printf(”the end !”);
否是
printf("%d",x);
printf(”the end !”)
①
②
语句①
语句②
例:比较两数大小并输出最大值
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);
}
本例程序中,输入两个数 a,b。 把 a先赋予变量 max
,再用 if语句判别 max和 b的大小,如 max小于 b,
则把 b赋予 max。 因此 max中总是大数,最后输出
max的值。
x > y
printf("%d",x);
printf(”the end !”)
(2),if ( 表达式 )
语句 1
else
语句 2
例,if ( x > y ) printf("%d",x);
else printf("%d",y);
printf(”the end !”);
否
printf("%d",y);
①
②
①
② 选择一条执行输入两个整数,输出其中的大数 。
改用 if-else语句判别 a,b的大小,若 a大,则输出 a,否则输出 b
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 (表达式 1)语句 1
else if (表达式 2) 语句 2
else if (表达式 3) 语句 3
......
else if (表达式 m) 语句 m
else 语句 n
例 5.1输入两个实数,按代数值由小到大的次序输出这两个数 。
main()
{
float a,b,t;
scanf(”% f,% f”,&a,&b);
if(a>b)
{ t=a;a=b;b=t;}
printf(”% 5.2f,% 5.2f,a,b);
} 结果,3.6,-3.2 ↙
-3.2,3.6
例 5.2 输入 3个数 a,b,c要求按由小到大的顺序输出算法如下:
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 (a>b)
{t=a;a=b;b=t;}
if (a>c)
{t=a;a=c;c=t;}
if (b>c)
{t=b;b=c;c=t;}
printf("%5.2f,%5.2f,%5.2f",a,b,c);
}
这种编程的基本思想是:首先取一个数预置为 max( 最大值),然后再用 max依次与其余的数逐个比较,如果发现有比 max大的,
就用它给 max重新赋值,比较完所有的数后,
max中的数就是最大值。这种方法,对从 3
个或 3个以上的数中找最大值的处理,非常有效。请同学们仔细体会。
例 5.3:
if (x<-1) y=-1;
if (x>=-1&&x<1) y=0;
if (x>=1) y=1;
也可写成:
if (x>=1) y = 1 ;
else if (x>=-1) y=0 ;else y = -1
Fx>1
x>=-
1
y=1 y=0 语句 n-1 语句 n
T
表达式 n-1 0
非 0
F
0
T
y=-1
下一条语句
if语句中又包含 if语句 ( 三种形式之一 ),
if ( )
if ( ) 语句 1
else 语句 2
else
if ( ) 语句 3
else 语句 4
if语句的嵌套
if ( )
if ( ) 语句 1
else
if ( ) 语句 2
else 语句 3
以下写法该如何理解( if与 else不 一致)?
if与 else的配对原则:
else向靠得最近的 if匹配
if ()
{ if ( ) 语句 1 } (内嵌 if)
else 语句 2
为明确匹配关系,避免匹配错误,
强烈建议,将内嵌的 if语句,一律用花括号括起来 。
§ 5.3 if语句
注意,
(1),if 和 else分别要处理的内容应尽量不重复 。
if (考试== 100分 )
{ 吃饭 ;吃苹果; }
else 吃饭 ;
§ 5.3 if语句
注意,
(2).else不是必须的 if( 考试==100分 )
吃苹果;
(3) 注意 if条件的写法
if (考试 != 100分 )吃苹果 ; if (考试 == 100分 )
吃饭;
if( 考试==100分)
吃苹果;
else
没事
§ 5.3 if语句
注意,
(4) if (表达式 ) 语句例 if (x) x=1/x ;
意思为:如果 x!=0 则 x=1/x ;
例 if (x+3) x++ ;
任意表达式 根据任意 表达式的值是否 = 0,
决定条件是否成立。
§ 5.3 if语句
注意,
(5) 当不止一条语句时,必须加上 { }构成一个复合语句
if (a > b) { if (a>b)
t = a; t = a;
a = b; a = b;
b = t; b = t;
}
§ 5.4 条件运算符
if ( a > b )
max = a ;
else
max = b ;
条件运算符表达式,
(条件 )? 满足时取的值,不满足时取的值
max = ( a > b )? a,b
例如条件语句:
if(a>b) max=a;
else max=b;
可用条件表达式写为
max=(a>b)?a:b;
执行该语句的语义是,如 a>b为真,则把 a赋予 max,否则把 b 赋予 max。
条件运算符的优先级与结合性条件运算符的优先级,高于赋值运算符,但低于关系运算符和算术运算符 。 其结合性为,从右到左,( 即右结合性 ) 。
1.max=(a>b)?a:b
可以去掉括号而写为
max=a>b?a:b
2.a>b?a:c>d?c:d
应理解为
a>b?a:(c>d?c:d)
例 5.4 从键盘上输入一个字符,如果它是大写字母,
则把它转换成小写字母输出;否则,直接输出 。
main()
{ char ch;
printf("Input a character,");
scanf("%c",&ch);
ch=(ch>='A' && ch<='Z')? (ch+32),ch;
printf("ch=%c\n",ch);
}
例,学生成绩分类:
A ( >=90),B ( 80~ 89),C ( 70~ 79),
D ( 60~ 69),E ( <=60) 已知分数 分类
#include <stdio.h>
main(){
int score;
scanf("%d",&score);
if ( score>= 90 ) printf("A\n");
if ( score<90 && score>=80 ) printf("B\n");
if ( score<80 && score>=70 ) printf("C\n");
if ( score<70 && score>=60 ) printf("D\n");
if ( score < 60) printf("E\n");
}
或写成:
#include <stdio.h>
main(){
int score;
scanf("%d",&score);
if ( score >= 90 ) printf("A\n");
else /* score < 90 */
if ( score>=80 ) printf("B\n");
else /* score < 80 */
if ( score>=70 ) printf("C\n");
else /* score < 70 */
if ( score>=60 ) printf("D\n");
else printf("E\n") ;
/* score < 60 */
}
if 嵌套
0表达式
1
表达式
2
语句 1 语句 2 语句 n-1 语句 n
非 0
表达式 n-1 0
非 0
0
0
非 0
n个分支需要 n-1次比较
§ 5.5 多分支语句( switch)
#include <stdio.h>
main() {
int score;
scanf("%d",&score);
switch(score/10) {
case 10:
case 9,printf("A\n"); break ;
case 8,printf("B\n"); break ;
case 7,printf("C\n"); break ;
case 6,printf("D\n"); break ;
default,printf("E\n"); break ;}
}
须 int 或 char型
§ 5.5 多分支语句 ( switch)
switch语句形式,
switch( 表达式 )
{ case 常量 表达式1:语句 段1 ;
case 常量 表达式2:语句 段2 ;
....…
case 常量 表达式n:语句 段n ;
default,语句 段n+1 ;
}
可多条语句可依情况省略执行过程,计算表达式的值 。 并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时,即执行其后的语句,然后不再进行判断,继续执行后面所有 case后的语句 。 如表达式的值与所有 case
后的 常量表达 式均不相 同时,则 执行
default后的语句 。
§ 5.5 多分支语句( switch)
#include <stdio.h>
main() {
int score;
scanf("%d",&score);
switch(score/10)
{ case 10:
case 9,printf("A\n"); break ;
case 8,printf("B\n"); break ;
case 7,printf("C\n"); break ;
case 6,printf("D\n"); break ;
default,printf("E\n"); break ;
}
}
应各不相同各常量表达式值值为 10时没有指定语句,
将顺序执行下一种情况的语句说明
( 1) switch后面的“表达式”,可以是 int,char和枚举型中的一种。
( 2)每个 case后面“常量表达式”的值,必须各不相同,否则会出现相互矛盾的现象(即对表达式的同一值,有两种或两种以上的执行方案)。
( 3) case后面的常量表达式仅起语句标号作用,并不进行条件判断 。系统一旦找到入口标号,就从此标号开始执行,不再进行标号判断,所以必须加上 break语句,以便结束 switch语句。
§ 5.5 多分支语句( switch)
#include <stdio.h>
main() {
int score;
scanf("%d",&score);
switch(score/10)
{ case 10:
case 9,printf("A\n"); break ;
case 8,printf("B\n"); break ;
case 7,printf("C\n"); break ;
case 6,printf("D\n"); break ;
default,printf("E\n"); break ;
}
}
一般需要 break配合使用输入:
77
输出:
C
D
E
输入:
94
输出:
A
B
C
D
E
§ 5.5 多分支语句已知分类 分数
#include <stdio.h>
main() {
char grade;
scanf("%c",&grade);
if (grade =='A') printf("90~ 100\n") ;
if (grade =='B') printf("80~ 89\n") ;
if (grade =='C') printf("70~ 79\n") ;
if (grade =='D') printf("60~ 69\n") ;
if (grade =='E') printf("<=60\n") ;
}
§ 5.5 多分支语句已知分类 分数
#inclde <stdio.h>
main() {
char grade;
scanf("%c",&grade);
switch(grade)
{ case 'A',printf("90~ 100\n”);break;
case 'B',printf("80~ 89\n”); break;
case 'C',printf("70~ 79\n”); break;
case 'D',printf("60~ 69\n”); break;
case 'E',printf("<=60\n”); break;
}
}
§ 5.5 多分支语句 ( switch)
case语句中的表达式有时很难写得出 。
编程,输入值求范围假定,0 ~ 1.5 A
1.5 ~ 3 B
3 ~ 4.5 C
4.5 ~ 6 D
如何用 case语句表示?
分析,每段间隔 1.5,由于
case所列值的类型必须是
int或 char,而 1.5是实型。
关键,把 1.5 的间隔转换成 int
可采用强制类型转换
(int)( x/1.5)
§ 5.5 多分支语句( switch)
#include <stdio.h>
main()
{
float score;
scanf("%f",&score);
switch((int)(score/1.5))
{ case 0,printf("A\n"); break ;
case 1,printf("B\n"); break ;
case 2,printf("C\n"); break ;
case 3,printf("D\n"); break ;
}
}
§ 5.5 多分支语句 ( switch)
编程,输入值求范围假定,0 ~ 1.5 A
1.5 ~ 4.5 B
4.5 ~ 6 C
如何用 case语句表示?
如果 1.5改成 1.4还能实现吗?
switch((int)(score/1.5))
{ case 0,printf("A\n"); break ;
case 1,
case 2,printf(”B\n"); break ;
case 3,printf(”C\n"); break ;
}
[例 5.6] 求一元二次方程 ax2+bx+c=0的解( a≠0)。
#include "math.h"
main()
{float a,b,c,disc,x1,x2,p,q;
scanf(“%f,%f,%f”,&a,&b,&c);
disc=b*b-4*a*c;
if (fabs(disc)<=1e-6) /*fabs(),求绝对值库函数 */
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);
}
}
}
说明,由于实数在计算机中存储时,经常会有一些微小误差,所以本案例判断 disc是否为 0的方法是:
判断 disc的绝对值是否小于一个很小的数(例如
10-6)。
思考题,如果将系数 a,b,c定义成整数,能否直接判断 disc是否等于 0?
[例 5.7] 已知某公司员工的保底薪水为 500,某月所接工程的利润 profit( 整数 ) 与利润提成的关系如下 ( 单位:元 ),
profit≤1000 没有提成;
1000< profit≤2000 提成 10%;
2000< profit≤5000 提成 15%;
5000< profit≤10000 提成 20%;
10000< profit 提成 25%。
算法设计要点:
为使用 switch语句,必须将利润 profit与提成的关系,转换成某些整数与提成的关系 。 分析本题可知,提成的变化点都是 1000的整数倍 ( 1000,2000,5000,……),如果将利润 profit整除 1000,则当:
profit≤1000 对应 0,1
1000< profit≤2000 对应 1,2
2000< profit≤5000 对应 2,3,4,5
5000< profit≤10000 对应 5,6,7,8,9,10
10000< profit 对应 10,11,12,……
为解决相邻两个区间的重叠问题,最简单的方法就是:利润
profit先减 1( 最小增量 ),然后再整除 1000即可:
profit≤1000 对应 0
1000< profit≤2000 对应 1
2000< profit≤5000 对应 2,3,4
5000< profit≤10000 对应 5,6,7,8,9
10000< profit 对应 10,11,12,……
main()
{long profit;
int grade;
float salary=500;
printf("Input profit,");
scanf("%ld",&profit);
grade= (profit – 1) / 1000; /*将利润 -1,再整除 1000,
转化成 switch语句中的 case标号 */
switch(grade)
{ case 0,break; /*profit≤1000 */
case 1,salary += profit*0.1; break; /*1000< profit≤2000 */
case 2:
case 3:
case 4,salary += profit*0.15; break; /*2000< profit≤5000 */
case 5:
case 6:
case 7:
case 8:
case 9,salary += profit*0.2; break; /*5000< profit≤10000 */
default,salary += profit*0.25; /*10000< profit */
}
printf("salary=%.2f\n",salary);
}
表达式
关系 表达式
逻辑 表达式
条件 表达式
语句
if语句与条件运算符
多分支语句 ( switch)
§ 5.1 关系运算符和关系表达式比较 两个量 (x,y)之间关系的 6种形式:
x < y x <= y x = = y
x > y x >= y x != y
比较的结果:
成立 如,3>1
或 不成立 如,1>3
int x=6; x>=1
int x=6; x<2
比较结果的表示结果 成立 1 不成立 0
例,int x=2,y=6;
x =( y>3) 结果,x=1
x =( x>y) x=0
§ 5.1 关系运算符和关系表达式
运算符优先级,算术运算符 高
<,<=,>,>=
= =,!=
=,+= 低
例:
2,b - 1 != a >= c = = 3
相当于 ((b - 1) != (a >= c )) = =3
该表达式结果为 0
1,d = b+2 = = 3
若 b=1 则 d=1,其他 b 则 d=0
§ 5.1 关系运算符和关系表达式
运算符优先级,算术运算符 高
<,<=,>,>=
= =,!=
=,+= 低
例:
3,x = 3 < y < 5,若 y=2,x=?
若 y=4,x=?
等价 x = ( 3<y ) < 5
= 1
关系表达式只能比较两个量之间的关系,若要表达三个量之间的关系必须使用逻辑表达式
§ 5.2 逻辑运算符和逻辑表达式
3 < x < 5
0 3 5 x
x > 3 并且 x < 5
逻辑运算符逻辑表达式逻辑表达式,用逻辑运算符连接多个关系表达式,以表示一种复杂的关系
§ 5.2 逻辑运算符和逻辑表达式
X&&Y X||Y
X Y X Y
!X X
与 或非
逻辑与 && 逻辑或 || 逻辑非 !
例 (x>1)&&(y>1) (x>1)||(y>1) !(x>1)
y y
1
x<=1
x x
– 1
§ 5.2 逻辑运算符和逻辑表达式
§ 5.2 逻辑运算符和逻辑表达式
逻辑与 && 逻辑或 || 逻辑非 !
x y x&&y x||y x !x
0 0 0 0 0 1
0 1 0 1 非 0 0
1 0 0 1
1 1 1 1
* +
同时成立 只要有一个成立并且 或者
5&&7是否合法?
0 0
0 非 0
非 0 0
非 0 非 0 ! !5 =?
(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 。
所谓逻辑表达式是指,用逻辑运算符将 1个或多个表达式连接起来,进行逻辑运算的式子。在 C语言中,用逻辑表达式表示多个条件的组合。
逻辑与&& 逻辑或 || 逻辑非 !
运算优先级:
! 算术运算符 <,<=,>,>=
= =,!= && ||
例:设 x = 1,y = 2,c = 0
x >= y = = c && !x+2 > 30 0
1 2 0
0
§ 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)
§ 5.2 逻辑运算符和逻辑表达式例:写出判断下例要求的表达式:
⑴ ch 是小写英文字母 。
ch >= 'a' && ch <= 'z'。
⑵ x 为零 。
关系表达式 x = = 0
或 逻辑表达式 !x
验证,当,x= 0 !x=1 成立当,x不等于 0 !x=0 不成立当,x= 0 x= =0 成立当,x!=0 x= =0 不成立等价
⑶ x 不为零 。
x! =0 或 x
§ 5.2 逻辑运算符和逻辑表达式例,⑷ x 和 y 不同时为零 。
x != 0 || y!=0
或 !(x = = 0 && y = = 0)
(5) year 是闰年,即 year 能被 4 整除但不能被 100
整除,或 year 能被 400 整除 。
逻辑表达式 (year % 4 = = 0 && year % 100 != 0) ||
(year % 400 = = 0)
x >1
§ 5.3 if语句
语句形式:
(1).if ( 表达式 ) 语句例,if ( x > 1 ) printf("%d",x);
printf(”the end !”);
否是
printf("%d",x);
printf(”the end !”)
①
②
语句①
语句②
例:比较两数大小并输出最大值
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);
}
本例程序中,输入两个数 a,b。 把 a先赋予变量 max
,再用 if语句判别 max和 b的大小,如 max小于 b,
则把 b赋予 max。 因此 max中总是大数,最后输出
max的值。
x > y
printf("%d",x);
printf(”the end !”)
(2),if ( 表达式 )
语句 1
else
语句 2
例,if ( x > y ) printf("%d",x);
else printf("%d",y);
printf(”the end !”);
否
printf("%d",y);
①
②
①
② 选择一条执行输入两个整数,输出其中的大数 。
改用 if-else语句判别 a,b的大小,若 a大,则输出 a,否则输出 b
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 (表达式 1)语句 1
else if (表达式 2) 语句 2
else if (表达式 3) 语句 3
......
else if (表达式 m) 语句 m
else 语句 n
例 5.1输入两个实数,按代数值由小到大的次序输出这两个数 。
main()
{
float a,b,t;
scanf(”% f,% f”,&a,&b);
if(a>b)
{ t=a;a=b;b=t;}
printf(”% 5.2f,% 5.2f,a,b);
} 结果,3.6,-3.2 ↙
-3.2,3.6
例 5.2 输入 3个数 a,b,c要求按由小到大的顺序输出算法如下:
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 (a>b)
{t=a;a=b;b=t;}
if (a>c)
{t=a;a=c;c=t;}
if (b>c)
{t=b;b=c;c=t;}
printf("%5.2f,%5.2f,%5.2f",a,b,c);
}
这种编程的基本思想是:首先取一个数预置为 max( 最大值),然后再用 max依次与其余的数逐个比较,如果发现有比 max大的,
就用它给 max重新赋值,比较完所有的数后,
max中的数就是最大值。这种方法,对从 3
个或 3个以上的数中找最大值的处理,非常有效。请同学们仔细体会。
例 5.3:
if (x<-1) y=-1;
if (x>=-1&&x<1) y=0;
if (x>=1) y=1;
也可写成:
if (x>=1) y = 1 ;
else if (x>=-1) y=0 ;else y = -1
Fx>1
x>=-
1
y=1 y=0 语句 n-1 语句 n
T
表达式 n-1 0
非 0
F
0
T
y=-1
下一条语句
if语句中又包含 if语句 ( 三种形式之一 ),
if ( )
if ( ) 语句 1
else 语句 2
else
if ( ) 语句 3
else 语句 4
if语句的嵌套
if ( )
if ( ) 语句 1
else
if ( ) 语句 2
else 语句 3
以下写法该如何理解( if与 else不 一致)?
if与 else的配对原则:
else向靠得最近的 if匹配
if ()
{ if ( ) 语句 1 } (内嵌 if)
else 语句 2
为明确匹配关系,避免匹配错误,
强烈建议,将内嵌的 if语句,一律用花括号括起来 。
§ 5.3 if语句
注意,
(1),if 和 else分别要处理的内容应尽量不重复 。
if (考试== 100分 )
{ 吃饭 ;吃苹果; }
else 吃饭 ;
§ 5.3 if语句
注意,
(2).else不是必须的 if( 考试==100分 )
吃苹果;
(3) 注意 if条件的写法
if (考试 != 100分 )吃苹果 ; if (考试 == 100分 )
吃饭;
if( 考试==100分)
吃苹果;
else
没事
§ 5.3 if语句
注意,
(4) if (表达式 ) 语句例 if (x) x=1/x ;
意思为:如果 x!=0 则 x=1/x ;
例 if (x+3) x++ ;
任意表达式 根据任意 表达式的值是否 = 0,
决定条件是否成立。
§ 5.3 if语句
注意,
(5) 当不止一条语句时,必须加上 { }构成一个复合语句
if (a > b) { if (a>b)
t = a; t = a;
a = b; a = b;
b = t; b = t;
}
§ 5.4 条件运算符
if ( a > b )
max = a ;
else
max = b ;
条件运算符表达式,
(条件 )? 满足时取的值,不满足时取的值
max = ( a > b )? a,b
例如条件语句:
if(a>b) max=a;
else max=b;
可用条件表达式写为
max=(a>b)?a:b;
执行该语句的语义是,如 a>b为真,则把 a赋予 max,否则把 b 赋予 max。
条件运算符的优先级与结合性条件运算符的优先级,高于赋值运算符,但低于关系运算符和算术运算符 。 其结合性为,从右到左,( 即右结合性 ) 。
1.max=(a>b)?a:b
可以去掉括号而写为
max=a>b?a:b
2.a>b?a:c>d?c:d
应理解为
a>b?a:(c>d?c:d)
例 5.4 从键盘上输入一个字符,如果它是大写字母,
则把它转换成小写字母输出;否则,直接输出 。
main()
{ char ch;
printf("Input a character,");
scanf("%c",&ch);
ch=(ch>='A' && ch<='Z')? (ch+32),ch;
printf("ch=%c\n",ch);
}
例,学生成绩分类:
A ( >=90),B ( 80~ 89),C ( 70~ 79),
D ( 60~ 69),E ( <=60) 已知分数 分类
#include <stdio.h>
main(){
int score;
scanf("%d",&score);
if ( score>= 90 ) printf("A\n");
if ( score<90 && score>=80 ) printf("B\n");
if ( score<80 && score>=70 ) printf("C\n");
if ( score<70 && score>=60 ) printf("D\n");
if ( score < 60) printf("E\n");
}
或写成:
#include <stdio.h>
main(){
int score;
scanf("%d",&score);
if ( score >= 90 ) printf("A\n");
else /* score < 90 */
if ( score>=80 ) printf("B\n");
else /* score < 80 */
if ( score>=70 ) printf("C\n");
else /* score < 70 */
if ( score>=60 ) printf("D\n");
else printf("E\n") ;
/* score < 60 */
}
if 嵌套
0表达式
1
表达式
2
语句 1 语句 2 语句 n-1 语句 n
非 0
表达式 n-1 0
非 0
0
0
非 0
n个分支需要 n-1次比较
§ 5.5 多分支语句( switch)
#include <stdio.h>
main() {
int score;
scanf("%d",&score);
switch(score/10) {
case 10:
case 9,printf("A\n"); break ;
case 8,printf("B\n"); break ;
case 7,printf("C\n"); break ;
case 6,printf("D\n"); break ;
default,printf("E\n"); break ;}
}
须 int 或 char型
§ 5.5 多分支语句 ( switch)
switch语句形式,
switch( 表达式 )
{ case 常量 表达式1:语句 段1 ;
case 常量 表达式2:语句 段2 ;
....…
case 常量 表达式n:语句 段n ;
default,语句 段n+1 ;
}
可多条语句可依情况省略执行过程,计算表达式的值 。 并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时,即执行其后的语句,然后不再进行判断,继续执行后面所有 case后的语句 。 如表达式的值与所有 case
后的 常量表达 式均不相 同时,则 执行
default后的语句 。
§ 5.5 多分支语句( switch)
#include <stdio.h>
main() {
int score;
scanf("%d",&score);
switch(score/10)
{ case 10:
case 9,printf("A\n"); break ;
case 8,printf("B\n"); break ;
case 7,printf("C\n"); break ;
case 6,printf("D\n"); break ;
default,printf("E\n"); break ;
}
}
应各不相同各常量表达式值值为 10时没有指定语句,
将顺序执行下一种情况的语句说明
( 1) switch后面的“表达式”,可以是 int,char和枚举型中的一种。
( 2)每个 case后面“常量表达式”的值,必须各不相同,否则会出现相互矛盾的现象(即对表达式的同一值,有两种或两种以上的执行方案)。
( 3) case后面的常量表达式仅起语句标号作用,并不进行条件判断 。系统一旦找到入口标号,就从此标号开始执行,不再进行标号判断,所以必须加上 break语句,以便结束 switch语句。
§ 5.5 多分支语句( switch)
#include <stdio.h>
main() {
int score;
scanf("%d",&score);
switch(score/10)
{ case 10:
case 9,printf("A\n"); break ;
case 8,printf("B\n"); break ;
case 7,printf("C\n"); break ;
case 6,printf("D\n"); break ;
default,printf("E\n"); break ;
}
}
一般需要 break配合使用输入:
77
输出:
C
D
E
输入:
94
输出:
A
B
C
D
E
§ 5.5 多分支语句已知分类 分数
#include <stdio.h>
main() {
char grade;
scanf("%c",&grade);
if (grade =='A') printf("90~ 100\n") ;
if (grade =='B') printf("80~ 89\n") ;
if (grade =='C') printf("70~ 79\n") ;
if (grade =='D') printf("60~ 69\n") ;
if (grade =='E') printf("<=60\n") ;
}
§ 5.5 多分支语句已知分类 分数
#inclde <stdio.h>
main() {
char grade;
scanf("%c",&grade);
switch(grade)
{ case 'A',printf("90~ 100\n”);break;
case 'B',printf("80~ 89\n”); break;
case 'C',printf("70~ 79\n”); break;
case 'D',printf("60~ 69\n”); break;
case 'E',printf("<=60\n”); break;
}
}
§ 5.5 多分支语句 ( switch)
case语句中的表达式有时很难写得出 。
编程,输入值求范围假定,0 ~ 1.5 A
1.5 ~ 3 B
3 ~ 4.5 C
4.5 ~ 6 D
如何用 case语句表示?
分析,每段间隔 1.5,由于
case所列值的类型必须是
int或 char,而 1.5是实型。
关键,把 1.5 的间隔转换成 int
可采用强制类型转换
(int)( x/1.5)
§ 5.5 多分支语句( switch)
#include <stdio.h>
main()
{
float score;
scanf("%f",&score);
switch((int)(score/1.5))
{ case 0,printf("A\n"); break ;
case 1,printf("B\n"); break ;
case 2,printf("C\n"); break ;
case 3,printf("D\n"); break ;
}
}
§ 5.5 多分支语句 ( switch)
编程,输入值求范围假定,0 ~ 1.5 A
1.5 ~ 4.5 B
4.5 ~ 6 C
如何用 case语句表示?
如果 1.5改成 1.4还能实现吗?
switch((int)(score/1.5))
{ case 0,printf("A\n"); break ;
case 1,
case 2,printf(”B\n"); break ;
case 3,printf(”C\n"); break ;
}
[例 5.6] 求一元二次方程 ax2+bx+c=0的解( a≠0)。
#include "math.h"
main()
{float a,b,c,disc,x1,x2,p,q;
scanf(“%f,%f,%f”,&a,&b,&c);
disc=b*b-4*a*c;
if (fabs(disc)<=1e-6) /*fabs(),求绝对值库函数 */
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);
}
}
}
说明,由于实数在计算机中存储时,经常会有一些微小误差,所以本案例判断 disc是否为 0的方法是:
判断 disc的绝对值是否小于一个很小的数(例如
10-6)。
思考题,如果将系数 a,b,c定义成整数,能否直接判断 disc是否等于 0?
[例 5.7] 已知某公司员工的保底薪水为 500,某月所接工程的利润 profit( 整数 ) 与利润提成的关系如下 ( 单位:元 ),
profit≤1000 没有提成;
1000< profit≤2000 提成 10%;
2000< profit≤5000 提成 15%;
5000< profit≤10000 提成 20%;
10000< profit 提成 25%。
算法设计要点:
为使用 switch语句,必须将利润 profit与提成的关系,转换成某些整数与提成的关系 。 分析本题可知,提成的变化点都是 1000的整数倍 ( 1000,2000,5000,……),如果将利润 profit整除 1000,则当:
profit≤1000 对应 0,1
1000< profit≤2000 对应 1,2
2000< profit≤5000 对应 2,3,4,5
5000< profit≤10000 对应 5,6,7,8,9,10
10000< profit 对应 10,11,12,……
为解决相邻两个区间的重叠问题,最简单的方法就是:利润
profit先减 1( 最小增量 ),然后再整除 1000即可:
profit≤1000 对应 0
1000< profit≤2000 对应 1
2000< profit≤5000 对应 2,3,4
5000< profit≤10000 对应 5,6,7,8,9
10000< profit 对应 10,11,12,……
main()
{long profit;
int grade;
float salary=500;
printf("Input profit,");
scanf("%ld",&profit);
grade= (profit – 1) / 1000; /*将利润 -1,再整除 1000,
转化成 switch语句中的 case标号 */
switch(grade)
{ case 0,break; /*profit≤1000 */
case 1,salary += profit*0.1; break; /*1000< profit≤2000 */
case 2:
case 3:
case 4,salary += profit*0.15; break; /*2000< profit≤5000 */
case 5:
case 6:
case 7:
case 8:
case 9,salary += profit*0.2; break; /*5000< profit≤10000 */
default,salary += profit*0.25; /*10000< profit */
}
printf("salary=%.2f\n",salary);
}