收藏 分销(赏)

第二章数据类型、运算符和表达式.ppt

上传人:xrp****65 文档编号:13183932 上传时间:2026-01-31 格式:PPT 页数:90 大小:629.50KB 下载积分:10 金币
下载 相关 举报
第二章数据类型、运算符和表达式.ppt_第1页
第1页 / 共90页
第二章数据类型、运算符和表达式.ppt_第2页
第2页 / 共90页


点击查看更多>>
资源描述
华中科技大学信息学院,C,语言程序设计,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,第,2,章 数据类型、运算符和表达式,2.1,数据类型,2.2,常量和变量,2.3,运算符和表达式,2.4,位运算,2.5,运算符的优先级,2.6,格式化输入输出函数的进一步讨论,2.7,常见问题分析,2.1,数据类型,在,C,语言中,数据类型可分为,:,2.2,常量和变量,2.2.1,常量(,文字量,),1.,整型常量,:整型常量就是整常数。,(1),十进制整型常量,:例如,56,、,-100,、,2004,;,(2),八进制整常量,:必须以,0,开头,数码取值为,0,7,。,如:,017(15),10,、,0101(65),10,、,0177777(65535),10,;,(3),十六进制整常量,:前缀为,0X,或,0 x,,其数码取值为,0,9,,,A,F,或,a,f,。如:,0X2A(42),10,、,0 xA0(160),10,、,0XFFFF(65535),10,;,(4),整型常量的后缀(,L/l,、,H/h,),:,如果使用的数超过了整型数的范围,就必须用长整型数来表示。长整型数是用后缀“,L”,或“,l”,来表示的。如:,158L(,十进制为,158),012L(,十进制为,10),2.,浮点型常量,:也称为实型,它有二种形式:,十进制小数形式,指数形式,(,1,)十进制小数形式:由数字,0,9,和小数点组成,(,注意必须有小数点,),如:,0.0,、,5.0,、,3.14,、,.,0,、,0,.,(,2,)指数形式:,一般形式为:,整数部分,.,小数部分,(,e,E)n,后缀,符号,表示该组成部分为可选项,但必须遵守浮点数的下列组成规则:,一个浮点数可以无整数部分或小数部分,但不能二者全无;,一个浮点数可以无小数点或指数部分,但不能二者全无;,如:,.234e+12,25E5,1.23,+1.23e-4f,3.,字符型常量,:,用单引号括起来的一个字符,单引号中的内容,不能是单引号,双引号和反斜线。字符常量的值就是该字符,的,ASCII,码值。如:,a,、,C,、,=,、,+,、,?,转义字符,是一种特殊的字符常量。转义字符以反斜线“,”,开头,后跟一个或几个字符。转义字符具有特定的含义,不,同于字符原有的意义。,广义地讲,,C,语言,ASCII,字符集中的,任何一个字符均可用转义字符来表示,,,如:,101,表示字母,A,,,102,表示字母,B,。,常用的转义字符如下表所示:,转义字符,转义字符的意义,ASCII,代码,n,回车换行,10,t,横向跳到下一制表位置,9,b,退格,8,r,回车,13,f,走纸换页,12,反斜线符(,),92,单引号符(),39,双引号符(“),34,a,鸣铃,7,0,空字符(,=NULL,),ddd,1,3,位八进制数所代表的字符,xhh,1,2,位十六进制数所代表的字符,例,2.1,转义字符的使用,#include,void main(),char,ch,;,ch,=36;,/,将,ASCII,码为,36,即,30,的字符赋给,ch,printf(“ch,is%,cn”,ch,);,/,输出字符,,ASCII,码为,36,对应的字符为,$,输出结果为,:,ch,is$,4.,字符串常量,:,由一对双引号括起的字符序列。,字符串常量和字符常量是不同的量。它们之间主要有以下区别:,字符常量由单引号括起来,字符串常量由双引号括起来。,(2),字符常量只能是单个字符,字符串常量则可以含一个或多个字符。,(3),可以把一个字符常量赋予一个字符变量,但不能把一个字符串常量赋予一个字符变量。,(4),字符常量占一个字节的内存空间。字符串常量占的内存字节数等于字符串中字符数加,1,。增加的一个字节中存放字符,0(ASCII,码为,0),。这是字符串结束的标志。,5.,符号常量,:,常量除了用上述直接表示方法外,还可以采用符号表示,,称为符号常量,(,又称,宏,),使用符号常量的好处是:,含义清楚;能做到“一改全改”,。,符号常量在使用之前必须先定义,其一般形式为:,#define,标识符 常量,#define,是预处理命令(预处理命令都以,“,#”,开头),,称为宏定义命令。其功能是把该标识符定义为其后的常量值。如:,#define PI 3.14/C,的常量形式,无类型,C,的常量:,const double pi,3.14,;,/,有类型,例,2.2,采用宏定义的方式定义符号常量,#include,#define PI 3.14159,/,定义符号常量,PI,值为,3.14159,void main(),double radius=10.0;,double perimeter;,double area;,perimeter=2*PI*radius;,/,使用符号常量,area=PI*radius*,radius,;,/,使用符号常量,printf(radius,=%,lf,perimeter,=%,lf,area,=%,6.2,lfn,radius,perimeter,area,);,输出结果为,:,radius=10.000000,perimeter=62.831800,area=314.16,2.2.2,变量,在程序执行过程中,值可以改变的量称为变量。,变量数据类型的说明格式为:,数据类型 变量名表,=,初值,;,例:,int,a,b,c,;float f,g=3.0;,变量的命名必须遵循以下几条规则,:,必须是以英文字母或下划线开头的,由字母、数字和下划线组成的字符序列。,(2),不能与,C,语言的关键字,(,保留字,),重名,,(3),变量名的长度不受限制。但一般不超过,32,个字符,C,语言对变量名的大小写敏感。,另外,在,C,语言的长期使用过程中还形成了一些约定俗成的规则:,尽量使变量名能够表达出该变量的含义。,用户最好不要用下划线来作为变量名的开头。,习惯上符号常量的标识符用大写字母,变量标识符可大小写结合。,1,整型变量,在,C,语言中,整型用,int,表示。根据整型数在存储器中占用的字节,数,又可以用,long,和,short,来修饰,int,,表示长整型和短整型。根据其是,否带有符号,又可以用,signed,和,unsigned,来修饰,int,short,int,long,int,表示带,符号整型和无符号整型。,2.,浮点型变量,float,单精度型,double,双精度型,long double,长双精度型,3.,字符变量,字符变量用来存储字符常量,即单个字符。字符变量的类型说明符是,char,,在,C,语言中,字符型也可以分为,signed,和,unsigned,,它们的区别在于取,值范围的不同。可以把字符变量看成是整型量。,C,语言允许对整型变量赋以,字符值,也允许对字符变量赋以整型值。在输出时,允许把字符变量按整型,量输出,也允许把整型量按字符量输出。,例,2.3,字符变量与整型量之间的联系,#include,void main(),char,ch,=a;,int i=,ch,;,printf,(%c ASCII is%,dn,ch,ch,);,/,将字符量按整型量处理,printf,(%c ASCII is%,dn,i,i,);,/,将整型量按字符量处理,输出结果为:,a ASCII is 97,a ASCII is 97,周一,9-10,2.3,运算符和表达式,“运算符”就是记述各种不同运算过程的符号。,按运算对象的数目,:,单目运算符、双目运算符和三目运算符;,按照其功能,:,算术运算符、赋值运算符、关系运算符、,逻辑运算符、位运算符、自增自减运算符、,条件运算符、逗号运算符等等。,2.3.1,表达式,2.3.2,算术运算符与算术表达式,2.3.3,关系运算符与关系表达式,2.3.4,逻辑运算符与逻辑表达式,2.3.5,自增和自减运算,2.3.6,赋值运算符与赋值表达式,2.3.7,条件运算符与条件表达式,2.3.8,逗号运算符与逗号表达式,2.3.1,表达式,一般来讲,表达式是由运算符和运算量所组成,的符合,C,的语法的算式。运算量可以是变量、常,量、有返回值的函数等。从本质上讲,表达式是对,运算规则的描述并按一定规则执行运算的算式。,C,语言中的表达式根据运算符的种类可以分为:,算术表达式、关系表达式、逻辑表达式、,赋值表达式、条件表达式、逗号表达式,混合表达式,等。,2.3.2,算术运算符与算术表达式,C,语言中,算术运算符有,5,个,它们的具体含义见下表:,运算符,使用形式,含义,+,单目或双目运算符,单目运算表示,正号,,双目运算表示,加法,运算,-,单目或双目运算符,单目运算表示,求负,,双目运算表示,减法,运算,*,双目运算符,乘法运算,/,双目运算符,除法运算,%,双目运算符,取模运算(求余数),关于算术运算符的使用有以下规则:,+,、,-,、*、,/,运算符的运算量可为任何整型或浮点型的常,量、变量、有返回值的函数以及表达式。,(2),正如在数学中除法运算的除数不能为,0,一样,在,x/y,中,表,达式,y,的取值也不能为,0,,否则将出现错误。,(3)%,运算符要求运算量必须是整型,且,%,后面的运算量不,能为,0,。,例如,:,3%5,结果为,3,-17%5,结果为,-2,20%10,结果为,0,(4),当双目运算符的两个运算量的类型相同时,它们的运算,结果的类型与运算量类型相同。,例如,:,17.5+2.5,结果为浮点型,20.0,16/7,结果为整型,2,,小数部分被省去,(5),当双目运算符的两个运算量的类型不同时,运算前遵循,类型的一般转换规则将运算量自动转换成相同的类型,运算,结果的类型与转换后的运算量的类型相同,(,类型的一般转换规则将在本章的后面介绍,),。,例如,:15.5+5,操作数,15.5,的类型为浮点型,运算前将整型数,5,转换成浮点型,数,5.0,,然后进行运算,结果为浮点型数,20.5,例如:,16/5.0,结果为浮点型,3.2,例,2.4,五种算术运算示例,#include,void main(),int x,y;,float x1,y1;,x=15;,y=6;,x1=15.0;,y1=6.0;,printf(x,=%d,y=%,dn,x,y);,printf(x,+y=%,dn,x+y);,printf(x,y=%,dn,x-y);,printf(x,*y=%,dn,x*y);,printf(x,/y=%d.%,dn,x/y,x%y);,printf(x1/y1=%f n,x1/y1);,运行结果为:,x=15,y=6,x+y=21,x y=9,x*y=90,x/y=2.3,x1/y1=2.500000,【,说明,】,:在数学中恒等的表达式,在,C,语言表达式中不一定恒等,如:,6/4*56*5/4,。,建议:,在“,/”,运算符两边采用,float/double,数据,(,精确除,),下面的表达式隐含了危险,因为被,0,除:,18/,(,3/6,),18/,(,(double)3/6,),或者:“,/”,两边的整数有一个在数尾加小数点,如:,18/(3./6),在,C,语言中,字符型、整型和浮点型数据可以,在同一表达式中混合使用,,C,语言编译系统会按照,一定的准则自动进行类型转换。当出现下列三种情,况时发生自动类型转换:,当双目运算符的两个运算量结果的类型不相同,且进行算术运算时;,(2),当一个值赋予一个不同类型的变量时;,(3),函数调用,实参与形参类型不同时。,在本节中仅介绍前两种转换,,函数调用转换将在本,书的后面部分介绍到。,1.,算术运算时的自动类型转换,它的基本规则可描述为:双目运算符的两个运,算量中,值域较窄的类型向值域较宽的类型转换。,“值域”就是类型所能表示的值的最大范围。算术转,换遵循的转换方向如下图所示,:,同时要注意几点,:,表达式中的有符号和无符号字符以及短整型一律被转换为整型,如果,int,类型能表示原来类型的值,则转换成,int,类型,否则转换成,unsigned,类型。,(2),当算术运算中出现,float,类型时,首先将,float,转成,double,类型。,例如:,float f=3.6;,int n=6;,long k=21;,double,ss,=f *n +k /2;,double,double,long,double,double,2.,赋值运算时的自动类型转换,赋值转换将右值表达式结果的类型转成左值表达式,的数据类型。赋值转换具有强制性,(隐式),,它不,受算术转换规则的约束,转换结果的类型完全由左,值表达式的类型决定。,例如:,int,i,j,;,float m,;,i=m*j,;,周一,12,类型转换过程为:赋值运算符右,侧的表达式的值为,float/double,类型,经过赋值转换变成,int,类型,所以赋值表达式的值为,int,类型。,3.,强制类型转换,(显式),强制类型转换是靠,强制类型转换运算符,来,实现数据类型转换的,因此强制类型转换也,叫做显式转换。,强制类型转换表达式形式为:,(,类型名,),(表达式),作用是将表达式结果类型转换成“类型名”所指定的类型。,例如,:,float,m,n,(,int)m,将变量,m,的,值的类型,转换成,int,类型,表达式的值为,int,类型。,(,int)m+n,表达式的结果为,double,类型,需要注意的是,,无论是自动类型转换还是强制类型转换,都只是将变量或常量的值的类型进行暂时的转换,用于参与运算和操作,,而变量和常量本身的类型和数值并没有改变,。,2.3.3,关系运算符与关系表达式,C,语言中的关系运算符包括:,(,小于,),=,(,大于或等于,),(,大于,),!=,(,不等于,),关系运算符都是双目运算符,它用来比较两个运算量之间的关系。用关系运算符将前、后两个运算量连接起来的式子称为“关系表达式”,这,两个运算量可以是任意表达式,。当关系表达式成立时,表达式的结果为整数,1,,否则为整数,0,。,例,2.5,关系表达式的值,#include,void main(),char ch1,ch2;,ch1=a;,ch2=b;,printf(%c,=%c-%dn,ch1,ch2,ch1=ch2);,printf(%c,%c-%dn,ch1,ch2,ch1%c-%dn,ch1,ch2,ch1 ch2);,printf(%c,=%c-%dn,ch1,ch2,ch1=%c-%dn,ch1,ch2,ch1=ch2);,printf(%c,!=%c-%dn,ch1,ch2,ch1!=ch2);,运行结果为:,a=b-0,a b-0,a=b-0,a !=b-1,优先级,、,、,=,=,、,!=,关系运算符与算术运算符和赋值运算符比较优先级,算术运算符,关系运算符,高,低,高,低,关系运算符的结合性,左结合性,【,例,】,a=3,,,b=2,,,c=1,;,求:,a b c,的值,第一步:,3,2,关系成立,结果为,1,;第二步:,11,关系不成立,结果为,0,。,C,语言中的,逻辑运算符,包括:,&,(,逻辑与,),|,(,逻辑或,),!,(,逻辑非,),其中,逻辑与和逻辑或是双目运算符,逻辑,非是单目运算符。逻辑运算符及运算量按一,定规则所构成的表达式称为,逻辑表达式,。,2.3.4,逻辑运算符与逻辑表达式,C,的语法将参与逻辑运算的两个运算分量解释为逻辑量,,但通常逻辑运算符两边的运算分量可以是一般表达式。因此,,就需,先将这些表达式的结果数值转换为逻辑值,“,真,”,或,“,假,”,,再来进行逻辑比较,。,逻辑运算分量对应的表达式转换为逻辑量的规则:,若运算分量的值为,非,0,的任意数,,则为逻辑,“,真,”,;,若运算分量的值为,0,,则为逻辑,“,假,”,;,逻辑运算符的运算规则见下表,:,表达式,X,表达式,Y,!X,!Y,X&Y,X|Y,非,0,非,0,0,0,1,1,非,0,0,0,1,0,1,非,0,非,0,1,0,1,1,0,0,1,1,1,1,例,2.6,逻辑运算符,&,的使用,#include,void main(),int a,b,c,max;,a=10;,b=20;,max=b;,c=(a=1 and x=1&x=h,,,直接写成,1=x=h,,结果如何?,对,C,来说是符合语法的,,因为它是一个关系表达式,按左结合求解,1=x,,若,x,取值满足条件则表达式结果为,1,,然后,1h,时前面的关系表达式结果也为“真”。显然,这种书写方式不能起到对应的条件限制作用。,例:判断某个字符,C,是否为数字字符,正确的写法:,if(c=0&c=9),若写成:,if(0=c=9),则当,C,为,ASCII,码大于,57,的其它字符(如,a,、,A,、,),都可以使表达式为,“,真,”,。,【,经典示例,】,d!=0&n/d 0,(,假设,初始值:,d=0,),由于,d!=0,关系不成立,逻辑量为,“,假,”,,因为逻辑,“,与,”,运算等效于乘法,即只要两个运算分量中有一个为逻辑,“,假,”,,则整个逻辑,“,与,”,运算就为,“,假,”,。,故而,本例中,n/d0,将不被运算!从而避免被,0,除,增加程序的健壮性!,逻辑运算符的优化算法,编译程序,在处理含有,&,和,|,的表达式时,往往采用,优化算法,,有的书上称之为,“,短路器,”,,即自左而右一旦能确定结果的真假,则求值的计算立即结束,也就是说,并不是表达式中的所有逻辑运算符都被执行,或者说,不是所有的逻辑运算分量都被计算。,void main(),int,a,b,c;,a =b =c =1;,printf,(“(1)%d n”,+a|+b,printf,(“(2)%d t%d t%d n”,a,b,c);,printf,(“(3)%d n”,+a,printf,(“(4)%d t%d t%d n”,a,b,c);,printf,(“(5)%d n”,a|b|c );,printf,(“(6)%d t%d t%d n”,a,b,c);,printf,(“(7)%d n”,a,printf,(“(8)%d t%d t%d n”,a,b,c);,printf,(“(9)%d n”,a|b,printf,(“(10)%d t%d t%d n”,a,b,c);,结果输出:,1,211,(,),(,),(,),1,321,1,221,0,110,0,000,自增、自减运算符分别为,:,+,(,自增,),-,(,自减,),+,和,-,分别都有两种不同的形式:,前置式:,+i,、,-i,后置式:,i+,、,i-,2.3.5,自增和自减运算,前置运算是变量先自增,1,或自减,1,后,再参与其他的运算,即,先变后用;引用的是新值,例如,:x=0;y=-x+x;,结果为,x=-1,y=-2,(2),后置运算是该变量先以原来的值参加其它运算,,然后再自增,1,或自减,1,即,先用后变;引用的是旧值,例如:,x=10;y=x+x;,结果为,x=11,y=20,;,(3),自增自减运算符只能作用于变量,不能用于常量,和表达式以及函数调用,。,例,2.7,自增自减运算符的运算,#include,void main(),int,x,y,;,x=0;,y=10;,/*,变量,x,先输出值,再自增,变量,y,先自增,再输出值 *,/,printf(x,=%d,y=%,dn,x+,-y);,printf(x,=%d,y=%,dn,x,y);,运行结果为:,x=0,y=9,x=1,y=9,1.,基本赋值运算“”,它的一般表达式形式为:,左值表达式,=,右值表达式,赋值表达式的值,等于表达式左值变量的值,例如,:,int,i,j,char m,n,float,x,y,double z,j=i,i=m,z=x*i,2.3.6,赋值运算符与赋值表达式,i=m n,m n,的结果为整型,无需转换,直接将值赋给,i,i=j=10,(考虑结合性),相当于,i=(j=10),先将,10,赋给,j,而括号中的赋值表达式(,j=10,)的值就是赋值后的,j,的值,再将其赋给,i,(考虑类型转换),(,考虑优先级,),2.,复合赋值运算,在赋值运算符“,=”,前加上其他运算符,便构成了,复合赋值运算符。,C,语言中的复合赋值运算符共有,10,种,:,+=,、,-=,、*,=,、,/=,、,%=,、,&=,、,|=,、,=,、,=,复合赋值表达式的形式为:,左值表达式,op=,右值表达式,例如:,i+=j,等价于,i=i+j,x*=y-5,等价于,x=x*(y-5),m=2,等价于,m=m b)?a,:,b;,将,a,b,中最大的数赋值给变量,max,min=(a=?c,:,?);,printf,(“%c”,c=?c,:,?);,c=a b,?,a,:,b*b;c=(a b),?,a,:,(b*b);,(,),优先级:,关系运算符,高逻辑运算符?:条件运算符赋值运算符低,结合性,右结合性,a b,?,a,:,c d,?,c,:,d(a b),?,a,:,(c d),?,c,:,d),若:,a=1,b=2,c=3,d=4,,,则表达式值,=4,。,表达式,2,和表达式,3,可以不同类型,此时条件表达式的值的类型为二者中较高的类型,如:,xy?1:1.5,,若,xy,关系成立,则表达式结果为,1.0(double,类型,),。,例,2.8,条件运算符的使用,#include,void main(),int,a,b,c,;,a=10;,b=-5;,c=b 0?,a+b,:a-b;,/*,当,b0,时,,c,的值等于,a+b,;当,b0,时,,c,的值等于,a-b */,printf(a,=%,d,b,=%,d,a,+|b|=%,dn,a,b,c,);,运行结果为:,a=10,b=-5,a+|b|=15,附:在,C+,中有下面一条语法规则:,在一个条件运算符的表达式中,如果后面两个表达式的值类型相同,而且均可以作为左值,则该条件运算符的值是一个左值表达式。如:,int,x=5;long a,b;(x?a:b)=1;/,注:若,x,为真,则,a,变量的值将被赋值为,1,(x?x:b)=2;/,x,和,b,不是相同类型,条件运算符将作自动转换,经过转换类型的表达式不能再作为左值。,(,x?a:6.6)=3;/,6.6,不是左值,第一表达式可以为非左值的表达式,如:,(x=0?a:b)=8;,逗号运算符构成逗号表达式,结构为:,表达式,1,表达式,2,表达式,3,表达式,n,运算过程为:先求表达式,1,的值,然后再求表达式,2,的值,依次计算下去,最后表达式,n,的值也就是该逗号表达式的值。,例如,:,int,b,a,=10;/,分隔符,b=a+,a%3,/,逗号运算符,(顺序计算运算符),先求表达式,1,的值,结果为,10,,同时对,a,计算后缀,+,,此时,a,的值为,11,;,然后求表达式,2,(,a%3,),的值,由于在计算表达式,2,之前,变量,a,的自增,运算已经完成,因而表达式,2,的值为,2,。这样整个逗号表达式的值为,2,。,2.3.8,逗号运算符与逗号表达式,sizeof,运算符,1,、格式:,sizeof,(,类型名,),2,、,含义:,求某种数据类型的变量存储空间的长度(以字节为单位)。该运算符是在,编译时执行,,而不是在程序执行时进行运算。,3,、应用,类型名可以是,C,语言的基本数据类型或者构造数据类型(如:数组、指针、结构等),,如:,sizeof,(,struct,student),int,array7;,sizeof,(array),sizeof,(,int,);,sizeof,(,int,*),2.4,位运算,2.4.1,按位与运算符“,&”,2.4.2,按位或运算符“,|”,2.4.3,按位异或运算符“,”,2.4.4,二进制左移运算符“,”,2.4.6,按位取反运算符“,”,2.4.1,按位与运算符“,&”,按位与,运算是对两个操作数逐位求,与,当它们都为,1,时,结果为,1,否则为,0,。与运算符的定义如下表所示,:,位,1,位,2,位,1&,位,2,0,0,0,0,1,0,1,0,0,1,1,1,例如,:a=0 x96,b=0 x80,则,a&b,的结果为,0 x80,运算过程为,:,按位,“与”,的作用:,(1),将某些位清零,在实际应用中通常遇到这样一种情况,根据特定的需要将某些数,字的某些二进制位清零,如要将某端口控制的某些发光二极管熄灭,实,际上是将某个控制数的对应位清零,如,a=0 x55,要将,a,的低四位清零,那,就要将,a,与一个数进行按位与运算,这个数的低四位为零其它位为,1,。,运算过程如下:,运算的结果是对象数据的低四位清,0,,其它不变。,(2),取数中的特定位,与上述操作相反,在实际操作中通常要求保持某些位的状,态,如,a=0 x55,要保持,a,的低四位,其它位清零,那就要将,a,与一个,数进行按位与运算,这个数的低四位为,1,其它位为,0,。,运算过程如下:,运算的结果是对象数据的低四位不变,其它清,0,2.4.2,按位或运算符“,|”,按位或,运算是对两个操作数逐位相,或,。当它们都是,0,的时候,结果为,0,否则为,1,。,下表为位逻辑或操作的“真值表”,位,1,位,2,位,1|,位,2,0,0,0,0,1,1,1,0,1,1,1,1,运算过程为,:,例如,:a=0 x36,b=0 x55,则,a|b,的结果为,0 x77,按位,“或”,的作用,(1),将数的某些位置,1,在实际应用中有时也遇到这样一种情况,根据特定的需要将,某些数字的某些二进制位置,1,,如要将某端口控制的某些发光二极,管点亮,实际上是将某个控制数的对应位置,1,,如,a=0 x55,要将,a,的,低四位置,1,,那就要将,a,与一个数进行按位或运算,这个数的低四,位为,1,其它位为,0,。,运算过程如下,:,运算的结果是对象数据的低四位置,1,其它不变,(2),把一串二进制数连接到另一串二进制数后,在实际应用中有时也需要将一串二进制数连接到另一串二进制数,后,如通讯中的,CRC,校验就是这样,对于这样的问题一般是这样处理,的:先在对象字符串的末尾加上,N,个零,,N,为要连接的二进制串的位,数,然后进行按位或操作,得到的结果即为所求。如,a=0 x55,要连接的数,据为,8,位二进制串,表示成十六进制为,0 xaa;,则首先将,a,的后面加,8,个,0,(2),;,变,成,0 x5500,然后与,0 xaa,按位或。,2.4.3,按位异或运算符“,”,按位,异或,运算是将两个操作数逐位相异或,当它们,一个为,1,一个为,0,时,其相异或的结果为,1,否则为,0,。,下表为,位逻辑异或操作的“真值表”,位,1,位,2,位,1,位,2,0,0,0,0,1,1,1,0,1,1,1,0,运算过程为,:,从所得的结果看,某位要保持不变就异或,0,,某位要取反就异或,1,。,2.4.4,二进制左移运算符“,”,二进制左移运算符把数据向左移动若干位,移出左边界的所有位都将丢失,右侧新增加的位为,0,。,例如:,int a=4,a”,二进制右移运算符把数据向右移动若干位,移出右边界的所有,位都将丢失,左侧的新位的补充遵循下面的规则:,【,例,】,变量,a,是无符号数,,a=8,其二进制表示为,00001000,右移,1,位且左侧新位补,0,后结果为,00000100,所以,a1,的结果为,4.,由例子可知,,向右移动一位相当于整除以一个,2,1,。,a4,的结果为,0,(1),对于无符号数,右移时左侧的新位一律补,0,称为“,逻辑右移,”,(2),对于有符号数,若符号位是,0,则左侧新位一律补,0,;若符号位是,1,则左侧新位一律补,1,称为“,算术右移,”又叫“,符号位扩展,”,【,例,】,变量,a,是有符号数,,a=,1,其二进制表示为:,111111111,右移,1,位且左侧新位补,1,后结果为,111111111,所以,a1,的结果为,1.,?,a2,的结果仍为,1,(,unsigned,),a1,的结果为,2147483647,或,32767,?,2.4.6,按位取反运算符“,”,按位取反运算符是将操作数进行逐位“取反”。,例如,:,变量,a=0 x6a,,二进制表示为,01101010,,,按位取反后为,10010101,,所以,a,的结果为,0 x95,。,2.5,运算符的优先级和结合性,C,语言将,44,个运算符分为,15,个优先级,,1,级最高,,2,级次之,以此类推,,15,级最低。优先级高的运算符先执行运算。运算符的结合性是指当一个运算对象两侧的运算符优先级相同时,进行运算处理的结合方向。结合方向分为:,左结合、右结合,。,2.7,运算符的优先级和结合性总结,一、优先级,优先级是用来确定运算的先后顺序,更具体地说,当某个运算分量的两边各有一个运算符时,此时该运算分量将参与哪边运算符的运算就要考虑运算符的优先级,如:,b+c*d,中的,c,将和,d,一起参与乘法运算,然后中间结果与,b,一起参与加法运算。,下面给出一些注释,它有助于掌握,C,的,运算符优先原则:,2.7,运算符的优先级和结合性总结,3、基本运算符优先级最高,在任何情况下,“,(),”,最优先。,1、所有运算符归纳为8层:基本运算符单目运算符算术运算符关系运算符逻辑运算符条件运算符赋值运算符逗号运算符;,2、位运算符优先级容易混淆,通常使用括号。除了移位运算符外,其它位运算符与逻辑运算符相邻,但比逻辑运算符优先级高,又比关系运算符低。,4、单目运算符比二目、三目运算符优先级高。,5、算术运算符优先级比关系运算符高。,6、关系运算符优先级比逻辑运算符高。,7、条件运算符优先级高于赋值运算符。,8、赋值运算符优先级低于除逗号运算符以外的所有运算符。,9、逗号运算符优先级最低。,基本运算符:,(),.,单目运算符:,!+-+(,类型,)*&,sizeof,(),算术运算符:*,/%+,移位运算符:,关系运算符:,=!=,位运算符 :,&|,逻辑运算符:,&|,条件运算符:,?:,赋值运算符:,=+=*=/=%=&=|=,高,低,二、结合性,当运算分量两边的运算符是同优先级时,这时就要考虑处于同优先级的两个运算符的结合性了,即运算分量将同哪一边的运算符结合。,C,语言中同优先级的运算符结合性不外乎两种:左结合性、右结合性。绝大部分运算符是左结合性,只有,赋值运算符,、,条件运算符,和,单目运算符,为右结合性。,如:,x=y=0;,z+=-x+y;z+=(-(x+)+y);,例如,:,int,x,y,z,z=y“+”,(加法运算符),“&”“=”,。所以表,达式的运算过程可以表示为:,z=(ym,,则,m,自动取,n,值,即保证,n,个字符正常输出。,例,字符串的输出。,void main(),printf(%3s,%7.2s,%.4s,%-5.3sn,HUST,HUST,HUST,HUST);,输出如下:,HUST,HU,HUST,HUS,其中第,3,个输出项,格式说明为“,%.4s”,,即只指定了,n,,没指定,m,,自动使,m=n=4,,故占,4,列。,(3),浮点数,%f,,不指定字段宽度,由系统自动指定,使整数部分全部如数输出,并输出,6,位小数。应当注意,并非全部数字都是有效数字。单精度实数的有效位数一般为,7,位。,%,m.nf,,指定输出的数据共占,m,列,其中有,n,位小数。如果数值长度小于,m,,则左端补空格。,%-,m.nf,,,与,%,m.nf,基本相同,只是使输出的数值向左端靠,右端补空格。,例,输出实数时指定小数位数。,#include,void main(),float x=357.987;,printf(%f,%10f,%10.2f,%.2f%-10.2fn,x,x,x,x,x);,输出结果如下:,357.987000,,,357.987000,,,357.99,,,357.99,,,357.99 ,表,2.11,scanf,格式字符,格式字符,说明,d,用来输入有符号的十进制整数,o,用来输入无符号的八进制整数,x,X,用来输入无符号的十六进制整数(大小写作用相同),c,用来输入单个字符,s,用来输入字符串,在输入时以空白字符开始,以一个空白字符结束。,f,用来输入实数,可以用小数形式或指数形式输入,表,2.12,scanf,的附加格式说明字符,字符,说明,l,用于输入长整型数据(可用,%,ld,%lo,%lx,)以及,double,型数据,(,可用,lf)longdouble(%Lf,),h,用于输入短整型数据(可用,%,hd,%ho,%hx,),域宽,指定输入数据所占宽度(列数),域宽应为正整数,*,表示本输入项在读入后不赋给相应变量,2.7,常见问题分析,1.,数据的溢出问题,数据有其固定的表示范围,因此当数据的值超出了其范围时,将出现溢出问题。,例,2.9,整型数溢出,#include,void main(),short,a,b,;,a=32767;,b=a+1;,printf(%d,%dn,a,b,);,在上面这段程序中,变量,a,的值为,32767,它在内存中的表示为,:,a:,0111 1111,1111,1111,当,a,加上,1,后,内存中的表示为,:,1000 0000,0000,0000,它的实际十进制值为,-32768,,与我们希望的,32768,的值不符,这就是因为溢出问题而产生的错误,在程序编写过程中需要注意避免。,2.,无符号整数与有符号整数的混合运算问题,例,2.10,无符号整型数与有符号整型数混合运算出错,#include,void main(),int x=1;,unsigned int y=2;,printf(x,-y=%d,(x-y)/2=%d,n,x,-y,(x-y)/2);,输出结果为:,x y=-1,(x-y)/2=32767,按照常理,我们认为,(1-2)/2,结果应该为,-0.5,,截去小数后,结果应为,0,,但事实上并非如此,而是得到结果,32767,。,分析如下,:,变量,x,,,y,的值分别为,1,和,2,它在内存中的表示为,:,x:0000 0000,0000,0001,y:0000 0000,0000,0010,执行,x y,操作后,根据,C,语言中的类型自动转换原则,计算,结果的类型应为符号整型数,其结果在内存中的存放形式,为:,x y:1111 1111,1111,1111,如果将,x y,的结果以有符号整型数形式输出,因,x-y,的最高,位为,1,,输出结果为,-1,。如果将,(x y)/2,其结果在内存中的存,放形式为:,(x y)/2:0111 1111,1111,1111,以有符号数的形式输出,正好为,32767,。而不是我们按常理,应得到的数字,0,。,3.,浮点型变量的舍入误差问题,例,2.11,实型数据的舍入误差,#include,void main(),float x,y;,x=1.0;,y=x/3*3;,printf(x,=%f,y=%f n,x,y);,输出结果为:,x=1.000000,y=0.999999,建议:如果在表达式中出现除法运算符“,/”,时,建议将“,/”,尽量,往后放。在一定程度上可以提高计算结果的精度。,4.,书写标识符时,忽略了大小写字母的区别,例,2.12,标识符大小写引起的问题,#include,void main(),int a=5;,printf(%d,A,);,编译程序把,a,和,A,认为是两个不同的变量名,而显示,出错信息。,C,认为大写字母和小写字母是两个不同,的字符。习惯上,符号常量名用大写,变量名用小,写表示,以增加可读性。,5.,忽略变量的类型,进行了不合法的运算,#include,void m
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 百科休闲 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服