STC单片机C语言程序设计-第10章-STC单片机C语言运算符

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

STC单片机C语言运算符主讲:何宾Email:hebin@mail.buct.edu.cn2016.03在C语言中,提供了丰富的运算符用于实现复杂的运算功能,包括:算术运算、逻辑运算及逻辑判断等。本章将详细的介绍C语言中所提供的赋值运算符、算术运算符、递增和递减运算符、关系运算符、逻辑运算符、位运算符、符合赋值运算符、逗号运算符、条件运算符、强制类型转换符以及sizeof运算符。通过本章内容的学习,掌握C语言运算符的表示方法及所实现的功能,灵活高效地运用这些运算符实现对数据进行处理。STC单片机C语言运算符在C语言中,提供了丰富的运算符用于对数据的处理。通过运算符和数据的有效合理搭配,就构成了可以完成所要求运算功能的表达式。对于C语言的运算符来说,可以从下面的角度进行分类:根据所实现的功能,C语言中的运算符可以分为赋值运算符、算术运算符、递增和递减运算符、关系运算符、逻辑运算符、位运算符、符合赋值运算符、逗号运算符、条件运算符、指针和地址运算符、强制类型转换运算符和sizeof等运算符。C语言运算符分类根据参与运算数据的个数,C语言中的运算符可以分为单目运算符、双目运算符和三目运算符。对于单目运算符,只有一个操作数。典型地,包括:递增递减运算符、取地址运算符、指针运算符、取正数运算符,取负数运算符、按位取反运算符和sizeof运算符。对于双目操作符,有两个操作数。典型地,包括加法、减法、乘法和除法运算符等。对于三目操作符,有三个操作数。典型地,条件运算符。C语言运算符分类所谓的运算符优先级是指,在一个运算表达式中,执行运算的先后顺序。在C语言中,共分了15级优先级,最高优先级称为第1级,最低优先级称为第15级,也就是所数字越高优先级越低。注:表中的一些其它运算符在后续章节中将详细介绍。C语言运算符优先级在C语言中,赋值操作使用“=”号实现,“=”称为赋值运算符,赋值语句的格式为:变量=表达式;先计算由表达式所得到的值,然后在将该值分配给变量。【例10-1】不同类型之间赋值操作的例子代码清单10-1main.c文件intmain(){volatileunsignedinta;//定义无符号的整型变量a,带有volatile属性volatileintb=-2345;//定义带符号的整型变量,初值为-2345a=b;//将b的值赋给a,return0;}赋值运算符读者可以进入到本书所提供资料的stc_program_example\例子10-1\目录下,在KeilμVision5集成开发环境下打开该设计,并进入调试器模式,使用单步运行。根据前面说提到的,由于b是有符号的变量,而a是无符号的变量,当把有符号变量的数赋值给无符号变量a的时候,会有什么结果?下面对该段代码进行分析。在Disassembly窗口中,查看该段C语言代码的反汇编代码。赋值运算符代码清单10-2main.c的反汇编代码2:{3:volatileunsignedinta;4:volatileintb=-2345;C:0x0003750AF6MOV0x0A,#0xF6C:0x0006750BD7MOV0x0B,#0xD75:a=b;C:0x0009850A08MOV0x08,0x0AC:0x000C850B09MOV0x09,0x0B6:return0;赋值运算符C:0x000FE4CLRAC:0x0010FEMOVR6,AC:0x0011FFMOVR7,A7:}从代码很清楚的可以知道下面的事实,即:将立即数0xF6D7保存到8051单片机片内基本数据RAM地址为0x0A和0x0B的空间,该数字是变量b的值-2345的二进制补码表示。b=a的操作就是,将8051单片机片内基本数据RAM地址为0x0A和0x0B的内容保存到8051片内基本数据RAM地址为0x08和0x09的位置,也就是变量a的内容。赋值运算符但是声明a是无符号的整数,因此就将8051片内基本数据RAM地址为0x08和0x09位置的内容当作无符号处理即0xF6D7的无符号数表示为63191。因此a的值最终表示为63191,b的值最终表示为-2345。注:虽然这两个变量a和b的值在8051片内基本数据RAM内饰完全一样的,但是由于在声明变量a和b的时候,其类型是不同的,因此最终导致对0xF6D7的理解完全不同。通过这个分析过程清楚地知道,要想学好C语言是需要了解一些CPU的细节的,否则C语言的这些语法是无法彻底理解清楚的。赋值运算符从上面的过程可以清楚地看出来赋值的过程:赋值过程是从右到左,即先等到“=”号右侧表达式的值;然后,在将右侧表达式的值赋值给“=”号左侧的变量。在赋值过程中,如果“=”号左右两侧的数据类型不相同的时候,将右侧表达式的值自动的转换到与“=”左侧的数据类型相一致。赋值运算符在调试器模式下,在keilμVision集成开发环境右下角的Watch1窗口中,分别输入两个变量a和b的名字,在右侧可以清楚地显示这两个变量的值,一目了然。退出调试器模式,并关闭该设计。赋值运算符【例10-2】正确赋值操作的例子代码清单10-3main.c文件intmain(){inta;charb;floatc;a=10000;b=200;c=0.5;return0;}赋值运算符总结:当赋值运算符两边的运算对象不同时,将要发生类型转换,转换的规则是:把赋值运算符右侧表达式的类型转换为左侧变量的类型,即:浮点型float与整型int。将浮点数转换为整数时,将舍弃浮点数的小数部分,只保留整数部分。将整数值赋值给浮点变量时,数值保持不变,只是将形式改为浮点形式。字符型char与整型int。当整型int数值赋值给字符型char变量时,只保留其最低8位,高位部分舍弃。当字符型char数值赋值给int型变量时,如果原来的char型数据取正值,转换后仍为正值;如果原来char型值可正可负,则转换后保持原值,只是数据的内部表示形式有所不同,比如对于下面代码:赋值运算符volatilechara=-127;volatileintc;c=a;当a赋值给c后,c的值也是-127。只不过a和c在8051单片机内表示的形式不同而已,a=-127用一个字节表示为0x81,而c=-127用两个字节表示为0xFF81,从实质上来说,也是符号扩展。当变量a值的符号位为1,表示负数时,使用1扩展,即用1将高位填满得到整型变量的值;当变量a的符号位为0,表示正数时,使用0扩展,即用0将高位填满得到整型变量的值。赋值运算符整型int与长整型long。当把长整型long的数值赋值给整型int变量时,将低16位值送给int型变量,而将高16位截断舍弃;将整型int的数值赋值给长整型long变量时,其外部值保持不变,而内部形式有所改变,比如对于下面的代码:volatileinta=-32768;volatilelongintc;c=a;赋值运算符当a赋值給c后,c的值也是-32768。只不过a和c在8051单片机内表示的形式不同而已,a=-32768用两个字节表示为0x8000,而c=-127用四个字节表示为0xFFFF8000,从实质上来说,也是符号扩展。当变量a值的符号位为1,表示负数时,使用1扩展,即用1将高位填满得到长整型变量的值;而当变量a的符号位为0,表示正数时,使用0扩展,即用0将高位填满得到长整型变量的值。无符号整数。将一个无符号型unsigned数据赋值给一个占用相同存储单元的整型变量时,比如unsignedint到int,unsignedlong到long,unsignedshort到short,原值照赋,内部存储方式不变,但是外部的值可能变化,对于下面的代码:volatileunsignedinta=40001;volatileintc;c=a;赋值运算符因为a为无符号的整型变量,它在8051单片机中占用两个字节表示为0x9c41。当赋值给c的时候,将0x9c41赋值给c,但是由于c为带符号的整型变量,此时将0x9c41理解为负数,也就是补码,等效的十进制数为-25535。当把一个非unsigned整型数据赋值给长度相同的unsigned型变量时,内部存储实型不变,但是外部表示时总是无符号的,对于下面的代码:volatileinta=-30000;volatileunsignedintc;c=a;赋值运算符因为a是有符号的整型变量,它在8051单片机内占用两个字节表示为0x8ad0。当赋值给c的时候,将0x8ad0赋值给c,但是由于c为无符号的整型变量,此时将0x8ad0理解为正数,即十进制数的35536。C语言这种赋值时的类型转换形式可能会使程序员感到不严谨,因为不管表达式的值怎样,系统都自动将其转换为赋值运算符左边变量的类型。注:在进行赋值操作的时候,一定要注意变量和表达式值的数据类型。否则,会产生意想不到的后果,这可能是C语言的一个缺点,但是不要忘记当初C语言出现的时候,就是为了替换汇编语言而设计的,所以类型变换比较随意。赋值运算符在C语言中,所提供的算术运算符包括:+(加法运算或者取正数运算)、-(减法运算或者取负数运算)、*(乘法运算)、/(除法运算)、%(取余运算)。在这些算术运算中,除取正和取负运算是单目运算外,其他都是双目运算。在求取表达式的值时,按照运算符的优先级进行。按照下面优先级:单目运算的优先级要高于双目运算。在双目运算中,优先级按照*、/、%、+、-从高到低排列。程序员可以通过使用()修改运算的优先级顺序。算术运算符对于整数除法运算来说,遵循以下的规则:整数相除且不能整除时,如果除数和被除数其中只有一个为负数,运算符“/”的运算结果就为负数;如果除数和被除数两个均为负数,运算符“/”的运算结果就为正数,这与代数运算的结果一致。整数相除且不能整除时,如果除数和被除数中出现负数,则运算符“%”的运算结果由表达式(a/b)*b+a%b=a确定,即a%b=a-(a/b)*b。对于运算符“/”和“%”来说,除数(第二个操作数)不能为0。算术运算符【例10-3】有符号整数相除的例子。代码清单10-4main.c文件intmain(){inta1=-20,b1=3,c1,d1;inta2=20,b2=-3,c2,d2;inta3=-20,b3=-3,c3,d3;c1=a1/b1;d1=a1%b1;c2=a2/b2;d2=a2%b2;c3=a3/b3;d3=a3%b3;return0;}算术运算符【例10-4】不同数据类型运算和赋值的例子。代码清单10-5main.c文件intmain(){inta=1000,b=30,c=15;floatd,e;d=a/b*c;e=a/(b*c);return0;}算术运算符下面对该程序代码进行分析。对于d=a/b*c的运算来说:“=”号右侧都是整型变量,因此按照整数运算的规则。先计算a/b的结果,然后该结果再与c相乘。由于等号左侧变量d的数据类型为浮点数,所以将等号右侧的整型运算结果转换成浮点型,然后赋值给变量d。算术运算符对于e=a/(b*c)运算来说:“=”号右侧都是整型变量,因此按照整数运算的规则。在该运算中,通过符号“()”改变了运算顺序,即先计算b*c的结果,然后a再与该结果相除。由于等号左侧变量e的数据类型为浮点数,所以将等号右侧的整型运算结果转换成浮点型,然后赋值给变量e。算术运算符【例10-5】算术运算操作的例子代码清单10-6main.c文件intmain(){inta=1000,b=33,c,d,h,i;longinte,j;floatm=13414e-3,n=0.6547;floatf,g,k,l;c=a/b;//整数除法,求商d=a%b;//整数除法,求余e=a*b;//乘法求积f=a/b;//整数除法,然后类型转换算术运算符g=a+b-c;//整数加法和减法运算,然后类型转换h=(a+b)*c;//带()的优先级加法和乘法运算i=b-a*c;//整数乘法

1 / 61
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功