第9章 运算符与表达式.docx
《第9章 运算符与表达式.docx》由会员分享,可在线阅读,更多相关《第9章 运算符与表达式.docx(16页珍藏版)》请在冰豆网上搜索。
第9章运算符与表达式
第9章运算符与表达式
C语言对数据有很强的表达能力,具有十分丰富的运算符,利用这些运算符可以组成各种表达式及语句。
运算符就是完成某种特定运算的符号。
表达式则是由运算符及运算对象所组成的具有特定含义的一个式子。
由运算符或表达式可以组成C语言程序的各种语句。
C语言是一种表达式语言,在任意一个表达式的后面加一个分号“;”就构成了一个表达式语句。
按照运算符在表达式中所起的作用,可分为算术运算符、关系运算符、逻辑运算符、赋值运算符、增量与减量运算符、逗号运算符、条件运算符、位运算符、指针和地址运算符、强制类型转换运算符和sizeof运算符等。
运算符按其在表达式中与运算对象的关系,又可分为单目运算符、双目运算符和三目运算符等。
单目运算符只需要有一个运算对象,双目运算符要求有两个运算对象,三目运算符要求有三个运算对象。
9.1算术运算符与表达式
C语言提供的算术运算符有:
+加或取正值运算符。
如:
1+2的结果为3。
-减或取负值运算符。
如:
4-3的结果为1。
*乘运算符。
如:
2*3的结果为6。
/除运算符。
如:
6/3的结果为2。
%模运算符,或称取余运算符。
如:
7%3的结果为1。
上面这些运算符中加、减、乘、除为双目运算符,它们要求有两个运算对象。
取余运算要求两个运算对象均为整型数据,如果不是整型数据可以采用强制类型转换。
例如8%3的结果为2。
取正值和取负值为单目运算符,它们的运算对象只有一个,分别是取运算对象的正值和负值。
9.2进行数学运算并将结果在51MCUDEMO试验板上输出显示。
9.2.1实现方法
定义4个无符号字符型变量out、a、b、c,给a、b、c赋初值,然后按公式out=a+3*(b-c)/2进行数学运算,结果在数码管上显示出来。
9.2.2源程序文件
在D盘建立一个文件目录(CS9-1),然后建立CS9-1.uv2的工程项目,最后建立源程序文件(CS9-1.c)。
输入下面的程序:
#include//1
#defineucharunsignedchar//2
#defineuintunsignedint//3
ucharcodeSEG7[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//4
voiddelay(uintk);//5
//=====================6=========
voidmain(void)//7
{//8
uchara,b,c,out;//9
a=100;//10
b=60;//11
c=9;//12
out=a+3*(b-c)/2;//13
while
(1)//14
{//15采用静态显示方法。
P0=SEG7[out/100];//16
P2=0xfb;//17
delay
(1);//18
P0=SEG7[(out%100)/10];//19
P2=0xfd;//20
delay
(1);//21
P0=SEG7[out%10];//22
P2=0xfe;//23
delay
(1);//24
}//25
}//26
//=====================27==
voiddelay(uintk)//28
{//29
uinti,j;//30
for(i=0;ifor(j=0;j<121;j++)//32
{;}}//33
}//34
编译通过后,51MCUDEMO试验板接通5V稳压电源,将生成的CS9-1.hex文件下载到试验板上的单片机89S51中,注意,标示“LEDMOD_DATA”及“LEDMOD_COM”的双排针应插上短路块。
右边3个LED数码管显示“176”。
这个结果正确吗?
我们验证一下:
由于b-c加了括号,因此优先级最高,其差值为51。
接下来乘法的优先级要高于其它运算符,因此51乘3等于153。
再下来153除2得76.5,舍去小数部分,得76。
76加100,结果为176。
完全正确。
9.2.3程序分析解释
序号1:
包含头文件REG51.H。
序号2~3:
数据类型的宏定义。
序号4:
数码管0~9的字形码。
序号5:
延时子函数声明。
序号6:
程序分隔。
序号7:
定义函数名为main的主函数。
序号8:
main的主函数开始。
序号9:
定义无符号字符型变量a、b、c、out。
序号10:
a赋值100。
序号11:
b赋值60。
序号12:
c赋值9。
序号13:
数学运算,其结果放out。
序号14:
while循环语句进行无限循环。
序号15:
while循环语句开始。
序号16:
取出out的百位数送P0口显示。
说明:
out除100,得out的百位数(其十、个位均成为小数而舍去)。
序号17:
点亮百位数码管。
序号18:
延时1mS以便观察清楚。
序号19:
取出out的十位数送P0口显示。
说明:
out余100,得out的十、个位数,然后再除10,取得out的十位数。
序号20:
点亮十位数码管。
序号21:
延时1mS以便观察清楚。
序号22:
取出out的个位数送P0口显示。
说明:
out余10,得out的个位数。
序号23:
点亮个位数码管。
序号24:
延时1mS以便观察清楚。
序号25:
while循环语句结束。
序号26:
main的主函数结束。
序号27:
程序分隔。
序号28~34:
延时子函数。
9.3关系运算符与表达式
C语言中有以下的关系运算符:
>大于。
如:
x>y。
<小于。
如:
a<4。
>=大于等于。
如:
x>=2。
<=小于等于。
如:
a<=5。
==测试等于。
如:
a==b。
!
=测试不等于。
如:
x!
=5。
前4种关系运算符(>,<,>=,<=)具有相同的优先级,后两种关系运算符(==,!
=)也具有相同的优先级,但前4种的优先级高于后2种。
关系运算符通常用来判别某个条件是否满足,关系运算的结果只有“真”和“假”两种值。
当所指定的条件满足时结果为1,条件不满足时结果为0。
1表示“真”,0表示“假”。
9.4在51MCUDEMO试验板上实现输入数的大小比较及判断
按下S2键或S1键后,输入两个小于10的整数a、b,其中a在数码管上十位上显示。
b在数码管个位上显示,由程序判断a、b的大小:
若a>b,则数码管千位上显示“H”;若a=b,则数码管千位上显示“=”;若a
9.4.1实现方法
定义3个无符号字符型变量a、b、c,通过按键输入,给a、b各赋一个小于10的值,然后用关系运算符进行a、b的判断。
a>b,c赋值0x76;a
将结果c在数码管上显示出来即可。
9.4.2源程序文件
在D盘建立一个文件目录(CS9-2),然后建立CS9-2.uv2的工程项目,最后建立源程序文件(CS9-2.c)。
输入下面的程序:
#include//1
#defineucharunsignedchar//2
#defineuintunsignedint//3
ucharcodeSEG7[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//4
//=========================5=======
uchara=0,b=0,c;//6
//-----------------------------------------7
ucharkey_S1(void);//8
ucharkey_S2(void);//9
voiddelay(uintk);//10
//-----------------------------------------11
voidmain(void)//12
{uchari;//13
while
(1)//14
{//15
b=key_S1();//16
a=key_S2();//17
if(a>b)c=0x76;//18
if(a
if(a==b)c=0x09;//20
for(i=0;i<50;i++)//21
{//22
P0=SEG7[a];//23
P2=0xfd;//24
delay
(2);//25
P0=SEG7[b];//26
P2=0xfe;//27
delay
(2);//28
P0=c;//29
P2=0xf7;//30
delay
(2);//31
}//32
}//33
}//34
//------------------------------------------35
voiddelay(uintk)//36
{//37
uinti,j;//38
for(i=0;ifor(j=0;j<121;j++)//40
{;}}//41
}//42
//------------------------------------------43
ucharkey_S1(void)//44
{staticucharx;//45
P3=0xff;//46
if(P3!
=0xff)//47
{delay(10);//48
if(P3==0xfb)//49若P3口等于0xfe,说明接下的为S1键
{//50
x=x+1;//51
}//52
}//53
if(x>9)x=0;//54
returnx;//55
}//56
//------------------------------------------57
ucharkey_S2(void)//58
{staticuchary;//59
P3=0xff;//60
if(P3!
=0xff)//61
{delay(10);,//62
if(P3==0xf7)//63
{//64
y=y+1;//65
}//66
}//67
if(y>9)y=0;//68
returny;//69
}//70
编译通过后,51MCUDEMO试验板接通5V稳压电源,将生成的CS9-2.hex文件下载到试验板上的单片机89S51中,注意,标示“LEDMOD_DATA”及“LEDMOD_COM”的双排针应插上短路块。
右边2个数码管显示“00”,千位数码管显示“=”。
按下S2键,十位数码管上的数字开始递增,当十位数码管的数字大于个位数码管时,千位数码管显示“H”;按下S1键,个位数码管上的数字开始递增,当个位数码管的数字大于十位数码管时,千位数码管显示“L”;,当个位数码管的数字等于十位数码管时,千位数码管显示“=”。
程序自己判别出了两个数值的大小,并将结果显示出来。
9.4.3程序分析解释
序号1:
包含头文件REG51.H。
序号2~3:
数据类型的宏定义。
序号4:
数码管0~9的字形码。
序号5:
程序分隔。
序号6:
定义无符号字符型全局变量a、b、c。
序号7:
程序分隔。
序号8~10:
函数声明。
序号11:
程序分隔。
序号12:
定义函数名为main的主函数。
序号13:
main的主函数开始。
定义无符号字符型局部变量i。
序号14:
while循环语句进行无限循环。
序号15:
while循环语句开始。
序号16:
调用S1键判断子函数,其键值返回至变量b中。
序号17:
调用S2键判断子函数,其键值返回至变量a中。
序号18:
若a>b,c赋值0x76。
序号19:
若a
序号20:
若a等于b,c赋值0x09。
序号21:
for循环语句,共循环50次。
序号22:
for循环语句开始。
序号23:
变量a送P0口。
序号24:
点亮数码管十位。
序号25:
延时2ms。
序号26:
变量b送P0口。
序号27:
点亮数码管个位。
序号28:
延时2ms。
序号29:
变量c送P0口。
序号30:
点亮数码管千位。
序号31:
延时2ms。
序号32:
for循环语句结束。
序号33:
while循环语句结束。
序号34:
main主函数结束。
序号35:
程序分隔。
序号36~42:
延时子函数。
序号43:
程序分隔。
序号44:
定义函数名为key_S1的按键判断子函数。
序号45:
key_S1子函数开始。
定义静态的局部变量x。
序号46:
P3口置全1,以便读取按键状态。
序号47:
若P3口不为0xff,说明可能有键按下。
序号48:
延时10ms再判。
序号49:
若P3口等于0xfe,说明接下的为S1键。
序号50~52:
变量x递增。
序号53:
结束if(P3!
=0xff)语句。
序号54:
若x的值超过9,则赋0。
序号55:
返回x的值。
序号56:
key_S1子函数结束。
序号57:
程序分隔。
序号58~70:
函数名为key_S2的按键判断子函数,具体可参考序号44~56分析。
9.5逻辑运算符与表达式
C语言中提供的逻辑运算符有3种:
||逻辑或
&&逻辑与
!
逻辑非
逻辑运算的结果也只有两个:
“真”为1,“假”为0。
逻辑表达式的一般形式为:
逻辑与:
条件式1&&条件式2
逻辑或:
条件式1||条件式2
逻辑非:
!
条件式
9.6赋值运算符与表达式
9.6.1简单赋值运算
在C语言中,最常见的赋值运算符为“=”,赋值运算符的作用是将一个数据的值赋给一个变量,利用赋值运算符将一个变量与一个表达式连接起来的式子称为赋值表达式,在赋值表达式的后面加一个分号“;”便构成了赋值语句。
例如:
x=5;
9.6.2复合赋值运算符
在赋值运算符“=”的前面加上其他运算符,就构成了所谓复合赋值运算符。
具体如下所示:
+=加法赋值运算符
-=减法赋值运算符
*=乘法赋值运算符
/=除法赋值运算符
%=取模(取余)赋值运算符
>>=右移位赋值运算符
<<=左移位赋值运算符
&=逻辑与赋值运算符
|=逻辑或赋值运算符
^=逻辑异或赋值运算符
~=逻辑非赋值运算符
复合赋值运算首先对变量进行某种运算,然后将运算的结果再赋给该变量。
复合运算的一般形式为:
变量复合赋值运算符表达式
例如:
a+=5等价于a=a+5;
采用复合赋值运算符,可以使程序简化,同时还可以提高程序的编译效率。
9.7在51MCUDEMO试验板上实现逻辑判断
按下S1键,个位数码管上显示输入值“5”;按下S2键,十位数码管上显示输入值“8”;若同时按下S1、S2键,则除了个位、十位数码管显示外,千位数码管还显示“P”。
9.7.1实现方法
定义3个无符号字符型变量a、b、out,通过按键输入,给a、b分别赋值8、5,然后用逻辑运算符进行a、b的判断。
a=8并且同时b=5,out赋值1,否则out赋值0。
下来再对out进行判断,若out为1,则使千位数码管显示“P”,否则千位数码管熄灭。
9.7.2源程序文件
在D盘建立一个文件目录(CS9-3),然后建立CS9-3.uv2的工程项目,最后建立源程序文件(CS9-3.c)。
输入下面的程序:
#include//1
#defineucharunsignedchar//2
#defineuintunsignedint//3
sbitP3_2=P3^2;//4
sbitP3_3=P3^3;//5
ucharcodeSEG7[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//6
//=========================7=======
uchardataa=0,b=0,out;//8
//------------------------------------------9
ucharkey_S1(void);//10
ucharkey_S2(void);//11
voiddelay(uintk);//12
//------------------------------------------13
voidmain(void)//14
{//15
while
(1)//16
{//17
b=key_S1();//18
a=key_S2();//19
if((a==8)&&(b==5))out=1;//20
elseout=0;//21
P0=SEG7[a];//22
P2=0xfd;//23
delay
(2);//24
P0=SEG7[b];//25
P2=0xfe;//26
delay
(2);//27
if(out==1)P0=0x73;//28
elseP0=0x00;//29
P2=0xf7;//30
delay
(2);//31
}//32
}//33
//------------------------------------------34
voiddelay(uintk)//35
{//36
uinti,j;//37
for(i=0;ifor(j=0;j<121;j++)//39
{;}}//40
}//41
//------------------------------------------42
ucharkey_S1(void)//43
{uchardatax;//44
P3=0xff;//45
if(!
P3_2)x=5;//46
elsex=0;//47
returnx;//48
}//49
//------------------------------------------50
ucharkey_S2(void)//51
{uchardatay;//52
P3=0xff;//53
if(!
P3_3)y=8;//54
elsey=0;//55
returny;//56
}//57
编译通过后,51MCUDEMO试验板接通5V稳压电源,将生成的CS9-3.hex文件下载到试验板上的单片机89S51中,注意,标示“LEDMOD_DATA”及“LEDMOD_COM”的双排针应插上短路块。
右边2个数码管显示“00”。
按下S1键,个位数码管上显示“5”;按下S2键,十位数码管上显示“8”;同时按下S1、S2键后,观察到千位数码管显示“P”。
9.7.3程序分析解释
序号1:
包含头文件REG51.H。
序号2~3:
数据类型的宏定义。
序号4:
定义P3.2的符号名为P3_2。
序号5:
定义P3.3的符号名为P3_3。
序号6:
数码管0~9的字形码。
序号7:
程序分隔。
序号8:
在data区定义无符号字符型全局变量a、b、out。
序号9:
程序分隔。
序号10~12:
函数声明。
序号13:
程序分隔。
序号14:
定义函数名为main的主函数。
序号15:
main的主函数开始。
序号16:
while循环语句进行无限循环。
序号17:
while循环语句开始。
序号18:
调用S1键判断子函数,其键值返回至变量b中。
序号19:
调用S2键判断子函数,其键值返回至变量a中。
序号20:
如果a为8且b为5同时成立(逻辑与),则out赋值1。
序号21:
否则out赋值0。
序号22:
变量a送P0口。
序号23:
点亮数码管十位。
序号24:
延时2ms。
序号25:
变量b送P0口。
序号26:
点亮数码管个位。
序号27:
延时2ms。
序号28:
如果out为1,则P0口赋值0x73。
序号29:
否则P0口赋值0x00。
序号30:
点亮数码管千位。
序号31:
延时2ms。
序号32:
while循环语句结束。
序号33:
main主函数结束。
序号34:
程序分隔。
序号35~41:
延时子函数。
序号42:
程序分隔。
序号43:
定义函数名为key_S1的键判断子函数。
序号44:
key_S1子函数开始。
定义局部变量x。
序号45:
P3口置全1,以便读取按键状态。
序号46:
如果P3.2为低电平(S1键按下),x赋值5。
序号47:
否则x赋值0。
序号48:
返回x值。
序号49:
key_S1子函数结束。
序号50:
程序分隔。
序号51~57:
函数名为key_S2的键判断子函数,具体可参考序号43~49分析。