d=a>b//d=1,表达式值为1
f=a>b>c//f=0,表达式值为0
2.关系运算注意问题:
◆应避免对实数作相等或不等的判断
如:
1.0/3.0*3.0==1.0结果为0
可改写为:
fabs(1.0/3.0*3.0-1.0)<1e-6
◆注意区分“=”与“==”
◆
如:
inta=0,b=1;
if(a=b)
printf(“aequaltob”);
else
printf(“anotequaltob”);
执行结果为:
aequaltob
§4.2逻辑运算符和表达式
1.逻辑运算符种类:
!
&&||
2.逻辑运算真值表:
a
b
!
a
!
b
a&&b
a||b
真
真
假
假
真
假
真
假
假
真
假
真
假
真
真
假
假
真
假
假
真
真
假
真
C语言中,运算量:
0表示“假”,非0表示“真”
运算结果:
0和1,0表示“假”,1表示“真”
!
(逻辑非)高
算术运算符
关系运算符
&&和||
赋值运算符
逗号运算符低
3.优先级:
!
:
2
&&:
11
||:
12
4.结合方向:
!
:
从右向左
&&:
从左向右
||:
从左向右
例:
a<=x&&x<=b
//(a<=x)&&(x<=b)
a>b&&x>y//(a>b)&&(x>y)
a==b||x==y//(a==b)||(x==y)
!
a||a>b//(!
a)||(a>b)
例:
如果a=4,b=5,下列表达式的结果是:
!
a值为0
a&&b值为1
a||b值为1
!
a||b值为1
4&&0||2值为1
5>3&&2||8<4-!
0(5>3)&&2||(8<(4-(!
0)))值为1
‘c’&&‘d’值为1
5.短路特性:
逻辑表达式求解时,并非所有的逻辑运算符都被执行,只是在必须执行下一个逻辑运算符才能求出表达式的解时,才执行该运算符
例:
a&&b&&c//只在a为真时,才判别b的值;只在a、b都为真时,才判别c的值
例:
a||b||c//只在a为假时,才判别b的值;只在a、b都为假时,才判别c的值
例:
a=1;b=2;c=4;d=3;
(m=a>b)&&(n=c>d)//m=0,n=1,结果为0,
§4.3if语句(条件选择语句)
1.if语句的三种形式
<形式一>:
★格式:
if(expression)
statement
★执行过程:
★如:
if(x>y)
printf(“%d”,x);
<形式二>:
★格式:
if(expression)
statement1
else
statement2
★执行过程:
★如:
if(x>y)max=x;
elsemax=y;
<形式三>:
★格式:
if(expr1)statement1
elseif(expr2)statement2
elseif(expr3)statement3
...
elsestatementn
★执行过程:
(见流程图)
★如:
if(salary>1000)index=0.4;
elseif(salary>800)index=0.3;
elseif(salary>600)index=0.2;
elseif(salary>400)index=0.1;
elseindex=0;
2.有关if语句的几点说明:
★if后面的表达式类型任意
如:
if(a==b&&x==y)printf(“a=b,x=y”);
if(3)printf(“OK”);
if(‘a’)printf(“%d”,’a’);
★if(x)<==>if(x!
=0)if(!
x)<==>if(x==0)
★语句可以是复合语句
例:
考虑下面程序的输出结果:
#include
main()
{intx,y;
scanf(“%d,%d”,&x,&y);
if(x>y)t=x;x=y;y=t;
elsex++;y++;
printf(“%d,%d\n”,x,y);
}
上面程序是错误程序,正确程序为:
#include
main()
{intx,y;
scanf(“%d,%d”,&x,&y);
if(x>y){t=x;x=y;y=t;}
else{x++;y++;}
printf(“%d,%d\n”,x,y);
}
3.例题:
例4-1求一个数的绝对值
/*ch4_1.c*/
#include
main()
{intx,y;
printf("Enteraninteger:
");
scanf("%d",&x);
y=x;
if(y<0)
y=-y;
printf("\ninteger:
%d--->absolutevalue:
%d\n",x,y);
}
运行程序,显示:
Enteraninteger:
-12<回车>
程序执行结果:
integer:
-12--->absolutevalue:
12
例4-2.输入两个数并判断两数相等否
/*ch4_2.c*/
#include
main()
{inta,b;
printf("Enterintegera:
");
scanf("%d",&a);
printf("Enterintegerb:
");
scanf("%d",&b);
if(a==b)printf("a==b\n");
elseprintf("a!
=b\n");
}
运行程序:
(1)Enterintegera:
12
Enterintegerb:
12
a==b/*程序输出*/
(2)Enterintegera:
12
Enterintegerb:
6
a!
=b/*程序输出*/
例:
判断输入字符种类
#include
main()
{charc;
printf("Enteracharacter:
");
c=getchar();
if(c<0x20)printf("Thecharacterisacontrolcharacter\n");
else
if(c>='0'&&c<='9')printf("Thecharacterisadigit\n");
else
if(c>='A'&&c<='Z')
printf("Thecharacterisacapitalletter\n");
else
if(c>='a'&&c<='z')
printf("Thecharacterisalowerletter\n");
elseprintf("Thecharacterisothercharacter\n");
}
(1)运行:
Enteracharacter:
<回车>
Thecharacterisacontrolcharacter
(2)运行:
Enteracharacter:
8<回车>
Thecharacterisadigit
(3)运行:
Enteracharacter:
D<回车>
Thecharacterisacapitalletter
(4)运行:
Enteracharacter:
h<回车>
Thecharacterisalowerletter
(5)运行:
Enteracharacter:
F1<回车>
Thecharacterisothercharacter
3.If语句的嵌套:
if语句可以嵌套使用,即一个if语句中又包含一个或多个if语句。
(1)一般形式:
a)(内嵌在if条件成立的分支中)
if(expr1)
if(expr2)statement1
elsestatement2
else
statement3
如:
if(x>=0)
if(x>0)y=1;
elsey=0;
else
y=-1;
b)(内嵌在if条件不成立的分支中)
if(expr1)
statement1
else
if(expr2)statement2
elsestatement3
如:
if(x>0)
y=1;
else
if(x<0)y=-1;
elsey=0;
c)(内嵌在if语句的两个分支中)
if(expr1)
if(expr2)statement1
elsestatement2
else
if(expr3)statement3
elsestatement4
如:
if(a>b)
if(a>c)max=a;
elsemax=c;
else
if(b>c)max=b;
elsemax=c;
(2)if~else配对原则:
在程序的书写上最好采用比较规范的缩排格式,即不同层次的if-else写在不同的缩排级上,这样可以使人对程序中if语句的嵌套层次看得比较清晰明了。
但即使如此,计算机并不能识别人的意图,C语言规定:
缺省{}时,else总是和它上面离它最近的未配对的if配对
如:
if(a==b)
if(b==c)printf(“a==b==c”);
elseprintf(“a!
=b”);
等价于:
if(a==b)
if(b==c)printf(“a==b==c”);
elseprintf(“a!
=b”);
如果需要else与非默认的if配对,必须用花括号来确定配对关系,如:
修改后:
if(a==b)
{if(b==c)
printf(“a==b==c”);
}
elseprintf(“a!
=b”);
◆例题:
例4-3.输入两数并判断其大小关系
/*ch4_3.c*/
#include
main()
{intx,y;
printf("Enterintegerx,y:
");
scanf("%d,%d",&x,&y);
if(x!
=y)
if(x>y)printf("X>Y\n");
elseprintf("Xelse
printf("X==Y\n");
}
运行程序:
※Enterintegerx,y:
12,23<回车>
X※Enterintegerx,y:
12,6<回车>
X>Y/*输出结果*/
※Enterintegerx,y:
12,12<回车>
X==Y/*输出结果*/
例4-4考虑下面程序输出结果:
/*ch4_4.c*/
main()
{intx=100,a=10,b=20;
intv1=5,v2=0;
if(a
if(b!
=15)
if(!
v1)x=1;
else
if(v2)x=10;
x=-1;
printf(“%d”,x);
}
运行结果:
-1
4.条件运算符
C语言有一个三元运算符,称为条件运算符。
它由一个“?
”和一个“:
”组成,可以连接三个运算量组成条件表达式,一般格式为
exp1?
exp2:
exp3
其中,exp1、exp2和exp3都是表达式,其功能是:
先计算exp1,若exp1≠0,则计算exp2,将exp2的值作为整个条件表达式的值;若exp1=0,则计算exp3,将exp3的值作为整个条件表达式的值。
例如,
(a>b)?
a:
b
当a>b时,取a的值;当a≤b时,取b的值。
条件运算符的优先级仅高于赋值运算符和逗号运算符,低于其他运算符,因此,上面式子(a>b)中的括号可以省略。
条件运算符的结合性为从右至左。
例如,
exp1?
exp2:
exp3?
exp4:
exp5
等价于
exp1?
exp2:
(exp3?
exp4:
exp5)
而
exp1?
exp2?
exp3:
exp4:
exp5
则等价于
exp1?
(exp2?
exp3:
exp4):
exp5
如:
a=1,b=2,c=3,d=4a>b?
a:
c>d?
c:
d=?
a>b?
a:
c>d?
c:
d等价于a>b?
a:
(c>d?
c:
d)
结果为:
4
例转换大写字母为小写字母ˋ
main()
{charch;
scanf(“%c”,&ch);
ch=(ch>=‘A’&&ch<=‘Z’)?
(ch+32):
ch;
printf(“%c”,ch);
}
§4.4switch语句(开关分支语句)
1.一般形式:
switch(表达式)
{case常量表达式E1:
语句1;
break;
case常量表达式E2:
语句2;
break;
……
case常量表达式En:
语句n;
break;
[default:
语句n+1;
break;]
}
2.执行过程:
●如果去掉break语句,执行过程将变为:
不带break的switch语句
●关于break语句:
从上图可以看出,在switch语句中,如果执行到某个case中的语句后,会接下去执行下一个。
这种往下贯穿各个case的方法有优点也有缺点。
从积极的方面讲,它使一个操作可以有多个case,可以达到“一石多鸟”的效果。
但是另一方面,从一个case下落到另一个case是不牢靠的,因为当修改程序时,很容易造成混乱。
因此,作为一个较好的程序结构和一种保护措施,在每一个case语句序列的末尾加上一条break语句,强迫控制立即退出switch,这就防止了从一个case下落到另一个case中。
而且这样做的另一个好处是一旦后面还要再添加case时,程序流程不会受到影响。
加上break后,switch语句的执行流程见前图。
后面还要看到,break语句还可用在循环语句中,强迫控制立即退出循环。
3.有关switch语句的几点说明:
★E1,E2,…,En是常量表达式,且值必须互不相同
★E1,E2,…En应避免使用实型
★E1,E2,…,En起语句标号作用,必须用break跳出
★case后可包含多个可执行语句,且不必加{}
★default适合于表达式的值不是E1…En的情况,也可以缺省
★switch可嵌套(但break只跳出一层switch语句)
★多个case可共用一组执行语句
如:
……
case‘A’:
case‘B’:
case‘C’:
printf(“score>60\n”);
break;
……
4.例题
例:
switch(score)
{case5:
printf(“Verygood!
”);
case4:
printf(“Good!
”);
case3:
printf(“Pass!
”);
case2:
printf(“Fail!
”);
default:
printf(“dataerror!
”);
}
运行结果:
score为5时,输出:
Verygood!
Good!
Pass!
Fail!
dataerror!
例4-5:
/*ch4_5.c*/
main()
{intx=1,y=0,a=0,b=0;
switch(x)
{case1:
switch(y)
{case0:
a++;break;
case1:
b++;break;
}
case2:
a++;b++;break;
case3:
a++;b++;
}
printf(“\na=%d,b=%d”,a,b);
}
运行结果:
a=2,b=1
例1
例1.
3.
1.
1.