第十六次课(位运算)_第1页
第十六次课(位运算)_第2页
第十六次课(位运算)_第3页
第十六次课(位运算)_第4页
第十六次课(位运算)_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1

位运算2概述前面介绍的各种运算都是以字节作为最基本单位进行的。但在很多系统程序中常要求在位(bit)一级进行运算或处理。C语言提供了位运算的功能,这使得C语言也能像汇编语言一样用来编写系统程序。3位运算符和位运算C语言提供了六种位运算符运算符含义&按位与|按位或^按位异或~取反>>右移<<左移4一、按位与&运算按位与运算符“&”是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,结果位才为1,否则为0。参与运算的数以补码方式出现。00001001(&)0000010100000001(9的二进制补码)(5的二进制补码)(1的二进制补码)0&0=00&1=01&0=01&1=1例如:9&5可写算式如下:可见9&5=1。5按位与&的用途清零取一个数中的某些指定位00101011(&)0100010000000000001011001010110000000000111111110000000010101100abc001011001010110011111111000000000010110000000000abcb=(377)8c=a&b b=(177400)8c=a&b 6想保留哪一位,就与一个数进行&运算,此数在该位取101010100(&)0011101100010000保留左面的3、4、5、7、8位7

二、按位或|运算按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的两个二进位有一个为1时,结果位就为1。参与运算的两个数均以补码出现。0|0=00|1=11|0=11|1=1例如:9|5可写算式如下:00001001(|)0000010100001101(9的二进制补码)(5的二进制补码)(13的二进制补码)可见9|5=13。8按位或|的用途常用来对一个数据的某些位定值为1a|0377例如:a是一个整数(16位),如果有下式则低8位全置为1,高8位保留原样9三、

按位异或∧运算按位异或运算符“∧”是双目运算符。其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。相同时,结果为0。参与运算数仍以补码出现0∧0=00∧1=11∧0=11∧1=0例如:9∧5可写算式如下:00001001(∧)0000010100001100(9的二进制补码)(5的二进制补码)(12的二进制补码)可见9∧5=12。10按位异或∧的用途使特定位翻转01111010(∧)0000111101110101与0相∧,保留原值

00001001(∧)00000000

0000100111交换两个值,不用临时变量例如:a=3,b=4,交换a和b

00000011(∧)00000100

00000111(∧)00000100

00000011(∧)00000111

00000100a=3b=4a=a∧b=7b=a∧b=3a=b∧a=4b=4a=7a=a∧bb=b∧a=b∧a∧b=a∧b∧b=a∧0=aa=a∧b=a∧b∧b∧a∧b=ba=a∧bb=b∧aa=a∧b12四、

取反~运算求反运算符~为单目运算符,具有右结合性。其功能是对参与运算的数的各二进位按位求反。运算级别较高(2级)例如:~9的运算如下:(~)000010011111011013取反~的用途若一个整数a为16位,想使最低一位为0,可以用a=a&0177776如果将c源程序移植到以32位存放一个整数的计算机上,应改用a=a&037777777776如上,移植性差,可改为:a=a&~114五、

左移<<运算左移运算符“<<”是双目运算符。其功能把“<<”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数,高位丢弃,低位补0。a的值二进制形式a<<1a<<26401000000010000000010000000012701111111011111110011111110015说明左移1位相当于乘2,左移2位相当于乘4…,前提是被溢出舍弃的高位中不包含1左移比乘法运算快,有些c编译程序自动将乘2的运算用左移1位来实现,将乘2n的幂运算处理为左移n位16六、

右移>>运算右移运算符“>>”是双目运算符。其功能是把“>>”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。例如:设a=15,有式子a>>2表示把00001111右移为00000011(十进制3)注意:对于有符号数,在右移时,符号位将随同移动。当为正数时,最高位补0;而为负数时,符号位为1,最高位是补0或是补1取决于编译系统的规定。移入0的称为“逻辑右移”,即简单右移,移入1的称为“算术右移”,很多系统规定为补1。17七、

位运算赋值运算符位运算符和赋值运算符可以组成复合赋值运算符&=、|=、>>=、<<=、∧=例如:a&=b相当于a=a&b18八、

