第11章位运算_第1页
第11章位运算_第2页
第11章位运算_第3页
第11章位运算_第4页
第11章位运算_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

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

文档简介

1、第第11章章 位运算位运算第第11章章 位运算位运算11.1 位运算符位运算符11.2 位运算符的运算功能位运算符的运算功能11.3 位段位段习题习题11第第11章章 位运算位运算11.1 位运算符计算机中的位运算是针对二进制代码进行的。每一个二进制位的取值只有0或1。位运算符的操作对象是一个二进制位的集合,如一个字节(8 bit)。 位运算符共有6种,即 、&、| 和 ,分别表示按位取反、左移位、右移位、按位与、按位或和按位异或,见表11-1所示。第第11章章 位运算位运算表11-1 位 运 算 符 按位操作的情况,见表11-2所示,其中,a和b分别表示一个二进制位。运 算 符 名

2、称 使 用 格 式 按 位 取 反 表 达 式 左 移 位 表 达 式1 右 移 位 表 达 式1 表 达 式2 & 按 位 与 表 达 式1 & 表 达 式2 | 按 位 或 表 达 式1 | 表 达 式2 按 位 异 或 表 达 式1 表 达 式2 第第11章章 位运算位运算 表11-2 按位逻辑运算a b a a & b a | b a b 0 0 1 0 0 0 0 1 1 0 1 1 1 0 0 0 1 1 1 1 0 1 1 0 第第11章章 位运算位运算 移位运算符是将一个数的二进制位向左或向右移若干位。每向左移一位,就相当于对操作对象乘以2;每向右移一位

3、,就相当于对操作对象除以2。向左移位时,右边补0,高位溢出舍弃不用;向右移位时,对无符号数左边补0。在C语言中,对有符号数,若该数为正,则左边补0;若该数为负,则左边补1。11.1.1 按位取反 求反运算符“”为单目运算符,具有右结合性。其功能是对参与运算的数的各二进位按位求反。例如,9的运算为(0000 0000 0000 1001)=1111 1111 1111 0110即将其操作对象中的所有二进制位全部改变状态,即“逢0变1,逢1变0”。第第11章章 位运算位运算 又如,八进制数0217(即二进制数1000 1111),其按位取反后为八进制数0160(即二进制数0111 0000),即1

4、000 1111 0111 000011.1.2 移位 移位运算符有左移运算符和右移运算符两种。1. 左移运算符 左移运算符“”是双目运算符。其功能是将一个数的各二进制位全部左移若干位(左丢弃,右补0),由“”右边的数指定移动的位数。第第11章章 位运算位运算左移运算符的一般书写格式为表达式1 表达式2其中,“表达式1”是被左移的对象,“表达式2”给出左移的位数。例如:a=1;a=a 表达式2其中,“表达式1”是被右移的对象,“表达式2”给出右移的位数。例如:a=15;a=a2;示把0000 1111右移为0000 0011(十进制3)。 第第11章章 位运算位运算应该说明的是,对于有符号数,

5、在右移时,符号位将随同移动。当为正数时,最高位补0,而为负数时,符号位为1,最高位是补0或是补1取决于编译系统的规定。Turbo C和很多系统规定为补1。 11.1.3 按位与 按位与运算符“&”是双目运算符。其功能是参与运算的两数各对应的二进位相与。参与运算的数以补码的方式出现。 按位与的一般书写格式为表达式1 & 表达式2其中,“表达式1”和“表达式2”均为整型表达式。第第11章章 位运算位运算 按位与的运算原则为:当两个操作对象的相应二进制位都为1时,则该位的结果为1,否则为0,即“两1为1,其余为0”。 但要注意,按位与运算时,两个表达式之间用“&”符号,而逻辑

6、与时,两个表达式之间用“&”符号,所以,一定要注意不要弄错。 例如,11&5可写成算式如下: 0000 1011&0000 01010000 0001第第11章章 位运算位运算所以,11&5的值为1。 按位与运算通常用来对某些位清0或保留某些位。例如把a的高八位清0,低八位保留,可作a&255运算(255的二进制数为0000 0000 1111 1111)。 【例11-1】右移运算符和按位与运算符举例。#include stdio.hmain( ) unsigned a,b; printf(input a number: ); scanf(%d,&

