您好,欢迎访问三七文档
§2.3运算符和表达式2.3.1表达式2.3.2算术运算符2.3.3赋值运算符2.3.4不同数据类型数据间的混合运算2.3.5关系运算符2.3.6逻辑运算符2.3.7增1/减1运算符2.3.8位逻辑运算符2.3.9其它运算符3.1表达式表达式的概念表达式是用运算符与圆括号将操作数连接起来所构成的式子。C语言的操作数包括常量、变量、函数值等。根据表达式进行运算,得到的数值即为表达式的解。表达式与简单语句在C语言中,在一个表达式的后面加上分号“;”就构成了简单语句。有意义的简单语句无意义的简单语句3.2算术运算符种类及运算+-*/%注意:两个整数相除,结果仍为整数,商向下取整。取模运算符%实际上是数学运算的求余数运算,其两个操作对象都必须是整数。减法运算符还可以用做单目运算符,是取负运算。其余操作符均为双目运算符。算术表达式及算术运算符的优先级算术表达式就是用算术运算符和圆括号将操作数连接起来的式子。算术表达式的解就是经过算术运算得到的表达式的值。算术运算符的优先级与数学基本相同,即先乘除,后加减。取模运算的优先级与乘除相同。函数和圆括号的优先级最高。注意:算术表达式应能正确的表达数学公式。例如:数学表达式是3+x2a相应的C语言表达式应该是什么呢?算术表达式的结果应该不超过其所能表示的数的范围。例如,最大的整型数是32767,那么,32767+3就不会是正确的结果。而32767L+3的结果是正确的,因为32767L是长整型数。算术运算符的结合性运算符的结合性是指如果一个操作数左边和右边的两个运算符的优先级相同,应该优先计算的操作符。例如:a+b-c操作数b左右的运算符+和-的优先级相同,那么,是先计算b-c,还是先计算a+b呢?C语言规定双目算术运算符的结合性是自左至右,也就是b先与左边a结合,再与右边c结合。所以是先计算a+b,然后用a+b的结果减c。双目运算符的结合性与数学运算并无不同。3.3赋值运算符普通赋值运算符赋值表达式的一般形式是:变量名=表达式赋值语句的一般形式是:变量名=表达式;赋值运算符的优先级小于算术运算符。赋值运算符的结合性是自右至左,以a=b=2为例复合赋值运算符把赋值运算符与算术、位逻辑、移位运算符放在一起,就构成复合赋值运算符。复合算术赋值运算符有5个+=、-=、*=、/=、%=。还有与移位和位逻辑结合的复合赋值运算符5个(=、=、&=、^=、|=)。复合赋值运算符的使用规则是:Xop=Y与X=XopY等价。3.4不同数据类型数据间的混合运算自动转换强制转换赋值表达式的类型转换自动转换所谓“自动转换”就是系统根据规则自动将两个不同数据类型的运算对象转换成同一种数据类型的过程。而且,对某些数据类型,即使是两个运算对象的数据类型完全相同,也要做转换,例如float。floatdouble高longunsignedchar、shortint低强制转换在C语言中,允许程序员根据自己的意愿将一种数据类型强制转换成另一种数据类型。强制转换的格式为:(数据类型名)操作对象注意,强制转换并不改变操作对象的数据类型和数值。例如,(int)f的确切含义是将f转换成为整型值参与运算,而f本身的数据类型和数值都没有任何改变。赋值表达式的类型转换当赋值运算符左边的变量与赋值运算符右边的表达式的数据类型相同时,不需要进行数据类型的转换。当赋值运算符左边的变量与赋值运算符右边的表达式的数据类型不相同时,系统负责将右边的数据类型转换成左边的数据类型。此时,会有两种情况产生,一种是转换以后会丢失数据,另一种是转换以后不会丢失数据。这与赋值号两边的表达式的数据类型所占的字节数及存储表示方式有关。(详细内容自学)例3.1#includestdio.hvoidmain(){intc;/*charc;*/c='B';printf(c=%c,c+'a'-'A');}运行结果:c=b例3.2#includestdio.hvoidmain(){charc;inti=0x3241;printf(i=%c\n,i);c=i;printf(c=%d\n,c);printf(i=%d\n,i);}运行结果i=Ac=65i=128653.5关系运算符所谓关系运算,实际上就是比较两个数值的大小。那么,比较两个数值的大小的运算符就是关系运算符。关系运算符有六个、=、、=、==、!=。由关系运算符连接起来的表达式就是关系表达式。关系表达式的解一般应为真或假,C语言用整数1表示真,整数0表示假。初学者经常会混淆关系运算符“==”和赋值运算符“=”,因此要注意区分这两个运算符。例3.3#includestdio.hvoidmain(){intx,y,z1,z2;x=2;y=2;z1=(x=y);z2=(x==y);printf(%d,%d\n,z1,z2);}六个关系运算符中的“!=”和“==”的优先级小于其余四个运算符。关系运算符的优先级小于算术运算符,大于赋值运算符。关系运算符的结合性均为自左至右。当多种运算符在一个表达式中同时使用时,要注意运算符的优先级,防止记错运算符优先级的最好方法是加圆括号。例3.4注意,不赞成按本例这样编写程序。#includestdio.hvoidmain(){intx,y,z,i,j;x=4,y=3,z=2;i=yz;j=xyz;printf(%2d,%2d,,i,j);printf(%2d,,zy==3);printf(%2d,,y+zx);printf(%2d\n,y+2=z+1);}运行结果为:1,0,0,0,13.6逻辑运算符如果将“与、或、非”运算应用于逻辑值(逻辑真和逻辑假)则称为逻辑运算。C语言中的逻辑运算符有三个:逻辑与&&、逻辑或||和逻辑非!其中逻辑与和逻辑或是双目运算符,而逻辑非是单目运算符。AB!A!BA&&BA||B逻辑真逻辑真逻辑假逻辑假逻辑真逻辑真逻辑真逻辑假逻辑假逻辑真逻辑假逻辑真逻辑假逻辑真逻辑真逻辑假逻辑假逻辑真逻辑假逻辑假逻辑真逻辑真逻辑假逻辑假逻辑运算的规则与二进制的位逻辑是相似的。逻辑运算的规则下表:C语言系统对任何非0值都认定为是逻辑真,而将0认定为逻辑假。如果一个表达式参与逻辑运算,只要这个表达式的解为非0,则系统就认为这个表达式的结果是逻辑真。但是要注意,系统逻辑运算的结果仍然只有两个:1(逻辑真)和0(逻辑假)。逻辑运算符经常与关系运算符一起使用。C语言表达式(x=10)&&(x=100)的数学含义是:10≤x≤100逻辑运算符的优先级!&&||高低!的优先级高于算术运算符(当然也高于关系运算符)和赋值运算符&&和||的优先级高于赋值运算符,但是低于算术运算符和关系运算符。!单目运算符,其结合性是自右至左;&&和||的结合性是自左至右。计算表达式78&&3||69-!0的值注意:在C语言中,如果逻辑运算符的左操作数已经能够确定表达式的解,则系统不再计算右操作数的值。x==1&&y==0若x此时不为1,在检测x==1以后,就不会再检测y==0。因为x==1的结果是逻辑假,逻辑假与任何数进行逻辑与操作结果都会是逻辑假。x==y||x=0若x==y成立,则表达式的值为真,不需要继续做x=0了。但是,若x==y不成立,由于x=0是个赋值表达式,表达式的结果很可能是错误的。假设该表达式计算以前,x值为1,y的值为0,x==y的计算结果是0,这时需要执行赋值x=0,表达式的结果仍然是0,而实际上这时的x和y的值均为0,又满足了x==y,这不是产生了矛盾吗?不要在一般的表达式中夹杂赋值运算3.7增1/减1运算符++和--。这两个运算符都是单目运算符,其功能分别是将变量自身的内容增1和减1。++i和--i是前缀表示法,i++和i--是后缀表示法。如果直接在++i和i++的后面加上分号构成C的执行语句,即++i;和i++;前缀与后缀并无区别(减1符号也一样)。但是,将它们用在表达式中则前缀与后缀是有区别的。前缀表示法是先将i值增/减1,再在表达式中使用;而后缀表示法是先在表达式中使用i的值,再将i值增/减1。例如:i=3;i=3;j=i++;j=++i;结果j的内容为3j的内容为4i的内容为4i的内容为4注意:增1/减1运算符的操作对象是一个变量2++、--2以及(x/y)++均为非法增1/减1运算符的优先级高于算术运算符,与单目运算符-(取负)、!(逻辑非)的优先级相同,结合方向自右至左。例如表达式-i++等价于-(i++)副作用:printf(“%d,%d”,i,i++);在不同的编译环境下结果有可能不同。尽量不要在一般的表达式中将增1/减1运算符与其它运算符混合使用。3.8位逻辑运算符~&|^按位取反左移右移按位与按位或按位异或操作数在实现位操作时按二进制进行运算,7一般应为无符号型整数。按位与&按位与的运算规则是:0&0=00&1=01&0=01&1=1例如:charw1,w2,w3;w1=10;w2=8;w3=w1&w2;w3的内容可以通过下式运算:0000101000001000(按位与&)00001000(结果)&运算经常用于把特定位清零(屏蔽)。例如,a的值为11011010,b的值为11110000,a&b11011010&1111000011010000相当于把a的低4位屏蔽,高4位不变。按位或|按位或的运算规则是:0|0=00|1=11|0=11|1=1例如:charw1,w2,w3;w1=10;w2=8;w3=w1|w2;w3的内容可以通过下式运算:0000101000001000(按位或|)00001010(结果)按位异或^按位或的运算规则是:0^0=00^1=11^0=11^1=0例如:charw1,w2,w3;w1=10;w2=8;w3=w1^w2;w3的内容可以通过下式运算:0000101000001000(按位异或^)00000010(结果)按位取反~按位取反的规则是:~0=1~1=0注意:对于位逻辑反来说,~0x7在16位机上的表示是1111111111111000即0xfff8,但在32位机上的表示是0xfffffff8,所以通常用~0x7来表示7的逻辑非,而不用0xfff8或oxfffffff8。移位运算符左移右移双目运算符,运算符右边的表达式表示移位的位数。x=x2表示把x进行左移以后赋值给x,注意不能只用x2左移可以扩大原数的倍数,左移1位扩大2倍,左移2位扩大4倍,…。右移可以缩小原数的倍数。右移时,若符号位为0,则右边填零。若符号位为1,根据机器不同分为算术移位(填充1)逻辑移位(填充0)。3.9其它运算符逗号运算符表达式1,表达式2逗号表达式的求值过程是:先求解表达式1,再求解表达式2,并将表达式2的解作为逗号表达式的解。例如5,6的值是6z=(y=3,x*y)与z=x*(y=3)是等价的逗号运算符一般用于循环for语句,不提倡使用在其它的表达式中。求字节数运算符sizeof是一个比较特殊的单目运算符,也是一个非常有用的运算符,经常用于动态分配空间。其语法格式为:sizeof(表达式)表达式可以是变量名、常量、以及数据类型名。它的功能是:求表达式中变量名所代表的存储单元所占的字节数;或是求表达式中常量的存储单元所占的字节数;或是求表达式中的数据类型表示的数据在内存单元中所占的字节数。sizeof(int)的结果是2,sizeof运算符比较灵活,同样是求整型int数据所占的字节数,可以使用三种办法:(1)求sizeof(int)(2)求sizeof(10)(3)使用inta;求sizeof(a)例3.5求各种有数据类型在内存中所占的位(bit)数。#includestdio.hvoidmain(c){printf(char=%dbit\n,8*sizeof(char));printf(shortint=%dbit\n,8*sizeof(shortint));printf(int=%dbit\n,8*sizeof(10))
本文标题:运算符和表达式
链接地址:https://www.777doc.com/doc-4597171 .html