《第9章 位运算》由会员分享,可在线阅读,更多相关《第9章 位运算(30页珍藏版)》请在金锄头文库上搜索。
1、第第9 9章章 位运算位运算第第9 9章章 位运算位运算本章要点本章要点: :六种位运算的基本概念、主要应用六种位运算的基本概念、主要应用位运算的混合使用位运算的混合使用2第第9 9章章 位运算位运算9 91 1 位运算的类型位运算的类型 9 92 2 位运算举例位运算举例9 93 3 位段位段9 94 4 总结与提高总结与提高39 91 1 位运算的类型位运算的类型 C C语言一共提供了六种位运算符:语言一共提供了六种位运算符:& &:按位:按位“与与”| |:按位:按位“或或”:按位:按位“异或异或”:取反:取反:右移:右移 这六种运算符号的优先级别(由高到低):这六种运算符号的优先级别(
2、由高到低): & & | |。这六种运算符号的结合性为:这六种运算符号的结合性为:为自右至左,为自右至左,其它为自左至右。其它为自左至右。 49 91 1 位运算的类型位运算的类型 要特别注意的是,参与运算的数是以要特别注意的是,参与运算的数是以补补码码方式出现的,并且参与运算的量应为方式出现的,并且参与运算的量应为整型整型或或字符型字符型,不能为实型数据。,不能为实型数据。 59 91 1 位运算的类型位运算的类型按位按位“与与”运算运算 按位按位“ “与与” ”运算符运算符“ “&”&”是双目运算符,其功是双目运算符,其功能是对参与运算的两数从低位到高位对应的位相能是对参与运算的两数从低位
3、到高位对应的位相与,与,“ “与与” ”操作规定为:操作规定为:1&11&1的结果为的结果为1 1,0&10&1、1&01&0、0&00&0的结果都为的结果都为0 0。 69 91 1 位运算的类型位运算的类型按位按位“与与”运算运算例例9-19-1两个整数的两个整数的“ “与与” ”操作。操作。main()main() int a=5, b=6; int a=5, b=6; int c=-5, d=-6; int c=-5, d=-6; int x, y; int x, y; x=a & b; x=a & b; y=c & d; y=c & d; printf( printf(n%d, %d
4、, x, y);n%d, %d, x, y); 该程序运行的结果为:该程序运行的结果为:4,-64,-679 91 1 位运算的类型位运算的类型按位按位“与与”运算运算说明:说明:5 5的二进制数是的二进制数是00000101,600000101,6的二进制数是的二进制数是00000110,00000110,那么那么a&ba&b的结果为的结果为4 4,如下式所示。,如下式所示。 00000101 (5) 00000101 (5)(&) 00000110 (6)(&) 00000110 (6) 00000100 (4) 00000100 (4)而而-5-5的二进制数补码是的二进制数补码是1111
5、101111111011,-6-6的二进制的二进制数补码是数补码是1111101011111010,因此,因此c&dc&d的结果为的结果为-6-6,如下,如下式所示。式所示。 11111011 (-5) 11111011 (-5)(&) 11111010 (-6)(&) 11111010 (-6) 11111010 (-6) 11111010 (-6)89 91 1 位运算的类型位运算的类型按位按位“与与”运算运算 按位按位“ “与与” ”运算常用于运算常用于位清零位清零。欲将一个。欲将一个变量的某些位清零,只要同另一个相应位为变量的某些位清零,只要同另一个相应位为其余位为的数进行其余位为的数
6、进行“ “与与” ”运算即可。运算即可。 同理,要同理,要提取某个数的一些位提取某个数的一些位,只要将其,只要将其同另一个相应位为而其余位为的数进行同另一个相应位为而其余位为的数进行“ “与与” ”运算即可。运算即可。 99 91 1 位运算的类型位运算的类型按位按位“或或” ” l按位按位“或或”运算符运算符“|”|”是双目运算符,其功能是是双目运算符,其功能是参与运算的两数从低位到高位对应的位相或,参与运算的两数从低位到高位对应的位相或,“或或”操作规定为:操作规定为:0|00|0的结果为的结果为0 0,1|11|1、1|01|0及及0|10|1的结果都为的结果都为1 1。 109 91
7、1 位运算的类型位运算的类型按位按位“或或” 按位按位“ “或或” ”运算常用来对数据的某些位置运算常用来对数据的某些位置1 1。假设假设intint 型变量型变量a a的值为的值为2000020000,它对应的,它对应的1616位二位二进制数是进制数是01001110001000000100111000100000,表达式,表达式a|255a|255的的结果是变量结果是变量a a对应数值的低对应数值的低8 8位全置为位全置为1 1,高,高8 8位保位保留原样。如下式所示。留原样。如下式所示。 0100111000100000 (20000)0100111000100000 (20000)(
8、| ) 0000000011111111 (255) ( | ) 0000000011111111 (255) 0100111011111111 (20223) 0100111011111111 (20223) 从上例中可以看出,从上例中可以看出,如果要使某个数的一些如果要使某个数的一些位变成位变成1 1,可以让这些位按位与,可以让这些位按位与1 1进行进行“ “或或” ”运算,运算,其它位则分别与其它位则分别与0 0相相“ “或或” ”,保持不变,保持不变。 119 91 1 位运算的类型位运算的类型按位按位“异或异或” ” 按位按位“ “异或异或” ”运算符运算符“”“”是双目运算符,其功
9、能是是双目运算符,其功能是参与运算的两数从低位到高位对应位相参与运算的两数从低位到高位对应位相“ “异或异或” ”,“ “异或异或” ”运算规定:运算规定:1010和和0101的结果为的结果为1 1,1111和和0000的结果的结果为为0 0。 八进制数八进制数2222与与八进制数八进制数1313按位进行按位进行“ “异或异或” ”的算式如的算式如下所示。下所示。 00010010 (022)00010010 (022) 00001011 (013) 00001011 (013) 00011001 (031) 00011001 (031) 与与1 1进行进行“ “异或异或” ”运算的位将得到与
10、该位相反的值运算的位将得到与该位相反的值,即即10101 1,11110 0。与与0 0进行进行“ “异或异或” ”运算的位则保持运算的位则保持不变不变,即,即00000 0,01011 1。因此,。因此,“ “异或异或” ”运算可以运算可以方便地将数据的方便地将数据的某些位翻转某些位翻转,而其它位不变。,而其它位不变。 129 91 1 位运算的类型位运算的类型取反取反 取反运算符取反运算符“ “” ”是是单目运算符单目运算符,其功能是,其功能是对参与运算的数的各二进制位按位求反。例如:对参与运算的数的各二进制位按位求反。例如: 0000000010110010000000001011001
11、0 1111111101001101 1111111101001101139 91 1 位运算的类型位运算的类型左移左移 左移运算符左移运算符“ “”是双目运算符,它的功能是把是双目运算符,它的功能是把“ “ ” ”左边的运算数的各二进位整体左移若干位,左边的运算数的各二进位整体左移若干位,“ “”右边右边的数则指定移动的位数,左移过程中丢弃移出存储单元的的数则指定移动的位数,左移过程中丢弃移出存储单元的高位数据,低位补高位数据,低位补0 0。例如:。例如: 表达式表达式a4a”是双目运算符。其功能是把是双目运算符。其功能是把“ “ ” ”左边的运算数的各二进位全部右移若干位,左边的运算数的各
12、二进位全部右移若干位,“ “”右边的右边的数指定移动的位数。数指定移动的位数。 例如:设例如:设 a=15a=15,a2a2表示把表示把0000111100001111右移为右移为00000011(00000011(十进制十进制3)3)。 应该说明的是,应该说明的是,对于有符号数,在右移时,对于有符号数,在右移时,符号位将随同移动符号位将随同移动。当为正数。当为正数时,时, 高位补高位补0 0;而为负数时,高位是补;而为负数时,高位是补0 0或是补或是补1 1 取决于编取决于编译系统的规定。译系统的规定。Turbo CTurbo C和很多系统规定为补和很多系统规定为补1 1。 与左移运算对应的
13、,右移与左移运算对应的,右移n n位相当于连续除以位相当于连续除以n n个个2 2,而且在除而且在除2 2时,舍弃小数部分,作取整运算。时,舍弃小数部分,作取整运算。 正数不断右移结果是正数不断右移结果是0 0,负数不断右移结果是,负数不断右移结果是-1-1。159 92 2 位运算举例位运算举例 例例9-2 9-2 取一个整数取一个整数a a从右端开始的从右端开始的4 47 7位。位。 要取出要取出a a的的4 47 7位,可以使用按位位,可以使用按位与与运算,只要将运算,只要将a a与与00000000111100000000000011110000(十进制为(十进制为240240)按位与
14、即可,这样)按位与即可,这样(a&240)(a&240)的值中的值中4 47 7位保留位保留a a的原值,而其余位变成了的原值,而其余位变成了0 0,然后将,然后将(a&240)(a&240)的值右移的值右移4 4位即可。程序如下:位即可。程序如下:main()main() unsigned a, b; unsigned a, b; scanf(%uscanf(%u, &a);, &a); b=(a & 240)4; b=(a & 240)4; printf(printf( nana=%u, b=%d, a, b);=%u, b=%d, a, b); 169 92 2 位运算举例位运算举例在在
15、运运行行时输入入217217,则输出出为: 217217 a=217,b=13 a=217,b=13179 92 2 位运算举例位运算举例也可以这样考虑:也可以这样考虑:(1)(1)先将先将a a右移右移4 4位,使得位,使得4 47 7位挪到位挪到0 04 4位,这可位,这可以通过以通过a4a4做到;做到;(2)(2)设置一个低设置一个低4 4位全为位全为1 1,其余位全为,其余位全为0 0的数,可的数,可以用下面的方法做到:以用下面的方法做到: (0404a4)& &(040(16-n)b=a(16-n)(2 2)将)将b b的高的高16-n16-n位置位置0 0:b&b&(0n0n)(3
16、 3)将)将a a左移左移n n位,其右边位,其右边n n位自动补位自动补0 0:c=anc=a(16-n) b=a(16-n) b=b&( b=b&( ( 0n);0n); c=an; c=a1 a=161 b=16-(16111) 第第2 2种写法更有技巧性,运行效率更高,不过这种写种写法更有技巧性,运行效率更高,不过这种写法要注意左移右移时最高位和最低位的变化。法要注意左移右移时最高位和最低位的变化。289 94 4 总结与提高总结与提高 另外,在嵌入式系统编程中,常用位操作对另外,在嵌入式系统编程中,常用位操作对寄存器进行位设置,达到将其内容清零或屏蔽部寄存器进行位设置,达到将其内容清零或屏蔽部分位的作用。分位的作用。29下课啦。下课啦。休息下。休息下。30