7、;a); 第第11章章 位运算位运算b=a5; /* a右移5位,将右移后的值赋给b */ b=b&15; /* 将b和15按位与的值赋给b */ printf(a=%dtb=%dn,a,b); 运行结果:input a number: 255a=255 b=7第第11章章 位运算位运算【例11-2】利用按位与来获取指定位的值。 假设x是一般的unsigned类型的整型数(2个字节),现在需要获取其低字节的值,这时,只需将x与0377相与即可。例如:y = x & 0377式中,x的二进制表示为0101 0001 0111 0010,0377的二进制表示为0000 0000 1

8、111 1111,y的二进制表示为0000 0000 0111 0010。即0101 0001 0111 0010&0000 0000 1111 11110000 0000 0111 0010第第11章章 位运算位运算【例11-3】利用按位与来测试指定的位是否为0。 假设需测试上例中x的从左数第4位是否为0, 则只需将它与010000(八进制)按位与(即y=x & 010000)。若y为0,则说明被测位为0,否则为1。 由于x的二进制表示为0101 0001 0111 0010,010000的二进制表示为0001 0000 0000 0000,因此,计算结果为0001 0000

9、 0000 0000。即0101 0001 0111 0010&0001 0000 0000 00000001 0000 0000 0000第第11章章 位运算位运算11.1.4 按位或 按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的两个二进位有一个为1,结果位就为1,即“两0为0,其余为1”。参与运算的两个数均以补码的形式出现。 按位或的一般书写格式为表达式1 | 表达式2其中,“表达式1”和“表达式2”均为整型表达式。但要注意,按位或运算时,两个表达式之间用“|”符号,而逻辑或时,两个表达式之间用“|”符号,所以,一定要注意不要弄错。第第11章

10、章 位运算位运算例如,9|5可写成算式如下:0000 1001|0000 01010000 1101(十进制为13)所以,9|5的值为13。第第11章章 位运算位运算 【例11-4】利用按位或将指定位设置为1。 假设将x的从右数第3位(二进制位)设置为1,则只需执行如下的表达式即可。x = x | 04式中,x的二进制表示为0101 0001 0111 0010,04的二进制表示为0000 0000 0000 0100,按位或后的x值为0101 0001 0111 0110。即0101 0001 0111 0010| 0000 0000 0000 01000101 0001 0111 0110

11、 第第11章章 位运算位运算【例11-5】左移、右移、按位或和按位与运算符举例。#include stdio.hmain( ) char a=a,b=b; int p,c,d; p=a; p=(p8; printf(a=%dnb=%dnc=%dnd=%dn,a,b,c,d);第第11章章 位运算位运算 运行结果:a=97b=98c=97d=98第第11章章 位运算位运算11.1.5 按位异或 按位异或运算符“”是双目运算符。其功能是参与运算的两数各对应的二进位相异或,当两数对应的二进位相异时,结果为1。 按位“异或”的一般书写格式为表达式1 表达式2其中,“表达式1”和“表达式2”均为整型表达

12、式。 按位异或的运算原则为:当两个操作对象的相应位相同时,则该对应位的结果为0,否则为1,即“相同为0,不同为1”。即0 0 = 0;0 1 = 1;1 0 = 1;1 1 = 0 按位异或也可以称不进位加,即两个操作对象执行二进制相加,但不向高位进位。 第第11章章 位运算位运算例如,95可写成算式如下:0000 1001 0000 01010000 1100(十进制为12)所以,95的值为12。 利用按位异或可使一个数的各二进制位翻转。例如要使x的各位翻转,只需执行下面的表达式。x = x 0177777其中,x的二进制表示为0101 0001 0111 0010,异或后的结果为1010

