2.x<60||x>80(或!
(x>=60&&x<=80))
3.(x>=10&&x<=30)||(x>=50&&x<=90)
4.2if语句
if语句是一种常用的分支结构,用它可以构成复杂的判断选择。
一般使用有3种形式。
4.2.1if语句的简单形式
语句的一般形式如下:
if(表达式)
语句块
这种形式的if语句也称之为不含else的if语句。
如果表达式的值为真(非零数),那么执行语句块,否则,跳过语句块。
接着控制转向下一条语句,见流程图4.1。
在如下的例子中:
if(score>=90)
printf(“Congratuations!
\n”);//语句块由一条语句组成
printf(“Yourscoreis%d\n”,score);
当score的值大于等于90时(假设为95),程序显示两个结果:
Congratuations!
Yourscoreis95
当score的值小于90时(假设为65),程序显示一个结果:
Yourscoreis65
显然,printf(“Congratuations!
\n”);语句的执行与否由if后面的表达式来决定。
而printf(“Yourscoreis%d\n”,score);语句不是if语句块的一部分,它是一条独立的语句,程序在if语句执行后,紧接就执行它。
if语句后面的语句块实质就是一条语句,形式可以是单条语句,也可以是复合语句。
计算机将复合语句看作一条语句。
因此当if语句下面要控制一系列语句时,应用一对花括号将他们群聚成一组,即复合语句。
如:
if(score>=90)
{
printf("Congratuations!
\n");
printf("Yourscoreis%d\n",score);
}
当满足条件score>=90时,则执行复合语句,产生两个输出,否则不执行复合语句,即没有任何的输出结果。
注意,即使if语句中使用了复合语句,整个if结构仍被看成一个简单语句。
通常,在if语句中的表达式是个关系表达式或逻辑表达式,像表达式x>y和x>3&&x<5这样。
也可以是C语言中任意合法的表达式,像算术表达式、赋值表达式等。
当表达式的值为非零时,视为真;表达式的值为零时,视为假。
如:
if(a=0)
printf(“yes”);
无论if语句之前a为何值,因为括号内a=0为赋值表达式,值为0,if语句判断条件为假,语句printf(“yes”)不执行。
【例4.1】输入一个非零整数,如果其大于零,则输出“正数”;如果小于零,则输出“负数”。
1.算法分析
假设x代表一非零整数。
判断该数是否为正数,只需拿它与0进行比较。
利用关系表达式表示:
x>0。
如果该表达式为1(真),说明x是个大于零的正数。
同理,判断x是否是负数,只需判断其是否小于0。
利用关系表达式表示:
x<0。
如果该表达式值为1(真),说明x是小于零的负数。
因此,可用两个不含有else的if语句分别表示上述两种情况。
2.源程序代码(demo4_1.c)
#include
main()
{
intx;
printf("请输入一个非零整数\n");
scanf("%d",&x);
if(x>0)
printf("正数");
if(x<0)
printf("负数");
}
3.程序说明
程序中有两条并行关系的if语句。
printf("正数");这条语句的执行是否由表达式x>=0决定。
如果x>=0成立,则执行该条语句,否则不执行。
同样,语句printf("负数");也是如此。
4.程序运行结果
(1)运行结果1:
请输入一个非零整数
5↙
正数
(2)运行结果2:
请输入一个非零整数
-12↙
负数
说明:
↙表示Enter键。
【例4.2】商店售货,按购买货物款的多少分别给予不同的优惠折扣,编程计算实际应付货款。
购货不足250元,没有折扣;
购货250元(含250元,下同),不足500元,减价5%;
购货500元,不足1000元,减价7.5%;
购货1000元,不足2000元,减价10%;
购货2000元及以上,减价15%;
1.算法分析
设购物款为m,折扣率为d,则d可表示为:
根据m的取值范围确定d的值,可用if语句实现。
当d的值确定后,使用公式t=m*(1-d)计算实际应付款。
2.数据结构
根据题意,程序中应分配3个变量分别存储数据购物款、折扣率和应付款。
由于购物款、折扣率等一般都为小数,所以变量应定义为float类型。
3.源程序代码(demo4_2.c)
#include
main()
{
floatm,d,t;
printf("请输入购物款:
");//输出提示信息
scanf("%f",&m);//输入购物款,存储于变量m中
if(m<250)
d=0;
if(m>=250&&m<500)
d=0.05;
if(m>=500&&m<1000)
d=0.075;
if(m>=1000&&m<2000)
d=0.1;
if(m>=2000)
d=0.15;
t=m*(1-d),//计算应付款,存储于变量t中
printf("实际应付款:
%5.2f",t);//输出实际应付款,结果保留2位小数
}
4.程序说明
程序中的5条if语句是并行关系。
计算机对于每条if语句都要判断一次,但不一定都执行,只有当判断的表达式为真,才认为if语句执行了,否则认为if语句没有执行。
如:
假设m的值为150,第1条if语句执行了,其后面的其它4条if语句计算机都判断,但都没有执行,因为判断的表达式的值为假。
5.程序运行结果
(1)运行结果1:
请输入购物款:
249↙
实际应付款:
249.00
(2)运行结果2:
请输入购物款:
:
500↙
实际应付款:
462.50
说明:
↙表示Enter键。
4.2.2含有else的if语句
不含else的if语句使程序能够选择是否执行某个动作,而含else的if使程序能够在两个动作之间进行选择。
语句的一般使用形式:
if(表达式)
语句块1
else
语句块2
如果表达式为真(非零),则执行if后面的语句块1(亦称if子句);如果表达式为假(零),则执行else后面的语句块2(亦称else子句)。
显然,语句块1和语句块2不能同时执行。
执行流程见图4.2。
可用if…else语句来修改例4.1程序:
if(x>0)
printf("正数");
if(x<0)
printf("负数");
这个程序段在执行过程中,两条if语句都须进行判断。
而实际上,当x>0成立时,x<0一定不成立,采用if…else修改,则程序不必重新判断:
if(x>0)
printf("正数");
else
printf("负数");
如果x>0则输出正数,否则一定是小于零的情况,则输出负数。
这里程序仅仅只做了一次判断。
如果if和else之间有多条语句,则必须用花括号将其括起来。
下面的形式是错误的:
if(x>60)
printf(“pass”);
n++;
else
printf(“nopass”);
编译器认为if和else之间只有一条语句(单条或复合)。
遇到上述形式的程序段,编译器会报错,因为它认为printf(“pass”);是if的一部分,而n++被看作是独立的一部分,不属于if语句,接着就会认为else没有if与其匹配。
应该使用下面的形式:
if(x>60)
{//复合语句
printf(“pass”);
n++;
}
else
printf(“nopass”);
同样,如果else后面的语句块2(即else子句)是由多条语句组成,也应用花括号括起来形成复合语句。
如:
示例1:
if(score>=60)
printf(“pass\n”);
else
printf(“nopass\n”);
printf(“end\n”);
示例2:
if(score>=60)
printf(“pass\n”);
else
{
printf(“nopass\n”);
printf(“end\n”);
}
从缩排格式看,容易错误的将示例1等同于示例2。
但从4.2的运行结果对照来看,显然,else后面的两条语句加花括号和不加花括号对程序的执行结果是有本质不同的。
实际上示例1中只有printf(“nopass\n”)是else的子句。
而printf(“end\n”);是区别于if…else语句的其它语句。
表4.2示例1和示例2的运行结果对比
表达式
程序的输出结果
示例1
示例2
score>=60
为真时
pass
end
pass
为假时
nopass
end
不管是哪一种形式的if语句,编译器在识别else子句所遵循的规则是:
将关键字else后面紧靠它的第一条语句视为else子句(语句块)。
对于识别if子句(语句块1)也是如此。
计算机把复合语句看作一条语句。
【例4.3】编写程序,计算如下的分段函数:
x+1x≥0
y=
2x+5x≤0
1.算法分析
根据题意:
如果x大于等于0,选择表达式x+1计算y值,反之,选择表达式2x+5计算y值。
可利用if…else语句实现。
代数表达式要写成标准的算术表达式:
2x+5====>2*x+5
2.源程序代码(demo4_3.c)
#include
main()
{
intx;
printf("请输入1个整数\n");
scanf("%d",&x);
if(x>=0)
y=x+1;
else
y=2*x+5;
printf("结果为:
%d\n",y);
}
3.程序运行结果
(1)运行结果1:
请输入1个整数
5↙
结果为:
6
(2)运行结果2:
请输入1个整数
-3↙
结果为:
-1
说明:
↙表示Enter键。
【例4.4】求解任意的一元二次方程ax2+bx+c=0(a≠0)的根,a、b、c的值由键盘输入。
1.算法分析
当a≠0时,一元二次方程式的根有两种形式:
(1)当判别式b2-4ac≥0有两个实根,求根公式为
(2)当判别式b2-4ac<0有两个共轭复根,求根公式为
2.数据结构分析
由于问题简单,只需用到一些单精度实数。
方程系数a,b,c采用单精度变量,
3.伪代码
输入方程系数a,b,c
计算判别式d=b*b-4*a*c
if(判别式≥0)
{
计算两个实根
打印结果
}
else
{
计算实部和虚部
打印结果
}
4.源程序代码(demo4_4.c)
#include
#include
main()
{
floata,b,d,c,x1,x2,p,q;
printf("输入方程系数a,b,c:
");
scanf("%f,%f,%f",&a,&b,&c);
d=b*b-4.0*a*c;
if(d>=0)
{
x1=(-b+sqrt(d))/(2.0*a);
x2=(-b-sqrt(d))/(2.0*a);
printf("x1=%5.2f,x2=%5.2f\n",x1,x2);
}
else
{
p=-b/(2.0*a);
q=sqrt(-d)/(2.0*a);
printf("实部为:
%5.2f\n",p);
printf("虚部为:
%5.2f\n",q);
}
}
5.程序运行结果
(1)第1次运行程序
输入方程系数a,b,c:
2,5,3↙
x1=-1.00,x2=-1.50
(2)第2次运行程序
输入方程系数a,b,c:
2,3,4↙
实部为:
-0.75
虚部为:
1.20
说明:
↙表示Enter键
上述的例4.3和例4.4是比较简单的分支情况,除了用if…else语句实现,还可用C语言中提供的条件运算符来处理。
条件运算符是由“?
”和“:
”组成的运算符。
通常使用它将三个表达式连接成一个新的表达式,称之为条件表达式:
表达式1?
表达式2:
表达式3
若表达式1的值非零(真),则条件表达式的值为表达式2的值。
若表达式1的值为零(假),则条件表达式的值为表达式3的值。
如:
x>=0?
2+3:
16
假设x=6,那么此条件表达式的值为5。
条件运算符优先于赋值运算符,低于关系运算符。
其结合方向为“自右至左”。
例如:
a>b?
a:
c>d?
c:
d/*等价于a>b?
a:
(c>d?
c:
d)*/
因此,例4.4中if…else结构可用条件运算表达式表示:
y=(x>=0?
x+1:
2*x+5);
尽管条件运算符也可用于复杂的分支,但一般情况下,只有简单的分支才用条件运算符。
4.2.3含elseif的if语句
含elseif的if语句提供多种选择,并从中选择一个满足条件的情况操作,即多选一。
语句的一般形式:
if(表达式1)
语句块1
elseif(表达式2)
语句块2
…
elseif(表达式n)
语句块n
else
语句块n+1
程序依次判断if圆括号中表达式的真假,直到某个表达式i为真,则选择其后的语句块i执行,并完成if语句的执行,否则继续判断下一个表达式;如果所有if后面的表达式值都为假,则执行else后面的语句块n+1。
最后执行if后面的其他语句。
流程图如图4.3所示。
看下面的例子:
inta=70;
if(a>50)
printf("%d",a+1);
elseif(a>40)
printf("%d",a+2);
elseif(a>30)
printf("%d",a+3);
计算机是按照顺序依次判断括号内的条件表达式的值,当程序判断到第1个表达式a>50为真时,选择其后的printf("%d",a+1);语句执行,紧接的else意义为上面情况之外(即a<=50)再判断a的值,因此,程序不需再进行判断和执行后面所有语句。
输出结果是51。
如果把上面的程序段改成如下:
inta=70;
if(a>50)
printf("%d",a+1);
if(a>40)
printf("%d",a+2);
if(a>30)
printf("%d",a+3);
即3条并行的不含else的if语句组成。
计算机在执行时,对于每条if语句都要判断其表达式。
判断过程中,如果表达式为真,则执行其后的printf语句,否则接着判断下一条if语句。
因此该程序段的输出结果是:
515253。
【例4.5】从键盘输入一个整数,根据判断是正、负或是零分别输出字符“正数”、“负数”或“零”。
1.算法分析
一个整数,不可能既是零,又同时是正数且又是负数,这是矛盾的。
只能是其中的一种情况。
即三选一。
可利用if...elseif语句实现。
判断的本质条件是整数与零进行比较运算,可利用关系表达式表示。
2.源程序代码(demo4_5.c)
#include
main()
{
intx;
printf("请输入一个整数\n");
scanf("%d",&x);
if(x>0)
printf("x是正数\n");
elseif(x<0)
printf("x是负数\n");
else
printf("x是零\n");
}
3.程序说明
当x>0为假时,继续判断x<0是否为真,如果x<0也为假,那说明x的情况只能是为零,别无其它选择。
因此在if…elseif语句中,不需要再另外加elseif(x==0)这个分支判断。
else部分已足以说明问题。
4.程序运行结果
(1)运行结果1
请输入一个整数:
-3↙
x是负数
(2)运行结果2
请输入一个整数:
:
0↙
x是零
说明:
↙表示Enter键
【例4.6】用elseif语句改写例4.2的购物折扣程序。
1.源程序代码(demo4_6.c)
#include
main()
{
floatm,d,t;
printf("请输入购物款\n");
scanf("%f",&m);
if(m<250)
d=0;
elseif(m>=250&&m<500)
d=0.05;
elseif(m>=500&&m<1000)
d=0.075;
elseif(m>=1000&&m<2000)
d=0.1;
else
d=0.15;
t=m*(1-d);//计算应付款
printf("实际应付款:
%5.2f\n",t);//结果输出保留2位小数
}
2.程序运行结果
(1)运行程序1
请输入购物款:
249↙
实际应付款:
249.00
(2)运行程序2
请输入购物款:
:
500↙
实际应付款:
462.50
说明:
↙表示Enter键
3.程序说明
显然,用if…elseif语句表达逻辑性更强,程序更清晰,执行时间更省。
4.2.4if语句的嵌套
在一个if语句中可以包含另外一个或多个if语句,这称为if语句的嵌套。
如下例:
其执行流程是:
当x>=0时,执行虚线里面的if…else语句,否则执行语句printf(“Error”);。
这是在if子句(语句块1)中嵌套if的情况,当然也可以在else子句(语句块2)中嵌套if语句,这里就不再举例。
if语句有3种形式,当几种形式的if语句混合嵌套时,就涉及计算机如何判断哪个if对应哪个else的问题。
如下面的示例1:
if(x>=0)
if(x>0)
printf(“you”);
else
printf(“me”);
从缩排的格式上看,else好像是和第1个if配对。
如果按这种方式理解,当x大于0时,输出结果you;当x等于0时,没有输出;当x小于0时,输出结果me。
但这是错误的,因为编译器不是根据缩排格式识别if结构的。
其正确识别if语句的规则是:
else与它上面最接近的if匹配,且这个if没有被花括号或其它的else匹配掉。
因此,在示例1中,正确的是else应与第2个if配对。
通过缩排方式来表现即下面书写格式:
if(x>=0)
if(x>0)
printf(“you”);
else
printf(“me”);
当x大于0时输出结果是you;x等于0时,输出结果为