《C语言程序设计 第十一章 位运算.ppt》由会员分享,可在线阅读,更多相关《C语言程序设计 第十一章 位运算.ppt(18页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、甘肃工业职业技术学院信息工程系甘肃工业职业技术学院信息工程系2009年12月张燎 第十一章第十一章 位运算位运算 位运算符和位运算位运算举例位段 11.1位运算符和位运算语言提供了六种位运算符:&按位与按位与 取反取反|按位或按位或 右移右移说明:说明:(1)(1)位运算符除位运算符除以外,均为二目运算,即要求两侧各有一个以外,均为二目运算,即要求两侧各有一个 运算量。运算量。(2)(2)运算量只能是整型或字符型的数据,不能为实型数据。运算量只能是整型或字符型的数据,不能为实型数据。11.1.1“按位与”运算符(&)功能:对参与运算的两数各对应的二进位相与。功能:对参与运算的两数各对应的二进位
2、相与。只有对应的两个二进制位均为只有对应的两个二进制位均为1 1时,结果位才为时,结果位才为1 1,否则为,否则为0 0。即即 0&0=0,0&1=0,1&0=0,1&1=1参与运算的数以补码方式出现。参与运算的数以补码方式出现。例如例如 3&5,应该按位与:,应该按位与:00000011 (3)(&)00000101 (5)00000001 (1)按位与的特殊用途:按位与的特殊用途:某些位清零某些位清零保留某些位保留某些位取一个数中某些指定位取一个数中某些指定位例如:把例如:把a 的高八位清的高八位清 0,保留低八位。,保留低八位。可作可作a&255运算运算 00101100 1010110
3、0 (&)00000000 11111111 00000000 10101100把一个数把一个数01010100的左面第的左面第3、4、5、7、8位保位保留下来。留下来。01010100 (&)00111011 00010000原来数中为原来数中为1 1的的位,新数中相位,新数中相应位为应位为0 0原来数要保留原来数要保留的位,新数中的位,新数中相应位为相应位为1 111.1.2“按位或”运算符(|)功能:对参与运算的两数各对应的二进位相或。功能:对参与运算的两数各对应的二进位相或。只要对应的两个二进制位有一个为只要对应的两个二进制位有一个为1 1时,结果位就为时,结果位就为1 1。即即 0|
4、0=0,0|1=1,1|0=1,1|1=1例如:例如:9|59|5可写算式如下:可写算式如下:00001001 (9)(|)(|)00000101 (5)00001101 (13)可见可见 9|5=13按位或运算常用来对一个数据的某些位定值位按位或运算常用来对一个数据的某些位定值位1 1。11.1.3“异或”运算符()功能:对参与运算的两数各对应的二进位相异或。当对应的两个二进制位相异时,结果位就为当对应的两个二进制位相异时,结果位就为1 1。即 0 0=0,0 1=1,1 0=1,1 1=0例如:例如:9 9 5 5可写算式如下:可写算式如下:00001001 (9)()00000101 (
5、5)00001100 (12)可见可见 9 5=12“异或异或”的意思是判断两个相应的位值是否为的意思是判断两个相应的位值是否为“异异”,为为“异异”就取真(就取真(1 1),否则为假(),否则为假(0 0)。)。举例说明举例说明 运算符的应用运算符的应用使特定位翻转使特定位翻转假设有假设有0111010,想使其低,想使其低4 4位翻转,即位翻转,即1 1变为变为0 0,0 0变为变为1 1。01111010 ()00001111 01110101要想使哪几位翻转,就将与其进要想使哪几位翻转,就将与其进行行运算的该几位置为运算的该几位置为1 1即可。即可。与与0 0相相,保留原值,保留原值 0
6、1111010 ()00000000 01111010举例说明举例说明 运算符的应用运算符的应用交换两个值,不用临时变量交换两个值,不用临时变量假如假如a=3,b=4a=3,b=4,想将,想将a a和和b b的值互换,可以用以下赋值语句实现:的值互换,可以用以下赋值语句实现:a=ab;b=ba;a=ab;用竖式来说明:用竖式来说明:a=011 (3)()b=100 (4)a=111()b=100 b=011 (3)()a=111 a=100 (4)11.1.4“取反”运算符()功能:对参与运算的数的各二进位按位取反。取反运算符为单目运算符,具有右结合性。取反运算符为单目运算符,具有右结合性。例
7、如:9的运算为:(00000000 00001001)结果为结果为 11111111 11110110运算符的优先级高于 算数运算符、关系运算符、逻辑运算符、和其他位运算符都高。例如:例如:b&a,要先进行要先进行a运算,然后进行运算,然后进行&运算。运算。例:a a的值的值6412711.1.5左移运算符()功能:用来将一个数的各二进位全部左移若干位。高位左移后溢出,舍弃。低位补高位左移后溢出,舍弃。低位补0。a a的二进制形式的二进制形式0100000001111111 a1 a11000000011111110 a2 a)功能:用来将一个数的各二进位全部右移若干位。右移时,需要注意符号位
8、问题。右移时,需要注意符号位问题。对于无符号数,对于无符号数,右移时左边高位移入右移时左边高位移入0。对于有符号数,对于有符号数,如果原来符号位为如果原来符号位为0(该数为正),则左边也是移入(该数为正),则左边也是移入0。如果原来符号位为如果原来符号位为1(即负数),则左边移入(即负数),则左边移入0还是还是1,要取决于所用的计算机系统。要取决于所用的计算机系统。移入移入0的称为的称为“逻辑右移逻辑右移”移入移入1的称为的称为“算术右移算术右移”例如:例如:a:1001011111101101 (用二进制形式表示用二进制形式表示)a1:0100101111110110 (逻辑右移时)(逻辑右
9、移时)a1:1100101111110110 (算术右移时)(算术右移时)右移一位相当于该数除以右移一位相当于该数除以2,右移,右移n位相当于除以位相当于除以2n。11.2位运算举例例例12.1取一个整数取一个整数a从右端开始的从右端开始的4 7位。位。(1)(1)先使先使a a右移右移4 4位,目的是使要取出的那几位移到最右端。位,目的是使要取出的那几位移到最右端。08 7 4 3(a)1504 3(b)15右移到右端可以用右移到右端可以用 a4 来实现。来实现。(2)(2)设置一个低设置一个低4 4位全为位全为1 1,其余全为,其余全为0 0的数。的数。可以用可以用 (04)来实现。来实现
10、。0:00000000000:111111111104:1111110000 (04)&(04)根据上一节介绍的方法,与根据上一节介绍的方法,与低低4位位为为1的数进行的数进行&运算运算,就能将这四位保留下来。就能将这四位保留下来。#includevoid main()unsigned a,b,c,d;scanf(“%o”,&a);b=a4;c=(04);d=b&c;printf(“%o,%dn%o,%dn”,a,a,d,d);331 331,21715,13 11.3位段 对内存中信息的存储一般以字节为单位。实际上,对内存中信息的存储一般以字节为单位。实际上,有时存储一个信息不必用一个或多个
11、字节。有时存储一个信息不必用一个或多个字节。例如:例如:“真真”或或“假假”用用0或或1表示,只需表示,只需1位即可。位即可。那么,怎样向一个字节中的一个或几个二进制位赋那么,怎样向一个字节中的一个或几个二进制位赋值和改变它的值呢?值和改变它的值呢?可以用以下两种方法:可以用以下两种方法:可以人为地将一个整型变量可以人为地将一个整型变量datadata分为几部分。分为几部分。位段。位段。位段位段 C语言允许在一个结构体中以位为单位来指定其成员所占内存长度。这种以这种以位位为单位的成员称为为单位的成员称为“位段位段”或称或称“位域位域”。利用位段能够用较少的位数存储数据。利用位段能够用较少的位数
12、存储数据。struct packed_data unsigned a:2;unsigned b:6;unsigned c:4;unsigned d:4;int i;data;a占占 2位位b占占 6位位c占占 4位位d占占 4位位i占占 2个字节个字节总共占总共占4 4个字个字节节也可以使各个位段不恰好占满一个字节struct packed_data unsigned a:2;unsigned b:6;unsigned c:4;int i;data;struct packed_data unsigned a:2;unsigned b:6;unsigned c:4;unsigned d:4;in
13、t i;data;abcd2i64416abc2i64416在在a、b、c之后之后4位空间闲置不用,位空间闲置不用,i从另一字节开头起存放。从另一字节开头起存放。关于位段的定义和引用的几点说明:关于位段的定义和引用的几点说明:位段成员的类型必须指定为位段成员的类型必须指定为unsigned或或int类型。类型。若某一位段要从另一个字开始存放,可以用以下形式定义:若某一位段要从另一个字开始存放,可以用以下形式定义:unsigned a:1;unsigned b:2;unsigned :0;unsigned c:1;(另一存储单元另一存储单元)用了长度为用了长度为0的位段,其作用是使下一个位段从下一个存储单元开的位段,其作用是使下一个位段从下一个存储单元开始存放。始存放。一个位段必须存储在同一个存储单元中,不能跨两个单元。一个位段必须存储在同一个存储单元中,不能跨两个单元。可以定义无名位段。可以定义无名位段。位段的长度不能大于存储单元的长度,也不能定义位段数组。位段的长度不能大于存储单元的长度,也不能定义位段数组。位段可以用整型格式符输出。位段可以用整型格式符输出。位段可以在数值表达式中引用,它会被系统自动地转换成整型数。位段可以在数值表达式中引用,它会被系统自动地转换成整型数。一个存储单元一个存储单元