Jan 24, 2016
第 5 章 选择结构程序设计
§5.1 关系运算符和关系表达式§5.2 逻辑运算符和逻辑表达式§5.3 if 语句§5.4 switch 语句§5.5 程序举例
§5.1 关系运算符和关系表达式 关系运算实际上是比较运算关系运算实际上是比较运算 ,, 两个值进行比较两个值进行比较 ,,
判断比较的结果是否符合给定的条件判断比较的结果是否符合给定的条件 ,, 如果符如果符合比较的结果为合比较的结果为真真 ,, 否则结果为否则结果为假假。。
用 将两个表达式用 将两个表达式 (( 可以是算术表可以是算术表达式、关系表达式、逻辑表达式、赋值表达式、达式、关系表达式、逻辑表达式、赋值表达式、字符表达式)连接起来的式子叫 。字符表达式)连接起来的式子叫 。
关系运算符与其它运算符的 。关系运算符与其它运算符的 。
关系运算符
关系表达式
优先次序
§5.2 逻辑运算符和逻辑表达式
用 将关系表达式或逻辑量连接用 将关系表达式或逻辑量连接起来就是 。起来就是 。
逻辑运算符与其它运算符的 。逻辑运算符与其它运算符的 。 在逻辑表达式的求解中在逻辑表达式的求解中 ,, 并不是所有的逻并不是所有的逻辑运算都被执行辑运算都被执行 ..
逻辑运算规律逻辑运算规律 ::
优先次序
逻辑运算符
逻辑表达式
例如
§5.3 if 语句问题提出 :
计算分段函数:
y=
3-x x≤0
2/x x>0
解题的步骤:输入 x
x≤0
是
y=3-x y=2/x
否
输出 y的值
C 语言用来设计条件选择结构程序的选择语句有两种: if 语句、 switch 语句。
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 ( 表达式 1) if ( 表达式 2) 语句 1;
if ( 表达式 1) if ( 表达式 2) 语句 1; else 语句 2;
if 语句的嵌套
语句执行流程:
else 与 if 的配对原则: 就近一致原则:
else 与同一层最接近它,而又没有其它 else 语句与之相匹配的 if 语句配对。
真 ( 非0) 语句 2
假 (0)表达式
2
语句 1
语句 4
假 (0)
真 ( 非0)
表达式1
假 (0)
真 ( 非0)
表达式3
语句 3
if ( ) if ( ) 语句 1 else 语句 2else if ( ) 语句 3 else 语句 4
if ( ) if ( ) 语句 1else if ( ) 语句 2 else 语句 3
内嵌 if
内嵌 if
内嵌 if
if ( ) { if ( ) 语句 1 } else { if ( ) 语句 2 else 语句 3 }
-1 (x<0) 例如 y= 0 (x=0) 1 (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;
x>=0
y= -1
x>0
y=1 y=0
x<0
Y=-1
X= =0
Y=0 Y=1真
假
真 假
真
真假
假
{
3 . y= - 1;
if (x!=0)if (x>0) y=1;
else y=0;
真
真假
假
x>0
y=1
y= 0
x>=0
y=- 1
4. y=0; if (x>=0) if (x>0) y=1; else y= - 1;
真
真 假
假
x>0
y=1
y= -1
X!=0
y=0
5.3.3 条件运算符 ? :? :
表达式 1 ? 表达式 2 : 表达式 3条件表达式 max= (a>b)? a:b 相当于 if (a>b) max=a; else max=b;
说明 : 条件运算符的执行顺序 条件运算符的优先级别 , 仅高于赋值运算 条件运算符的结合方向为右结合性 条件表达式不能取代 if 语句 条件表达式中的表达式类型可以不同
1 、语句形式: switch (表达式) {
case 常量 1: 语句 1
; case 常量 2: 语句 2
; case 常量 3: 语句 3
; .......
case 常量 n: 语句 n
; default : 语句 n+1 ; }
根据表达式的不同值,根据表达式的不同值,选择不同的程序分支,选择不同的程序分支,
又称开关语句又称开关语句。
根据表达式的不同值,根据表达式的不同值,选择不同的程序分支,选择不同的程序分支,
又称开关语句又称开关语句。
数值型或
字符型
常量表达式的值必须互不相同,否则执行时将出现矛盾,即同一个开关值,将对应多种执行方案。
常量表达式的值必须互不相同,否则执行时将出现矛盾,即同一个开关值,将对应多种执行方案。
千万不能接 ( ; )号
§5.4 switch 语句
2 、语句执行流程:
指语句的最后一条是否为 break
简单语句或复合语句
break break有
无break
有
无
有
计算表达式
常量 1 常量 2 常量 n=
语句 1
…
= = =
语句 2 语句 n
其它=
语句 n+1
无
值
case 语句出现的次序并不影响执行
结果。
例如: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
将上面的例子修改如下:
#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↙
Wednesday
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 语句。
例 企业发放的奖金根据利润提成。从键盘输入当月利润,求应发放奖金总数?
10% 10
12% 10 20
14% 20 40
16% 40 60
18% 60 100
20% 100
利润 利润 万利润 利润 万利润 利润 万
奖金利润 利润 万利润 利润 万利润 利润 万
利润 x
x<=10
10<x≤20
20<x≤40
40<x≤60
60<x≤100
100<x
(int )x/10
常量
0,1
1,2
2,3,4
4,5,6
6 , 7 , 8 , 9,10
10 以上用这种方法转换后, n出现了在不同区域有重复数字的情况。解决的方法有很多,其中一种是可以采用当
x为 10 的整数倍时,将计算出的 n值减 1 。
使用 switch 解题的关键,通过分析找到表达式,将问题分成几种情况。
#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);}
程序如下:
§5.5 程序举例例例 5.55.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”);}
Year 被 4 整除Y N
Year 被 100 整除Y N
Y NYear 被
400 整除
leap=1 leap=0leap=1
leap=0
leapY N
输出闰年 输出非闰年
例 5.7 计算运费。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
C=s/250c<1 无折扣1<c<2 2%2<c<4 5%4<c<8 8%
8<c<12 10%c>12 15%
例 5.7main( )
{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 ); }
x1=x2=
b2-4ac=0
a=0Y N
输出“ 非二次
方程
输出两相
等实根-b/2a
b2-4ac>0Y N
实部 p=
虚部 q=
输出两个实根输出两个复根
p+qip-qi
NYY
例例 5.6 5.6 解一元二次方程解一元二次方程
#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);
}
}
}
第第 55 章结束章结束
C 语言提供六种关系运算符 ① < 小于 ② <= 小于等于 ③ > 大于 ④ >= 大于等于 ⑤ == 等于 ⑥ != 不等于
双目运算 , 左结合性 . 如 :
a>b , (a+b)>(b+c) ,( a=3 ) >(b=5) ,( a>b ) >c, a>b>c ,
赋值表达式 :
x=a>b
y=a>b>c
关系表达式的值是一个逻辑值,即真或假。运算时以 1代表真,以 0代表假。
的值为真 , 表达式的值为 1
的值为真,表达式的值为 1,
的值为假 , 表达式的值为 0,
例如:若 a=3 , b=2 , c=1 ,则
a>b
(a>b)= =c
b+c<a
优先次序 :
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 语句
语句形式:
if ( 表达式) 语句;
语句执行流程:
表达式
语句
真 ( 非0)
假 (0)
例如 :if (x>y) printf (“%d”,x);
这种 if 语句的执行过程见图 :
假 真
x>y
print(“%d”,x); 可以是一个语句也可以是复合语句
一般为逻辑表达式或关系表达式 .
理论上可以是任意数值
类型
If (a) printf(“Hello, world”);
例:从键盘输入两个整数 a和 b ,如果 a大于 b 则交换两数,最后输出两个数。
#include <stdio.h>
输入 a,b
a>b
交换 a、 b
输出
结束
真
假
void main() {int a,b,t; scanf("%d,%d",&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 ;
语句执行流程:
表达式
语句 1
真 ( 非0)
假 (0)
语句 2
例如 :
if(x > y) printf(“%d”,x); else printf(“%d”,y);
x>y
printf(“%d”,x); printf(“%d”,y)
真 假
注 意 注意
例 输入两个整数,输出其中较大的数。
#include <stdio.h>#include <math.h>
void main(){int x,y,max; scanf("%d,%d",&x,&y);
if(x>y) max=x; else max=y;
printf("max=%d\n",max); }
输入 x,y
x>y
max=x
输出最大值
结束
真
假
max=y
注意
if 和 else 语句之间只能有一个语句,当 if~else 之间的语句不只一句时,应用一对 {} 将语句括起。
if(a>b) {a++ ; b++ ; }
else { a=0 ; b=10 ; }
3 、多分支选择 if 语句语句形式:
if (if ( 表达式表达式 11 ) 语句) 语句 11 ;;else if (else if ( 表达式表达式 22 )语句)语句 22 ; ; … … … … else if (else if ( 表达式表达式 nn )语句)语句 nn ;; else else 语句语句 n+1n+1 ;;
语句执行流程:
表达式 1
语句 1
真 ( 非 0)
假 (0)
语句 2
表达式 2真 ( 非 0
) 表达式 2
语句 n 语句 n+1
假 (0)
假 (0)
例:计算分段函数。x 5 x 1
y 2x 1 x 10
3x 10
x 10
假输入 x
X<=1
真
X<10
y=3/(x-10)
y=2xy=x+5
假
真
#include <stdio.h>
void main()
{float x,y;
printf("enter x:");
scanf(" %f ",&x);
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); }
计算分段函数程序
if(x==10) printf("not define x.\n");
}
比较两个数, 输出三个数中最大的先大后小的输出例如 :
开始
输入两个数
a>b
t=a;a=b;b=t
输出 a,b
结束
真
假
开始
输入三个数
a>b
a>c
b>c
a=b
a=c
输出 a
结束
a=c假
真
真
假
真
假
表达式 1
条件表达式取表达式 2 的值
条件表达式取表达式 3 的值
真 ( 非 0) 假 (0)
高于赋值运算符。低于关系运算符和关系运算符
max=(a>b)?a:b 可以写成max= a>b ?a:b
有 a>b?a:b+1 相当于 a>b?a:(b+1) 而不是 (a>b?a:b)+1
有自右至左a>b?a:c>d?c:d
相当于a>b?a:(c>d?c:d)而不是(a>b?a:c)>d?c:d若 a=1;b=2;c=3;d=4;求表达式的值
不能替代如 :if (a>=b) max=a; else min=b;if (a>=b) max=a; else
printf(“ 变量 a 不是最大” );
可替代如 :
if (a>b) printf(“%d”,a); else printf(“%d”,b);
替代为 :printf(“%d”,a>b?a:b);
x ?‘ a’ :‘ b’x>y ? 1 : 1.5
编程,输入一个字符,若是大写就转换成小写;若不是就不转换,输出字符。main (){char a ;scanf (“ %c” , &a );if ( a>=‘A’&&a<=‘Z’ ) a=a+32;printf(“%c”,a);}
a=(a>=‘A’&&a<=‘Z’)?a+32:a;