第五章 选择结构程序设计
流程图有三种基本结构,顺序结构、选择结
构、循环结构。
其中 选择结构 和 循环结构 在 C语言中都有相
应的语句来实现。选择结构通常用 if语句来完成。
if 语句有几种格式,例如其中之一,
if (表达式) 语句 1 else 语句 2
例如,int a;
scanf(“%d”,&a) ;
if (a<0) printf(“a=%d \n”,-a);
else printf(“a=%d \n”,a);
在比如,int a;
scanf(“%d”,&d);
if(a>=0 and a<=100) printf(“a=%”,-a);
else printf(“a=%d”,a);
?关系运算符和表达式
?关系运算符
?种类, <, <=, = =,>=,>,!=
?结合方向:自左向右
?优先级别,
<
<=
>
>=
= =
!=
优先级 6(高)
优先级 7(低) 例 c>a+b //c>(a+b)
a>b!=c //(a>b)!=c
a==b<c //a==(b<c)
a=b>c //a=(b>c)
关系表达式的值:是逻辑值“真”或“假”,用
1和 0表示
例 int a=3,b=2,c=1,d,f;
a>b
(a>b)= =c
b+c<a
d=a>b
f=a>b>c < >
//表达式值 1
//表达式值 1
//表达式值 0
//d=1
//f=0
☆ 逻辑运算符和表达式
? 逻辑运算符,! (逻辑非),&&(逻辑与), || (逻辑或)
其中,&&(逻辑与), ||(逻辑或) 为二目运算符,
例如,a && b a || b
! (逻辑非) 为单目运算符
例如,! a
逻辑运算符 功能,
&&(逻辑与),例如,a && b 当 a, b 都是真时值为真,有
一个是假或两个都是假时值为假。
|| (逻辑或),例如,a || b 当 a,b中至少有一个是真时值为真,
两个 都是假时值为假。
! (逻辑非),例如,! a 当 a 为真时值为假,当 a 为假时值为
真。
a b !a !b a&&b a||b




假 假


– C语言中,运算量, 0表示, 假,,
非 0表示, 真,,
运算结果, 0表示, 假,,
1表示, 真,,
< >
















逻辑运算符得值总表(真值表),
! (2)
&& (11)
|| (12)


例 a<=x && x<=b
a>b&&x>y
a==b||x==y
!a||a>b
?优先级,
?结合方向,
!,从右向左
&&,从左向右
||,从左向右
< >
// (a<=x) && (x<=b)
//(a>b)&&(x>y)
//(a==b)||(x==y)
//(!a)||(a>b)
! (2)
&& (11)
|| (12)