13、1110 1000 1101。 第第11章章 位运算位运算11.2 位运算符的运算功能位运算符的运算功能【例11-6】将整型数据n的后5位数据置为0,其余各位不变。#include main( ) int n ; printf(input n : ) ; scanf(%d , &n) ; n&=037 ; printf(%dn , n) ; ;第第11章章 位运算位运算【例11-7】实现向左循环移位。#include main( ) unsigned a , b , c ; int n ; printf(input a : ) ; scanf(%o , &a) ; pr

14、intf(input n : ) ; scanf(%d , &n) ; b=a(16-n) ; c=an ; a=b | c ; printf(%on , a) ;第第11章章 位运算位运算【例11-8】将一个整型数据的各位以倒序输出。#include main( ) unsigned a , b ; int i ; printf(input a : ) ; scanf(%o , &a) ; b=0 ; for(i=0 ; i16 ; i+) b=b1 ; b=(a & (1i | b ; printf(%on , b) ;第第11章章 位运算位运算【例11-9】取一个

15、单元a的某几位到另一个单元b。#include void yiwei(pa , pb , st1 , st2 , n1)unsigned *pa , *pb ;int st1 , st2 , n1 ; unsigned c , d ; int move ; move=st1-st2 ; c=(0n1)(17-st1-n1) ; d=(0n1)0) *pb=(c & *pa)(-move) | (*pb & d) ;第第11章章 位运算位运算main( ) int a1 , b1 , n ; unsigned a , b ; printf(input a : n) ; scanf

16、(%o , &a) ; printf(input b:n) ; scanf(%o , &b) ; printf(input the start num a1 : n) ; scanf(%d , &a1) ;第第11章章 位运算位运算printf(input the start num b1 : n) ; scanf(%d , &b1) ; printf(input number of the bits:n); scanf(%d , &n) ; yiwei(&a , &b , a1 , b1 , n) ; printf(%on %on ,

17、a ,b) ;第第11章章 位运算位运算11.3 位段位段有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。例如,在存放一个开关量时,只有0和1两种状态,用一位二进位即可。为了节省存储空间,并使处理简便,语言又提供了一种数据结构,称为“位段”。 所谓“位段”,是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位段来表示。第第11章章 位运算位运算1. 位段的定义和位段变量的说明1) 位段的定义 位段定义与结构定义相仿,其格式为struct 位段结构名 位域列表 ;其

18、中,位域列表的格式为类型标识符 位域名:位域长度 例如:struct packed_data 第第11章章 位运算位运算 unsigned a:2; unsigned b:6; unsigned c:4; unsigned d:4; int i; data ;第第11章章 位运算位运算位段变量data的数据存储情况如图11.1所示。图11.1 位段变量的存储 a b c i d 2 6 4 4 16 data 第第11章章 位运算位运算 位段变量的说明与结构变量说明的方式相同。可采用先定义后说明,同时定义说明或者直接说明这3种方式。2) 说明 对于位段的定义尚有以下几点说明。(1) 一个位域必

19、须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域,也可以有意使某位域从下一单元开始。例如: 第第11章章 位运算位运算struct bs unsigned a:4 unsigned :0 /* 空域 */ unsigned b:4 /* 从下一单元开始存放 */ unsigned c:4在这个位段定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。 (2) 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度。也就是说,不能超过8位二进位。第第11章章 位运算位运算 (3) 位域可以无位域名,这

20、时它只用来作填充或调整位置。无名的位域是不能使用的。例如:struct k int a:1 int :2 /* 该2位不能使用 */ int b:3 int c:2; 从以上分析可以看出,位段在本质上就是一种结构类型,不过其成员是按二进位来分配的。第第11章章 位运算位运算2. 位域的引用 位域引用的一般格式为位段变量名.位域名位域允许用各种格式输出。 【例11-10】定义一个位段变量,对变量的位域赋值,输出位域的值。#include stdio.hmain( ) struct bs /* 定义位段bs */ 第第11章章 位运算位运算 unsigned a:1; unsigned b:3; unsigned c:4; bit,*pbit; /* 定义位段变量bit和指针pbit */bit.a=1; /* 第10行 */ bit.b=7; /* 第11行

温馨提示

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

评论

0/150

提交评论