您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > 第3章 操作符与表达式
C程序设计周二强zeq@hncj.edu.cn软件学院计算机科学与工程系第3章操作符与表达式3.1概述3.2赋值操作符和赋值表达式3.2.1赋值操作符3.2.2类型不匹配时的赋值操作3.2.3复合赋值操作符3.3算术操作符和算术表达式3.3.1算术表达式的求值3.3.2强制类型转换操作符3.3.3自增自减操作符3.4逗号操作符和逗号表达式3.5值与编译系统相关的表达式3.6典型例题分析操作符操作符也称运算符,是一种表示对数据进行何种处理的符号,如+,-,*,&等。操作符处理的对象(数据)称为操作数。操作数可以是字面量、变量或函数调用等。根据所需操作数的个数,操作符可分类为单目操作符(一个操作数),双目操作符(二个操作数)和三目操作符(三个操作数)。根据功能,操作符可分为赋值、算术、关系与逻辑、位和地址操作符等几种。表达式用操作符把操作数连接起来的,符合C语言语法规则的式子如3+2*5-6,称作表达式。C语言丰富的操作符构成了种类繁多的表达式。C语言表达式最重要的特征是每个表达式都有一个确定的值及(该值的)类型。所谓表达式的值是指按照规定的规则,对表达式进行运算所得到的结果。求解表达式的值要求解表达式的值就必须熟悉操作符的运算顺序。表达式中操作符的运算顺序服从于操作符的优先级和结合性规则。3+2*5-6优先级规则要求表达式求值时,优先级高的操作符先进行运算,类似于熟知的“先乘除后加减”规则。表达式中两个相邻的操作符具有相同的优先级时,首先运算哪一个操作符的问题由操作符的结合性规则来决定。结合性显然优先级相同的操作符的结合性也相同。若按自左向右的顺序进行运算,则称该优先级的操作符的结合性为左结合;若按自右向左的顺序进行运算,则称该优先级的操作符的结合性为右结合。+、-、*、/C语言表达式举例其中的字母均为变量。i+(j–m/n)%5n5&&i%3==0x=y++%2ij?n=2:n=-2n=2x=3,y*=6,89+56常见的数学运算C语言表达式中的操作符和操作数必须写在同一行上。对于数学上复杂的表达式如在改写成单行的表达式时需用到库函数。常见的数学运算如求绝对值、求平方根、求幂等在C语言中都已用库函数实现,如求绝对值可用fabs函数,求平方根可用sqrt函数,求幂可用pow函数。有关数学运算的库函数归类在数学库中,在math.h头文件中声明。用include命令把math.h头文件包含到程序中后,就可以方便地使用这些有关数学运算的库函数了。(fabs(a)+sqrt(b*b-pow(x,y)))/5(fabs(a)+sqrt(b*b-pow(x,y)))*0.2表达式求值和C语句表达式求值时,不仅需要注意操作符的优先级和结合性,还需注意操作数的数据类型和表达式的序列点。5/25/2.0在后面加一个分号(;),C语言表达式就变成了C语句,此时计算机执行C语句的过程,就是对表达式“求值”的过程。return3.2赋值操作符和赋值表达式赋值操作符“=”是双目操作符、右结合,由它构成的赋值表达式的一般形式为:变量=表达式。赋值表达式的操作是先计算出右边子表达式的值,再把值转换成变量的类型后存入变量所标示的存储空间。如:i=5/2;由于赋值操作符的优先级较低,可记为:先计算再赋值。例3-1分析下面程序的运行变量i的值并不会消失赋值语句i=i+1;执行过程中,会先计算赋值操作符右边子表达式i+1的值。在求i+1的值时变量i的值(1)被取到运算器中,然后运算器求出i+1的值为2。接着,计算结果会由运算器传回到变量i所标识的存储单元中,变量i值变为2。变量i的值并不会因被“取到”运算器中而消失。计算后,运算器中的和会被赋值给变量i,因此这条语句不矛盾。变量i的值并不会消失执行赋值语句j=i;时,变量i所标示的内存空间的存储状态(2的补码)会被传送到变量j所标示的内存空间中,因此变量j的值变为2,变量j原来的值因为存储状态的改变而消失,但是变量i的值仍然为2,因为变量i所标示的内存空间的存储状态没有改变仍然为2的补码。计算机在执行时只是检测一下(只是检测没有改变)变量i所标示的内存空间的状态(相关导线上的开关是接通还是断开),然后把变量j所标示的内存空间也设置成同样的状态。赋值表达式合法吗?赋值操作符左边的操作数只能是变量,如3=i、i++=5和a+b=23等的赋值表达式都不合法。赋值表达式i=j=k=23合法吗?赋值操作是右结合,故该表达式的操作顺序为i=(j=(k=23))。子表达式k=23是一个合法的赋值表达式。C语言表达式都有一个值,赋值表达式的值就是该表达式左边的操作数,即变量,也就是说表达式k=23执行完赋值操作后,它的值就是k,此时原表达式变为i=(j=k)。问题表达式(a=3*2)=5*7,与表达式a=3*2=5*7等价吗?=3*2)=5*7执行时,先计算子表达式a=3*2,值为a,故原表达式变为a=5*7。原表达式执行时,变量a先被赋值为6,后又被赋值为35。表达式a=3*2=5*7等价于a=(3*2=5*7)即a=(6=35)。子表达式6=35是不合法的赋值表达式(左操作数非变量),因此表达式a=3*2=5*7非法。合法并不代表合理注意:表达式(a=3*2)=5*7合法并不代表合理!为什么要写这样的代码呢?在某些编译系统中赋值表达式的值为变量的值(如23)并非变量(如k),语句i=j=k=23;应理解成k=23;j=23;i=23;三条赋值语句的简写形式。此时,赋值表达式(a=3*2)=5*7求值后变为6=5*7,也不合法。程序员应该牢记,程序的可读性是程序最重要的属性之一。return3.2.2类型不匹配时的赋值操作所谓类型不匹配时的赋值操作是指赋值表达式中赋值操作符左边子表达式值的类型与右边变量的类型不一致。字符型数据在内存中以ASCII码形式存储,ASCII码可以看成整数,因此C语言允许字符型数据与整型数据通用。把字符型看作码长一个字节的整型后,C语言的基本数据类型就只有整型和浮点型两大类了。因此类型不匹配时的赋值操作有?1.整型之间相互赋值编码长度相同的整型变量相互赋值时,只是简单地把等号左边变量所标示内存空间的存储状态设置成与等号右边变量的相同。如shorti=-1;unsignedshortui;当有赋值语句ui=i;时,变量ui所标示内存空间的存储状态为16个1,变量ui的值为65535。如:unsignedshortuj=65535,shortj;,当有赋值语句j=uj;时,变量j所标示内存空间的存储状态同样为16个1,变量j的值为-1。编码长度不同的整型相互赋值设整型变量a,b,有赋值语句a=b;。如果b的编码长度小于a,赋值时遵循的原则是使赋值后a的值与b的值保持一致。如何保持一致呢?具体地说,若b为有符号整型,则当b为正数时,赋值后a的低位状态与b的内存空间状态一致,其它位为0;当b为负数时,赋值后a的低位状态与b的内存空间状态一致,其它位为1(这样就可以保证a的值与b的值一致,可参考练习二第2.6题)。若b为无符号整型,则赋值后a的低位与b的内存空间状态一致,其它位为0。例3-2编码长度不同的整型相互赋值b的编码长度大于a如果b的编码长度大于a,则赋值后a的内存空间状态只与b的低位一致。b的高位状态丢失使a的值与b的值可能相差很大,因此这类赋值操作非常危险,编程时尽量不要出现。2.整型与浮点型之间相互赋值将浮点型数据赋值给整型变量时,仅把浮点数的整数部分赋给整型变量。将整型数据赋给浮点型变量时,先把整型数据转换成小数部分为0的浮点数,再正常赋值。例3-3整型和浮点型之间相互赋值return3.2.3复合赋值操作符赋值表达式i=i+1和i=i*(a+b)可以分别简写为i+=1,i*=a+b,其中操作符+=和操作符*=称为复合赋值操作符。从表3-1可知,C语言中大部分双目操作符都可以与赋值操作符组成复合赋值操作符,如由减法操作符组成的-=、由除法操作符组成的/=和由取余操作符组成的%=等。i=i*a+b不过类似i=i*a+b的表达式不能用复合赋值操作符简写。return3.3算术操作符和算术表达式C语言中的算术操作符有+,-,*,/,%,用算术操作符和括号将操作数连接起来组成的式子,称为算术表达式。C语言中算术操作符的优先级和结合性虽然和数学上的定义一致,但由于操作数的类型有整型(char,short,long)和浮点型(float,double)之分,当类型不同的操作数混合运算时,正确求出算术表达式的值也并非易事。类型转换的规则当两个操作数的类型不同时,求值之前会先进行类型转换以统一数据类型。类型转换的规则如下:1.float型自动转换成double型(为提高运算精度),char型自动转换成int(机器字长)。如果int型码长4个字节,则short型和unsignedshort型也会自动转换成int型。如:'A'+32floatf=2.3;f*3.2;类型转换的规则2.码长相同的整型变量混合运算时,有符号数会被认为是无符号数,结果也是无符号数。例3-41.有unsignedshortui=23;intj=-32;,那么ui+j的值大于0吗?分析:int型的码长为2个字节(TC中)时,ui,j的编码长度相同。码长相同的无符号数与有符号数混合运算时结果为无符号数,而无符号数不可能小于0,因此ui+j的值大于0。int型的码长为4个字节(vc6.0中)时,?unsignedshort型会根据规则1自动转换成int型,在运算器中计算的是int型的23和int型的-32的和,结果为-9(int型),因此,ui+j的值小于0。类型转换的规则例3-42.有unsignedshortui=23;shortj=-32;,那么ui+j的值大于0吗?分析:int型的码长为2个字节(TC中)时,变量ui和变量j不用转换成int型可以直接运算。码长相同的无符号数与有符号数混合运算时结果为无符号数,而无符号数不可能小于0且ui+j的值不可能为0,因此ui+j的值大于0。int型的码长为4个字节(vc6.0中)时,求值时变量ui和变量j需要转换成int型,因此ui+j结果为-9(int型),值小于0。类型转换的规则3.有unsignedlongui=23;shortj=-32;,那么ui+j的值大于0吗?分析:int型的码长为2个字节(TC中)时,因变量ui为长整型故变量j也需要转换成长整型。码长相同的无符号数与有符号数混合运算时结果为无符号数,而无符号数不可能小于0且ui+j的值不可能为0,因此ui+j的值大于0类型为unsignedlong。int型的码长为4个字节(vc6.0中)时,求值时变量j需要转换成int型,码长相同的无符号数与有符号数混合运算时结果为无符号数,而无符号数不可能小于0且ui+j的值不可能为0,因此ui+j的值大于0类型为unsignedlong。类型转换的规则3.整型与浮点型混合运算时,整型转换成double型,运算结果也是double型。floatf=2.3;f+3;类型转换的方法表达式求值时进行类型转换的方法与不匹配类型互相赋值时处理方法相同,但是此时会产生新的临时变量参加表达式求值,原变量本身的类型和值不会改变。inti=2;3.0/i的值为:,类型为:例3-5计算下面算术表达式的值20+'a'+5/2+12.6/3分析:计算时先算优先级高的操作符,即两个除法操作符,计算完除法后,原表达式变为连加运算,加法运算符的结合性为左结合,因此从左自右进行连加运算。例3-5计算下面算术表达式的值20+'a'+5/2+12.6/3先算子表达式5/2,操作数类型相同,计算结果为2,int型。再算子表达式12.6/3,操作数类型不同,3需转换成double型3.0,计算结果为4.2,double型。接着算子表达式20+'a',操作数类型相同('a'自动转换成int型97),计算结果为117,int型。再算子表达式117+2,操作数类型类型相同,计算结果是119,int型。最后算子
本文标题:第3章 操作符与表达式
链接地址:https://www.777doc.com/doc-3149909 .html