资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,基本数据类型及运算符,C,语言标识符和关键字,C,语言的基本数据类型,常量的定义和使用方法,变量的定义和使用方法,表达式及各种运算符的使用,各种数据类型之间的相互转换,位运算符的使用,基本数据类型及运算符 C语言标识符和关键字,1,C,语言标识符,计算机程序处理的对象是数据,编写程序也就是描述对数据的处理过程。在程序中通过名字建立定义与使用的关系。为了这种需要,每种程序语言都规定了在程序里如何描述名字,程序语言的名字通常被称为“标识符”。,直接地说,标识符就是一个名字,像后面介绍的符号常量名、变量名、函数名、标号、数组名、文件名、结构类型名和其他各种用户定义的对象名都是标识符,它们的命名必须满足标识符的构成规则。,C,语言中允许用作标识符的字符有:,26,个英文字母,包括大小写(共,52,个),数字,0,,,l,,,,,9,下划线,标识符的构成规则为:,必须由字母(,a,z,,,A,Z,)或下划线(,_,)开头,后面可以跟随任意的字母、数字或下划线,C语言标识符 计算机程序处理的对象是数据,编写程序也,2,在,C,语言中,大小写字母有不同的含义,例如:,num,,,Num,,,NUM,为三个不同的标识符。 在构造标识符时,应注意做到“见名知意”,即选择有含义的英文单词(或汉语拼音)作标识符,以增加程序的可读性。如表示年可以用,year,,表示长度可用,length,,表示和可以用,sum,等。,C,语言中有一些标识符被称为关键字,在系统中具有特殊用途,不能作为一般标识符使用,如用于整型变量定义的,int,关键字,就不能再用作变量名。 有些标识符虽不是关键字,但,C,语言总是以固定的形式用于专门的地方,因此,用户也不要把它们当做一般标识符使用,以免造成混乱。这些常用的标识符有:,define,,,include,,,ifdef,,,ifndef,,,endif,,,elif,。,在C语言中,大小写字母有不同的含义,例如:num,Nu,3,例如,以下均是合法的标识符:,sum, a1, i, j5k3, sum_avg,以下均是不合法的标识符:,5i/*,错在以数字开头*,/u.s/*,错在出现“,.”*/good bay/*,错在中间有空格*,/,在所有合法,C,标识符中有一个特殊的小集合,其中的标识符称为,C,语言的“关键字”。作为关键字的每个标识符在,C,程序中都有语言里预先定义好的特殊意义;这些关键字不能用于任何其他目的,例如,不能用关键字为程序中自己的东西命名。,C,语言的关键字总共有,32,个,下面列出了全部关键字。,autobreakcasecharconst continuedefaultdodoubleelseenumexternfloatforgotoifintlongregisterreturnshortsignedsizeofstaticstructswitchtypedefunionunsignedvoidvolatilewhile,例如,以下均是合法的标识符:sum, a1, i, j5k,4,基本数据类型,C,语言有五种基本数据类型:字符、整型、单精度实型、双精度实型和空类型。尽管这几种类型数据的长度和范围随处理器的类型和,C,语言编译程序的实现而异,但以,bit,为例,整数与,CPU,字长相等,一个字符通常为一个字节,浮点值的确切格式则根据实现而定。对于多数,32,位的计算机,表,2-1,给出了五种数据的长度和范围。,类型,长度,(bit),范围,char(,字符型,),8,0255,int(,整型,),32,-2 147 483 6482 147 483 647,Float(,单精度型,),32,约精确到,6,位数,double(,双精度型,),64,约精确到,12,位数,void(,空值型,),0,无值,基本数据类型 C语言有五种基本数据类型:字符、整型,5,除,void,类型外,基本类型的前面可以有各种修饰符。修饰符用来改变基本类型的意义,以便更准确地适应各种情况的需求。修饰符如下:,signed,(有符号),unsigned,(无符号),long,(长型符),short,(短型符),short,只能修饰,int,,且,short int,可省略为,short,。,long,只能修饰,int,和,double,,修饰为,long int,时,可省略为,long,。,unsigned,和,signed,只能修饰,char,和,int,,一般情况下,,char,和,int,默认为,signed,型。实型数,float,和,double,总是有符号的,不能用,unsigned,修饰。,除void类型外,基本类型的前面可以有各种修饰符。修,6,常量,在程序运行中,其值不能被改变的量称之为常量。在基本数据类型中常量分为整型常量、实型常量、符号常量和字符型常量(含字符常量和字符串常量)。,常量 在程序运行中,其值不能被改变的量称之为常量。在基,7,1.,整型常量,整型常量即为整型常数,可用十进制、八进制和十六进制,3,种形式表示。,十进制整型常量由,0,至,9,的数字组成,没有前缀,不能以,0,开始,没有小数部分。如:,-123,,,0,,,456,等。,八进制整型常量以,0,为前缀,其后由,0,到,7,的数字组成,没有小数部分。如:,0123,(等于十进制数的,83,),,047,(等于十进制数的,39,)。,十六进制整型常量以,0x,或,0X,为前缀,其后由,0,到,9,的数字和,A,到,F,(大小写均可)的字母组成,没有小数部分。如:,0x123,(等于十进制数的,291,),,0X7A,(等于十进制数的,122,)。,整型常量中的长整型数据可用,L,(或小写字母,l,)作后缀来表示。如:,1234L,,,5678l,等。,整型常量中的无符号型数据可用,U,(或,u,)作后缀来表示。如:,1234U,,,5678u,等。如果一个整型常量的后缀是,U,(或,u,)和,L,(或,l,),或者是,L,和,U,,都表示为,unsigned long,类型的常量。如:,12345UL,,,67890ul,等。,1. 整型常量整型常量即为整型常数,可用十进制、八进制和十六,8,2.,实型(浮点型)常量,实型常量是由整数部分和小数部分组成的,它只有十进制的两种表示形式。,(,1,)定点数形式。它由数字和小数点组成。整数和小数部分可以省去一个,但不可两者都省,而且小数点不能省。如:,1.234,,,.123,,,123.,,,0.0,等。,(,2,)指数形式(或称科学表示法)。它是在定点数形式表示法后加,e,(或,E,)和数字来表示指数。指数部分可正可负,但须为整数,且应注意字母,e,(或,E,)之前必须有数字。如:,1.234e3,,,12.34e2,均合法地代表了,1.234103,;而,e3,,,1e2.3,,,.e3,,,e,均不合法。,另外,实型常量的后缀用,F,(或,f,)表示单精度型,而后缀用,L,(或,l,)表示长双精度型。如:,0.5e2f,表示单精度数,,3.6e5L,表示长双精度数。,2. 实型(浮点型)常量 实型常量是由整数部分和小数部分组,9,3.,符号常量,在程序中,可以定义一个符号来代表一个常量,这种相应的符号称为符号常量。例如,用,PI,代表圆周率,,即,3.1415926,。使用符号常量有许多好处。一是增加可读性。,在程序中出现具有一定意义的符号常量时,一看便能帮助读者了解其含义,即见名知义。如:,PI,代表,,,NAME,代表姓名等。二是提高了可维护性。,使用符号常量可使修改该常量变得更加方便。例如:在程序中直接使用某个常量,且该常量在程序中多处出现,若需修改该常量时,则需在每处出现该常量的地方都要加以修改,容易漏改或改错。如果使用符号常量,则只要修改其定义处即可,即一改全改。如:程序中出现某职工的姓名,且多处需要用此姓名,若用,NAME,符号常量代表姓名,一旦需要改变姓名,只要修改,NAME,的定义处即可。,3. 符号常量 在程序中,可以定义一个符号来代表一个常量,10,在,C,语言中,是用预编译处理命令,#define,来定义符号常量。如:,#define PI 3.1415926,#define NAME ,姚木兰,这种语句的格式是在,#define,后面跟一个标识符和一串字符,彼此之间用空格隔开。由于它不是,C,语句,故语句末不用分号(,;,)。当程序被编译时,它先被编译预处理。即预处理遇到,#define,时,就用标识符后的字符串替换程序中的所有该标识符。,习惯上,符号常量标识符用大写字母写出,以示与变量名区别。另外,符号常量标识符一旦定义,就不能在其他地方给该标识符再赋值。如:,PI=3.14,;是错误的。,在C语言中,是用预编译处理命令#define来定义符号常,11,字符型常量包含字符常量和字符串常量两类。,1.,字符常量,用一对单引号括起来的一个字符称为字符常量。例如:,a,、,A,、,3,、,?,等。它的实际含义是该字符在内存中的编码值,常用的是以,ASCII,编码来表示字符,如:,a,的编码值是,97,,,A,的编码值是,65,,,3,的编码值是,51,而不是数值,3,。,除了以上形式的字符常量外,,C,还允许使用一种特殊形式的字符常量,即以反斜杠符(,)开头,后跟字符的字符序列,称之为转义字符常量,用它来表示控制及不可见的字符(见表,2-2,),它同样表示的是该转义字符的,ASCII,码值,如,n,表示换行,其,ASCII,码值为,10,,,a,表示响铃,其,ASCII,码值为,7,等。,字符型常量包含字符常量和字符串常量两类。1. 字符,12,转义字符,意义,ASCII,码,a,响铃,0x07,n,换行,0x0a,t,横向跳格,0x09,v,竖向跳格,0x0b,b,退格(,Backspace,),0x08,r,回车,0x0d,f,换页(走纸),0x0c,0,空字符,0x00,反斜杠,0x5c,单引号,0x27,双引号,0x22,ddd,1,3,位八进制数所代表的字符,对应字符的,ASCII,转义字符,ddd,(为八进制数字,,07,之一)将字符的,ASCII,码值转换为对应的字符,它表示任一个字符。例如,,101,表示字符,A,,,012,表示转义字符,n,,,0,或,000,表示,ASCII,码为,0,的控制字符,即“空”字符。,转义字符意义ASCII码a响铃0x07n换行0x0at,13,2.,字符串常量,字符串常量是用一对双引号(,)括起来的零个或多个字符的序列,例如:,This is a string,5401349,10000.00, /*,引号中有一个空格,本书中用, ,表示一个空格*,/, /*,引号中什么也没有*,/,a/*,引号中有一个转义字符*,/,字符串常量在内存中存储时,系统自动在每个字符串常量的尾部加一个“字符串结束标志”字符,0,。因此,长度为,n,个字符的字符串常量,在内存中要占用,n+1,个字节的空间。,例如,,hello,在内存中的形式是:,104 101 108 108 111 0,为了能直观理解,以后表示字符串时,直接用字符本身表示。上例表示成:,hello0,2. 字符串常量字符串常量是用一对双引号()括起来的零个,14,分析,【,程序,2-2】,的运行结果。,/*,文件名,:chap02_2.cpp */,#include ,#include ,void main(),char *cstr=Chinaan101t;,printf(%dn,strlen(cstr);,printf(%sn,cstr);,程序运行结果:,10,China,A ,程序中,Chinaan101t,是一个符号常量,由字符指针,cstr,指向它(有关字符指针的内容在后续章节中介绍)。该符号常量似乎有,17,个字符,事实上,它只有,10,个字符,分别是,C,、,h,、,i,、,n,、,a,、,a,、,n,、,101,(对应字符,A,)、,t,和,,其中有,5,个转义字符。,分析【程序2-2】的运行结果。,15,字符常量,A,(,A,)与字符串常量,A,(,“A”,)的区别:,定界符不同。字符常量使用单引号,而字符串常量使用双引号。,长度不同。字符常量的长度固定为,1,,而字符串常量的长度可以是,0,,也可以是某个整数。,存储要求不同。字符常量存储的是字符的,ASCII,码值,而字符串常量除了要存储有效的字符外,还要存储一个结束标志,0,。,在,C,语言中,没有专门的字符串变量,字符串常量如果需要存储在变量中,要用字符数组来解决。详细内容将在后续章节中介绍。,字符常量A(A)与字符串常量A(“A”)的区别:,16,变量,在程序运行过程中,其值可以被改变的量称为变量。变量有两个要素:,变量名。每个变量都必须有一个名字,即变量名。变量命名应遵循标识符的命名规则。,变量值。在程序运行过程中,变量值存储在内存中;不同类型的变量,占用的内存单元(字节)数不同。在程序中,通过变量名来引用变量的值。,【,程序,2-3】,用来输出两个整数相加、相减和相乘的结果,代码如下。,/*,文件名,:chap02_3.cpp */,#include ,void main(),int x,y;,printf(,请输入两个整数,中间用空格隔开:,);,scanf(%d%d,printf(%d+%d=%dn,x,y,x+y);,printf(%d-%d=%dn,x,y,x-y);,printf(%d*10%d=%dn,x,y,x*y);,程序运行结果:,请输入两个整数,中间用空格隔开:,10 5,10+5=15,10-5=5,10*5=50,本程序中,,x,和,y,定义成整型变量,用于接受用户输入的值。,变量在程序运行过程中,其值可以被改变的量称为变量。变量有两个,17,变量的定义与初始化,在,C,语言中,要求对所有用到的变量必须先定义后使用。在定义变量的同时,进行赋初值的操作称为变量初始化。,变量定义的格式如下:,存储类型,数据类型 变量名,1,变量名,2;,例如:,int i,j,k;/*,定义,i,j,k,为整型变量*,/,long m,n;/*,定义,m,n,为长整型变量*,/,float a,b,c;/*,定义,a,b,c,为实型变量*,/,char ch1,ch2;/*,定义,ch1,ch2,为字符型变量*,/,变量初始化的一般格式如下:,存储类型,数据类型 变量名,1=,初值,1,变量名,2=,初值,2,;,例如:,float f1=1.23,f2,f3;,该语句定义了,f1,,,f2,和,f3,三个实型变量,同时初始化了变量,f1,。,变量的定义与初始化在C语言中,要求对所有用到的变量必须先定,18,表达式,以上小节介绍了数据的类型,以及常量、变量的概念和定义,那么如何处理这些数据呢?可以用代表一定运算功能的运算符将运算对象连接起来,并且以符合,C,的语法规则构成一个说明运算过程的式子(即表达式)来完成对数据的处理。其运算对象包括常量、变量、函数等。,表达式 以上小节介绍了数据的类型,以及常量、变量的,19,运算符简介,运算符是,C,语言里用于描述对数据进行运算的特殊符号。有了基本数据对象和运算符,就可以写出描述计算的表达式了。语言具有丰富而繁多的运算符,由它构成了各种表达式,这是其它任何程序设计语言所不可比的。其中有些运算符已超出了一般,运算符,的概念,这为编写程序带来了很大的方便性和灵活性,使程序简洁而高效。但另一方面,由于运算符丰富也会产生不便于记忆、应用难度较高等问题。初学者一定要注意运算符、表达式和运算过程的使用规则,这是编程的基本条件。,Turbo C + 3.0,的运算符非常丰富,主要分为三大类,:,算术运算符,关系运算符与逻辑运算符,按位运算符。除此之外,还有一些用于完成特殊任务的运算符。下面分别进行介绍。,运算符简介 运算符是C语言里用于描述对数据进行运算的,20,算术运算符和算术表达式,表,2-3,列出了,C,语言中允许的算术运算符。在,C,语言中,运算符“,+”,、“”、“*”和“,/”,的用法与大多数计算机语言的相同,几乎可用于所有,C,语言内定义的数据类型。当“,/”,被用于整数或字符时,结果取整。例如,在整数除法中,,10/3=3,。,一元减法的实际效果等于用,-1,乘单个操作数,即任何数值前放置减号将改变其符号。模运算符“,%”,在,C,语言中也同它在其它语言中的用法相同。切记,模运算取整数除法的余数,所以“,%”,不能用于,float,和,double,类型。,运算符,作用,运算符,作用,减法,也是一元减法,%,模运算,+,加法,-,自减(减,1,),*,乘法,+,自增(增,1,),/,除法,算术运算符和算术表达式 表2-3列出了C语言中允许的,21,下面的程序说明,%,用法的程序段。,int x,y;,x=10;,y=3;,printf(%d,x/y);/*,显示,3*/,printf(%d,x%y);/*,显示,1,,整数除法的余数*,/,x=1;,y=2;,printf(%d,%d,x/y,x%y);/*,显示,0,1*/,最后一行打印一个,0,和一个,1,,因为,1/2,整除时为,0,,余数为,1,,故,1%2,取余数,1,。,下面的程序说明%用法的程序段。,22,赋值运算符和赋值表达式,赋值运算构成了语言最基本、最常用的赋值语句,同时语言还允许赋值运算符,=,与,10,种运算符联合使用,形成组合赋值运算,使得程序简明而精练。,1.,赋值运算符,赋值运算符用,=,表示,其功能是计算赋值运算符,=,右边表达式的值,并将计算结果赋给,左边的变量。例如:,n=12.3;/*,直接将实型数,12.3,赋给变量,n*/,c=a*b;/*,将,a,和,b,进行乘法运算,所得到的结果赋给变量,c*/,注意:赋值运算符,=,与数学中的等号完全不同,数学中的等号表示在该等号两边的值是相等的,而赋值运算符,=,是指要完成,=,右边表达式的运算,并将运算结果存放到,=,左边指定的内存变量中。可见,赋值运算符完成两类操作,一是计算,二是赋值。,赋值运算符和赋值表达式 赋值运算构成了语言最基本、最,23,2.,赋值表达式,赋值表达式由赋值运算符将一个变量和一个表达式连接起来的式子称为赋值表达式。它的一般形式为:变量名表达式,对赋值表达式的求解过程:计算赋值运算符右边,表达式,的值,并将计算结果赋值给赋值运算符左边的,变量,。赋值表达式,变量名表达式,的值就是赋值运算符左边,变量,的值。例如上面提到的算术表达式:,(a+b+c)/(sqrt(a)+b*(+sin(y)+sin(z),写成赋值表达式为:,v=(a+b+c)/(sqrt(a)+b*(+sin(y)+sin(z),。其中,v,是变量, 赋值号右边是算术表达式,,v,的值就是这个算术表达式的值,也就是该赋值表达式的值。以下的赋值表达式表示:,i=5/*,将常数,5,赋值给变量,i,,赋值表达式,i=5,的值就是,5 */,a=3.5-b/*,计算算术表达式,3.5-b,的值并赋值给变量,a */,x=(a+b+c)/12.4*8.5 /*,计算算术表达式,(a+b+c)/12.4*8.5,的值并赋值给变量,x */,2. 赋值表达式 赋值表达式由赋值运算符将一个变量,24,逗号运算符和逗号表达式,作为一个操作符,逗号把几个表达式串在一起。逗号操作符的左侧总是作为,void(,无值,),,这意味着其右边表达式的值变为以逗号分开的整个表达式的值。例如:,x=(y=3,y+1);,这行将,3,赋给,y,,然后将,4,赋给,x,,因为逗号操作符的优先级比赋值操作符优先级低,所以必须使用括号。,实际上,逗号表示操作顺序。当它在赋值语句右边使用时,所赋的值是逗号分隔开的表中最后那个表达式的值。例如:,y=10;,x=(y=y-5,25/y);,执行后,,x,的值是,5,,因为,y,的起始值是,10,,减去,5,之后结果再除以,25,,得到最终结果。在某种意义上可以认为,逗号操作符和标准英语的,and,是同义词。,逗号运算符和逗号表达式 作为一个操作符,逗号把几个表达式,25,类型转换,在对赋值表达式求解过程中,如果赋值运算符两边的数据类型不一致,赋值时要进行类型转换。其转换工作由编译自动实现,转换原则是以,“=”,左边的变量类型为准。即将,“=”,右边的值转换为与,“=”,左边的变量类型一致。下面用,【,程序,2-4】,说明一下:,/*,文件名,:chap02_4.cpp */,#include ,void main(),int i=5;/*,说明整型变量,i,并初始化为,5*/,float a=3.5,a1;/*,说明实型变量,a,和,a1,并初始化,a*/,double b=123456789.123456789;/*,说明双精度型变量,b,并初始化*,/,char c=A;/*,说明字符变量,c,并初始化为,A*/,printf(i=%d,a=%f,b=%f,c=%cn,i,a,b,c);/*,输出,i,a,b,c,的初始值*,/,a1=i;i=a;a=b;c=i;/*,整型变量,i,的值赋值给实型变量,a1,,实型变量,a,的值赋给整型变量,i,,双精度型变量,b,的值赋值给实型变量,a,,整型变量,i,的值赋值给字符变量,c*/,printf(i=%d,a=%f,a1=%f,c=%cn,i,a,a1,c);/*,输出,i,a,a1,c,赋值以后的值*,/,类型转换在对赋值表达式求解过程中,如果赋值运算符两边的数据类,26,Your Topic Goes Here,运行该程序的输出结果如下:,i=5,a=3.500000,b=123456789.123457,c=A,i=3,a=123456792.000000,a1=5.000000,c=(,心形字符,),由以上运行结果可见:,将,float,型数据赋值给,int,型变量时,先将,float,型数据舍去其小数部分,然后再赋值给,int,型变量。,int,型数据赋给,float,型变量时,先将,int,型数据转换为,float,型数据,并以浮点数的形式存储到变量中,其值不变。,double,型实数赋给,float,型变量时,先截取,double,型实数的前,7,位有效数字,然后再赋值给,float,型变量。,int,型数据赋值给,char,型变量时,由于,int,型数据用两个字节表示,而,char,型数据只用一个字节表示,所以先截取,int,型数据的低,8,位,然后赋值给,char,型变量。,Your Topic Goes Here运行该程序的输出结果,27,位运算,C,语言和其它高级语言不同的是它完全支持按位运算符。这与汇编语言的位操作有些相似。表,2-4,列举了一些为运算符,如下示:,运算符,含义,优先级,按位求反,5,(高),右移,4,&,按位与,3,按位异或,2,|,按位或,1,(低),以上位运算符中除“,”,以外,均为二目运算符,即要求两侧各有一个运算对象。,位运算 C语言和其它高级语言不同的是它完全支持按位,28,1. “,按位求反”运算(,),“”,是一个单目运算符,用来对一个二进制数按位求反,即将,0,变,1,,,1,变,0,。例如,,025,是对八进制数,25,(即二进制数,00010101,)按位求反。, 0000000000010101,-,1111111111101010,即八进制数,177752,。因此,,025,的值为八进制数,177752,,并非,-025,。,1. “按位求反”运算() “”是一个单目运算符,29,2. “,左移”运算(,),“,左移”运算符是双目运算符,用来将一个数的各二进位全部左移若干位。运算符左边是移位对象,右边是整型表达式,代表左移的位数。左移时,右端(低位)补,0,,左端(高位)移出的部分舍弃。例如:,int a=025;,a=a2;,将,a,的二进制数左移,2,位,右补,0,。,20000000000010101,-,0000000001010100,即八进制数,54,。因此,,0252,的值为八进制数,54,。,2. “左移”运算(,),右移运算符的使用方法与左移运算符一样,所不同的是移位方向相反。右移时,右端(低位)移出的二进制数舍弃,左端(高位)移入的二进制数分两种情况:对于无符号整数和正整数,高位补,0,;对于负整数,高位补,1,。,例如:,int a=025;,a=a2;,将,a,的二进制数右移,2,位,由于,a,为正整数,左补,0,。,20000000000010101,-,0000000000000101,即八进制数,5,。因此,,0252,的值为八进制数,5,。,3. “右移”运算() 右移运算符的使用方法与左移,31,4. “,按位与”运算(,&,),按位与运算的规则是:参加运算的两个数据,按二进位进行“与”运算,如果两个相应的二进位都为,1,,则该位的结果值为,1,,否则为,0,。即:,0&0=0,;,0&l=0,;,1&0=0,;,1&1=1,;,例如:表达式,12&10,的运算如下:,120000000000001100,& 100000000000001010,-,80000000000001000,即十进制数,8,。,4. “按位与”运算(&) 按位与运算的规则是:参加运,32,分析以上运算结果可知,按位与运算具有以下特征:任何位上的二进制数,只要和,0,进行与运算,该位即被屏蔽(清零);和,1,进行与运算,该位保留原值不变。利用这一特征可以实现如下功能:,(,1,)清零。如果想将一个单元清零,也就是使其全部二进位为,0,,只需与,0,进行按位与运算,即可达到清零目的。,(,2,)取一个数中某些指定位。如有一个整数,a,(,2,个字节),想要其中的低字节,只需将,a,与八进制数,377,(,0000000011111111,)按位与即可。如果想取两个字节中的高字节,只需将,a,与八进制数,177400,(,1111111100000000,)按位与即可。,(,3,)要想将哪一位保留下来,就与一个数进行,&,运算,此数在该位取,1,,例如有一个数,01010100,(十进制数,84,),想把其中左面第,3,、,4,、,5,、,7,、,8,位保留下来,设计一个数,其左面第,3,、,4,、,5,、,7,、,8,位为,1,,其他位为,0,,即为十进制数,59,,将这两个数进行按位与即可。,分析以上运算结果可知,按位与运算具有以下特征,33,5. “,按位异或”运算(,),按位异或的运算规则是:参与运算的两个运算数中相对应的二进制位上同号,则结果为,0,,异号则为,1,。即:,0&0=0,;,0&1=1,;,1&0=1,;,1&1=0,;,例如,,1210,:,120000000000001100, 100000000000001010,-,60000000000000110,即十进制数,6,。按位异或运算有如下应用:,5. “按位异或”运算() 按位异或的运算规则是:参,34,(,1,)使特定位翻转,假设有,01111010,,想使其低,4,位翻转,即,1,变为,0,,,0,变为,1,。可以将它与,00001111,进行按位异或运算,结果为,01110101,,结果值的低,4,位正好是原数低,4,位的翻转。要使哪几位翻转就将与其进行按位异或运算的该几位置为,1,即可。这是因为原数中值为,1,的位与,1,进行按位异或运算得,0,,原数中的位值,0,与,1,进行按位异或运算的结果得,1,。,(,2,)与,0,按位异或,保留原值,(,3,)交换两个值,不用临时变量,假设要想交换,a,、,b,之值,可以用以下赋值语句实现:,a=ab;,b=ba;,a=ab;,因为,a=,a,b,,(假设,a,和,b,最初的值加上下划线)则:,b=,b,a=,b,(,a,b,)=,a,b,b,=,a,0=,a,a=ab=(,a,b,),a,=,a,a,b,=0,b,=,b,(1)使特定位翻转,35,6. “,按位或”运算(,|,),按位或运算的规则是:参加运算的两个数据,按二进位进行“或”运算,如果两个相应的二进位都为,0,,则该位的结果值为,0,,否则为,1,。即:,0|0=0,;,0|l=1,;,1|0=1,;,1|1=1,;,例如:表达式,12|10,的运算如下:,120000000000001100,| 100000000000001010,-,140000000000001110,即十进制数,14,。分析以上运算结果可知,按位或运算具有以下特征:任何位上的二进制数,只要和,1,进行或运算,该位即为,1,;和,0,进行或运算,该位保留原值不变。例如,,a,是一个整数(,16,位),,a=a|0377,,使,a,的低,8,位全置为,1,,高,8,位保留原样。,6. “按位或”运算(|),36,7.,位运算赋值运算符,位运算符与赋值运算符可以组成复合赋值运算符,这样的复合赋值运算符如表,2-5,所列。,复合赋值运算符,表达式,等价的表达式,=,a=n,a=a=,a=n,a=an,&=,a&=b,a=a&b,=,a=b,a=ab,|=,a|=b,a=a|b,表,2-5,复合赋值运算符,7. 位运算赋值运算符 位运算符与赋值运算符可以组成复,37,8.,不同长度的数据进行位运算,位运算的运算数可以是整型和字符型数据。如果两个运算数类型不同时位数亦会不同。遇到这种情况,系统将自动进行如下处理:,(,1,)先将两个运算数右端对齐。,(,2,)再将位数短的一个运算数往高位扩充,即无符号数和正整数左侧用,0,补全;负数左侧用,1,补全;然后对位数相等的这两个运算数,按位进行位运算。,8. 不同长度的数据进行位运算,38,【,程序,2-5】,编写一个程序,实现无符号,16,位数的循环左移,n,位。,采用,unsigned short,类型存放无符号,16,位数。,C,语言中只有左、右移位,而没有循环移位功能。左移和循环左移的区别在于对从左边(高端)移出的,n,位数的处理上。左移时,移出的,n,位数被丢弃,循环左移时,移出的,n,位数应依次放在右边(低端)的,n,位上。为将无符号,16,位数,d,达到循环左移的目的,实现过程如下:,(,1,)先将,d,高端的,n,位数通过“右移”操作移至低端的,n,位上(高端全为,0,),把结果存入中间变量,a,中。,(,2,)再通过“左移”运算将,d,左移,n,位(低端移入的全为,0,),把结果存入另一中间变量,b,中。,(,3,)最后利用按位或运算将这两个中间变量中的内容“拼装”在一起,完全循环左移功能。,【程序2-5】编写一个程序,实现无符号16位数的循环左移n位,39,将循环左移功能设计成,leftmove(),函数,对应的程序如下:,/*,文件名:,chap02_5.cpp */,#include ,void leftmove(unsigned short *d,int n),unsigned short a,b;,a=*d(16-n);,b=(*d)n;,*d=a|b;,void main(),unsigned short d;,d=0x6271;,leftmove(,printf(%xn,d);,程序运行结果:,2716,将循环左移功能设计成leftmove()函数,对应的程序如下,40,
展开阅读全文