?优先级,
?结合方向,
!,从右向左
&&,从左向右
||,从左向右
例 a=4;b=5;
!a
a&&b
a||b
!a||b
4&&0||2
5>3&&2||8<4-!0
?c?&&?d?
值为 1
值为 0
值为 1
值为 1
值为 1
值为 1
//(5>3)&&2||(8<(4-(!0))) 值为 1
P
A B
真 假 P
B A
真 假
?选择结构
k
A1 A2 Ai An
k=k2 k=k1
k=kn
k=ki
...,.,
?二选一
分支选择结构
?多分支选择结构
? 选择型程序设计
– If 语句(条件选择语句)
?if语句的三种形式
形式一,
?格式,if (表达式 )
语句
?执行过程,表达式
语句
非 0
=0
例,
if (x>y)
printf(“%d”,x);
形式二,
?格式,if(表达式 1)
语句 1
else
语句 2
?执行过程,
表达式
语句 1 语句 2
非 0 =0
例,if (x>y) max=x;
else max=y;
形式三,
? 格式,if (表达式 1 ) 语句 1
else if ( 表达式 2 ) 语句 2
else if (表达式 3 ) 语句 3
…..,
[ else 语句 n ]
表达式 1
语句 1
非 0
=0
表达式 2
表达式 3
语句 n 语句 3 语句 2
非 0
非 0
=0
=0
?执行过程,
例,if ( number>1000) cost=0.4;
else if (number>800) cost=0.3;
else if (number>600) cost=0.2;
else if (number>400) cost=0.1;
else cost=0;
例如,x=5;
if (x) printf(“%d”,”x =5”);
else printf(“%d”,”x!=5”);
if( x!=0) printf(“%d”,”x=5”);
else printf(“%d”,”x!=5”);
if(!x) printf(“%d”,”x !=5”);
else printf(“%d”,”x=5”);
if(x==0) printf(“%d”,”x !=5“);
else printf(“%d”,”x=5” );
如,if(a==b&&x==y) printf(“a=b,x=y”);
if(3) printf(“OK”);
if(?a?) printf(“%d”,?a?);
?说明,
?if后面的表达式类型任意
? if(x) ? if(x!=0)
if(!x) ? if(x= =0)
Compile Error!
例 考虑下面程序的输出结果,
#include <stdio.h>
main()
{ int x,y,z;
scanf(“%d,%d”,&x,&y);
if(x>y)
z=x; x=y; y=z;
else
x++; y++;
printf(“%d,%d\n”,x,y);
}
?语句可以是复合语句
/*ch5_1.c*/
#include <stdio.h>
main()
{ int x,y;
printf("Enter an integer:");
scanf("%d",&x);
y=x;
if(x<0)
y= -y;
printf("\ninteger:%d--->absolute value:%d\n",x,y);
}
例 求一个数的绝对值
运行,Enter an integer:-12?
integer:-12--->absolute value,12
/*ch5_2.c*/
#include <stdio.h>
main()
{ int a,b;
printf("Enter integer a:");
scanf("%d",&a);
printf("Enter integer b:");
scanf("%d",&b);
if(a==b)
printf("a==b\n");
else
printf("a!=b\n");
}
例 输入两个数并判断两数相等否
运行,Enter integer a:12?
Enter integer b:12?
a==b
运行,Enter integer a:12?
Enter integer b:9?
a!=b
#include <stdio.h>
main()
{ char c;
printf("Enter a character:");
c=getchar();
if(c<32) printf("The character is a control character\n");
else if(c>='0'&&c<='9') printf("The character is a digit\n");
else if(c>='A'&&c<='Z') printf("The character is a capital letter\n");
else if(c>='a'&&c<='z') printf("The character is a lower letter\n");
else printf("The character is other character\n");
}
例 判断输入字符种类
运行,Enter a character,?
The character is a control character
运行,t t, 8 ?
t i digi
运行,Enter a character,D?
The character is a capital letter
运行,Enter a character,h
he c aracter is a lower let er
运行,Enter a ch racter,= ?
The character is other character
?if语句嵌套,
?一般形式,
if (表达式 1)
if (表达式 2) 语句 1
else 语句 2
else
if(表达式 3) 语句 3
else 语句 4
内嵌 if
内嵌 if
if (表达式 1)
if (表达式 2)
语句 1
else
语句 2
内嵌 if
if (表达式 1)
{ if (表达式 2)
语句 1 }
else
语句 3
内嵌 if
if (表达式 1)
语句 1
else
if(表达式 3)
语句 3
else
语句 4
内嵌 if
例 输入两数并判断其大小关系
/*ch5_4.c*/
#include <stdio.h>
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 ~ else 配对原则,缺省 { }时,
else总是和它上面离它最近的未
配对的 if配对
if(……)
if(……)
if(……)
else…..,else…..,
else…..,
例,if (a= =b)
if(b= =c)
printf(“a= =b= =c”);
else
printf(“a!=b”);
修改,if (a= =b)
{ if(b= =c)
printf(“a= =b= =c”);
}
else
printf(“a!=b”);
实现 if ~ else 正确配对方法:加 { }
–条件运算符与表达式
? 一般形式,expr1? expr2, expr3
? 执行过程
? 功能:相当于条件语句,但不能取代一般 if语句
例 if (a>b)
printf(“%d”,a);
else
printf(“%d”,b);
printf(“%d”,a>b?a:b);
例 求 a+|b|
printf(“a+|b|=%d\n”,b>0?a+b:a-b);
expr1
取 expr2值 取 expr3值
非 0 =0
例 (a==b)??Y?:?N?
(x%2==1)?1:0
(x>=0)?x:-x
(c>=?a? && c<=?z?)?c-?a?+?A?:c
? 条件运算符可嵌套
如 x>0?1:(x<0?-1:0)
? 优先级, 13
? 结合方向,自右向左
如 a>b?a:c>d?c:d ? a>b?a:(c>d?c:d)
? expr1,expr2,expr3类型可不同,表达式值取较高的
类型
< >
例 x??a?:?b? //x=0,表达式值为‘ b?; x?0,表达式值为‘ a?
x>y?1:1.5 //x>y,值为 1.0; x<y,值为 1.5
?switch语句 ( 开关分支语句 )
?一般形式,switch( 表达式 )
{ case E1,
语句组 1;
break;
case E2,
语句组 2;
break;
……,
case En,
语句组 n;
break;
[default,
语句组 ;
break;]
}
?执行过程,
switch
表达式
语句组 1 语句组 2 语句组 n 语句组 …..,
E 1 E 2 En default
case
?说明,
?E1,E2,… En是 常量表达式,且值必须互不相同
?语句标号作用,必须用 break跳出
?case后可包含多个可执行语句,且不必加 { }
?switch可嵌套
?多个 case可共用一组执行语句
如,……
case ?A?,
case ?B?,
case ?C?,
printf(“score>60\n”);
break;
…….,
例 switch(score)
{ case 5,printf(“Very good!”);
case 4,printf(“Good!”);
case 3,printf(“Pass!”);
case 2,printf(“Fail!”);
default, printf(“data error!”);
}
运行结果,score为 5时,输出,
Very good! Good! Pass! Fail! data error!
例 void main()
{ int x=1,y=0,a=0,b=0;
switch(x)
{ case 1,
switch(y)
{ case 0,a++; break;
case 1,b++; break;
}
case 2,a++;b++; break;
case 3,a++;b++;
}
printf(“\na=%d,b=%d”,a,b);
}
运行结果,a=2,b=1
/*ch5_5.c*/
#include <stdio.h>
main()
{ int c;
printf("Enter m or n or h or other:");
c=getchar();
switch(c)
{ case 'm',printf("\nGood morning!\n");break;
case 'n',printf("\nGood night!\n"); break;
case 'h',printf("\nHello!\n"); break;
default, printf("\n\n"); break;
}
}
例 根据输入字母输出字符串
程序举例, * 写程序,由公元号判断某一年是否闰年。
分析:闰年的条件,1)公元号能被 4整除,但不能被 100
整除,是闰年; 2)公元号能被 100整除,又能被 400整除,
是闰年。不满足这两个条件的不是闰年。
以变量 leap代表是否闰年的信息。若闰年,令 leap=1;非闰
年,leap=0。 ( leap是一个信号量)
T year被 4整除 F
T year被 100整除 F
leap=0
T year被 400整 F
leap=1 leap=1 leap=0
T leap F
输出 "闰年 " 输出 "非闰年 "
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");
}
main()
{int year,leap;
if (year%4!=0)
leap=0;
else if (year%100!=0)
leap=1;
else if (year%400!=0)
leap=0;
else
leap=1;
if (leap)
printf("%d is",year);
else
printf("%d is not",year);
printf("a leap year.\n");
}
main()
{int year,leap;
if (( year % 4 == 0 && year % 100 != 0 ) || (year % 100 = 0 && year%400 == 0))
leap=1;
else
leap=0;
if (leap)
printf("%d is",year);
else
printf("%d is not",year);
printf("a leap year.\n");
}
运行情况如下,
1989
1989 is not a leap year,
2000
2000 is a leap year,
运输公司对用户计算运费。路程( s)越远,每公里运费
越低。标准如下,
s<250km 没有折扣
250<=s<500 2%折扣
500<=s<1000 5%折扣
1000<=s<2000 8%折扣
2000<=s<3000 10%折扣
3000<=s 15%折扣
设每公里每吨货物的基本运费为 p,货物重为 w,距离为
s,折扣为 d,则总运费 f的计算公式为,f=p*w*s*(1-d)
分析此问题,可以看出,折扣的变化是有规律的,如下图所示,
折扣的“变化点”都是 250的倍数( 250,500,1000,2000、
3000)。利用这一特点,可以在横轴上加一种坐标 c, c的值为
s/250 。 C代表 250的倍数。当 c<1时,表示 s<250,无折扣 ;
1≤c<2 时,表示 250 ≤s<500,折扣 d=2%; 2≤c<4时,d=5%;
4≤c<8时,d=8%; 8≤ c<12时 d=10% ; c≥12时,d=15% 。
0 250 500 750 1000 1250 1500 1750 2000 2250 2500 2750 3000 s
2
4
6
8
10
12
14
16
折扣 d
1 2 3 4 5 6 7 8 9 10 11 12 c
main() case 8,
{int c,s; case 9,
float p,w,d,f; case 10,
scanf("%f,%f,%d",&p,&w,&s); case 11:d=10;break;
if (s>=3000) c=12; case 12:d=15;break;
else c=s/250; }
switch(c) f=p*w*s*(1-d/100.0);
{ printf("freight=%15.4f",f);
case 0:d=0;break; }
case 1:d=2;break;
case 2,
case 3:d=5;break;
case 4,
case 5,
case 6,
case 7:d=8;break;
运行情况如下,
100,20,300
freight=588000.0000
思考与问答题,作业,104页 5.3,5.4,5.5,5.6,5.8
1,关系运算符, <, <=, = =,>=,>,!= 的功能、优先级,
结合方向分别是什么?
2,逻辑运算符,! (逻辑非),&&(逻辑与), || (逻辑或)的
功能、优先级,结合方向分别是什么?
3,C语言中的如何表示“真”和“假”?,系统如何判断一个量的
“真”
和“假,?
4,if 语句对应哪种基本结构?有哪三种格式?
5,if语句嵌套有几种形式?
6,if ~ else 的配对原则是什么?
7、条件运算符,?, 的功能、结合方向分别是什么?
8,switch语句的格式、功能是如何规定的?
9、在什么时候需要使用复合语句?
?关系运算注意,
< >
例 若 a=0; b=0.5; x=0.3;
则 a<=x<=b的值为 0
例 5>2>7>8在 C中是允许的,
值为 0
例 int i=1,j=7,a;
a=i+(j%4!=0);
则 a= 2
例 ‘ a?>0 结果为
‘ A?>100 结果为
1
0
例 考虑下面程序输出结果,
main()
{ int x=100,a=10,b=20;
int v1=5,v2=0;
if(a<b)
if(b!=15)
if(!v1)
x=1;
else
if(v2) x=10;
x=-1;
printf(“%d”,x);
}
结果,-1
关系运算注意,
例 注意区分,=”与,= =”
int a=0,b=1;
if(a= =b)
printf(“a equal to b”);
else
printf(“a not equal to b”);
例 应避免对 实数 作相等或不等的判断
如 1.0/3.0*3.0==1.0 结果为
可改写为,fabs(1.0/3.0*3.0-1.0)<1e-6
0
在数学中经常遇到下面的条件:比如:已知 a>=50 且 a<=100,
再比如,已知 a < - 50 或 b < 50 。
在 C语言中如何表示上述运算呢?
这就是我们下面要讲的逻辑运算。