不同长度数据进行位运算如果两个长度不同的数据进行位运算(例如:a为long型,b为int型,a&b),系统将二者右端对齐。如果b为正数,则左侧16位补0。如果b为负数,则左侧16位补1。如果b为无符号整数型,则左侧补零。19位运算的优先级取反~→→右移>>和左移<<→→按位与&→→按位异或∧→→按位或|→→&=、|=、>>=、<<=、∧=20

九、位运算举例【例】取一个整数a从右端开始的4∽7位00000001010010110000000000010100a=337a>>4a=20c=~(~0<<4)c=150000000000001111b=a&c000000000000010021c=~(~0<<4)c=150000000000001111000000000000000011111111111111110~01111111111110000~(~0<<4)0000000000001111~0<<422main(){unsigneda,b,c,d;scanf(“%o”,&a);b=a>>4;c=~(~0<<4);d=b&c;printf(“%o,%d\n%o,%d\n”,a,a,d,d);}运行情况:331↙331,21715,1323【例】循环移位1101111110101011a=(157653)80111101111110101c=(75765)8241101111110101011a=(157653)80001101111110101c=a>>30110000000000000b=a<<13d=b|c011110111111010125main(){unsigneda,b,c,d;intn;scanf(“a=%o,n=%d”,&a,&n);b=a<<(16-n);c=a>>n;d=c|b;printf(“%o\n%o”,a,d);}运行情况:a=157653,n=3↙1576537576526

位段(位域)前面介绍的对内存中信息的存取都以字节为单位。实际上有些信息的存取不必用一个或多个字节,例如,“真”和“假”用0或1表示,只需1位即可。当计算机用于过程控制、参数检测或数据通讯领域时,控制信息往往只占一个字节的一个或几个二进制位,常常在一个字节中存放几个信息。向一个字节中的一个或几个二进位赋值有如下两种方法27(1)人为将一个整型变量data分为几部分dataabcd28一、现设c的原值为0,想将c的值变为120000dataabcd000000000000110012000000001100000012<<4data|12<<4110012<<4data|12<<4.29二、如果c的原值不为0,想将c的值变为12data=data&(0177417)8abcd对c清零data1111111100001111(0177417)80000dataabcd30(0177417)8称为“屏蔽字”,即把c以外的信息屏蔽起来不受影响,只使c变为0,但(0177417)8很难记,为此改为如下data=data&~(15<<4)data=data&(0177417)8

相当于:0000000000001111000000001111000011111111000011111515<<4~(15<<4)31data=data&~(15<<4)|12<<4将12赋给c0000000000001111150000000010101010n首先取n右端4位的值n&15如果想将n右端4位的值赋予c0000000000001010n&150000data&~(15<<4)abcd32data=data&~(15<<4)|(n&15)<<4与c中已清零的data按位或左移4位(n&15)<<400000000101000000000data&~(15<<4)abcd1010abcd33(2)位段(位域)位段:c语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或“”位域”(bitfield)。这样可以节省存储空间。位段的定义和位域变量的说明struct

位域结构名

{位域列表

};其中位域列表的形式为:

类型说明符

位域名:位域长度;

34位域变量的说明与结构变量说明的方式相同。可采用先定义后说明,同时定义说明或者直接说明这三种方式。structbs{inta:8;intb:2;intc:6;};structbsdata;structbs{inta:8;intb:2;intc:6;}data;dataabc35位段中数据的引用位段的使用和结构体成员的使用相同,一般形式为位段变量名·

位段名data.a=124data.b=2data.c=33注意位段允许的最大范围。下面是错的:data.b=8由于8的二进制为1000,而data.b只有两位,在此情况下,取1000的低2位,故data.b的值为0位域允许用各种格式输出。36main(){structbs{unsigneda:1;unsignedb:3;unsignedc:4;}bit,*pbit;bit.a=1;bit.b=7;bit.c=15;printf("%d,%d,%d\n",bit.a,bit.b,bit.c);pbit=&bit;pbit->a=0;pbit->b&=3;pbit->c|=1;printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c);}37main(){structbs{unsigneda:1;unsignedb:3;unsignedc:4;}bit,*pbit;bit.a=1;bit.b=7;bit.c=15;printf("%d,%d,%d\n",bit.a,bit.b,bit.c);pbit=&bit;pbit->a=0;pbit->b&=3;pbit->c|=1;printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c);}例38说明2)一个位段必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位段时,应从下一单元起存放该位段。也可以有意使某位段从下一单元开始。例如:structbs{unsigneda:4unsigned:0/*空域*/unsigned

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论