1、第十二章 位运算,位运算是指进行二进制位的运算,即对字节或字节内部的二进制位进行运算。计算机中是以补码形式存放数的.正数: 原码,反码,补码相同.负数的补码: 符号位不变,数值位按位取反加1 如: + 7:- 7 :,00000111,11111001,一.位运算符,参加位运算数据类型:有符号和无符号的整型数(包括:char、short int、 long unsigned) 位运算符共 6 种:& | 1. (按位取反运算符)作用: 对一个二进制数逐位取反。注意: 运算和 ! 运算的区别。 的优先级与+、-、 ! 同级。结合性从右至左。,如: a=15则 a例12.1 main( ) int
2、 a=0,b=1;printf (“ %d,%d n”, a ,b ) ; printf (“ %d,%d n”, !a , !b ) ; 运行结果: -1 , -21 , 0,00000000,00001111,11111111,11110000,a, a,00000000,00000000,11111111,11111111,0,0,2. 输出: 5&12 = 4此例说明: a , b 两个操作数参加 & 运算前后,其值不变。,00000001,00000000,11111110,11111111,00000000,00000000,a,b,a&b,3. | (按位或运算)作用: 对参加运
3、算的两个二进制数逐位进行逻辑或 运算。如: a | b规则: 0 | 0 = 0 , 1 | 0 = 1 , 0 | 1 = 1 , 1 | 1 = 1例如: a = 1 , b = -1 , 则: a | b = -1.,00000001,00000000,11111111,11111111,11111111,11111111,a,b,a|b,4. (按位异或运算)作用: 对参加运算的两个二进制数逐位进行逻辑 异 或运算.如: ab规则: 00 = 0 , 10 = 1 , 01 = 1 , 11 = 0 例如: a=15, b=0, 则: ab=15,00001111,00000000,0
4、0000000,00000000,00001111,00000000,a,b,ab,例 : main ( ) int a = 3 , b = 4 ;a=ab; b=ba;a=ab;printf(“%d,%d”,a,b); 输出: 4, 3结论: 利用异或运算,可以设置第三个变量就可以 实现 两个整型变量值的交换。,00000011,00000000,00000100,00000000,00000111,00000000,a,b,a,00000011,00000000,b,00000100,00000000,a,5. (左移位运算)作用: 将操作数的各个二进位顺序左移。右端空出的位补 0,而移出
5、左端之外的位则舍去。如: a n表示将a 的各个二进位顺序左移 n 位( n 为正整数)。 例如: a = 25 则 a3 结果为 200,00011001,00000000,11001000,00000000,a,a3,说明: (1) 左移运算相当于乘 2 运算。 对无符号数,左移 1 位,相当于乘 2 。左移 n 位,则乘 2n 。(2) 对于用补码表示的正数,如果左移出的全部是 0 ,且移出后的最高位仍是0。(3) 对于用补码表示的负数,如果左移出的全部是 1,且移出后的最高位仍是 1 。如:,11111110,11111111,11110000,11111111,-2,- 2 3,00
6、001111,00000000,按位取反取负号转换为10进制再减1 得-16,按位取反取负号再加1 转换为10进制得-16,(4) 若非上述情况 ( 如:左移出现溢出时),就不能简单地用 乘 2 来计算. 如: 有符号字符型数 64 , 当它左移 2 位时,结果为 0 。,01000000,64,00000000,64 2,6. (右移运算符)作用: 将操作数的各个二进位顺序右移。左端空出的位补0 或补 1,而移出右端之外的位则舍去.如: a n 表示将 a 的各个二进位顺序右移 n 位说明: 右移运算的结果与操作数的符号有关1) 对无符号数进行右移,左端空出的位一律补 0 。2) 对用补码表
7、示的有符号数,则随系统而定。“逻辑右移”空位一律补 0 ;“算术右移”正数右移,空位补 0; 负数右移, 空位补1 。(Turbo C中采用算术右移),例如: a = - 32768,00000000,10000000,00000000,01000000,00000000,11000000,a,a 1,a 1,逻辑右移, 结果为 16384,算术右移, 结果为-16384,算术右移运算相当于除 2 运算。右移 1 位,相当于除 2 。右移 n 位 ,则除 2n 。,二. 1. 位运算符的优先级结合性: 运算按从右至左 , 其余按从左至右例: x & 077 x & ( 077) x 2 & y
8、 2 )& (y = 如: a&=b a=a&ba=m+1 a=am+1,& |,高,低,三. 位运算的应用 例12.1 将整数 x 的后 6 位全置 0 , 其余位不变。取 y= 077 ( 八进制数 )则 x如输入: 256 输出为: x = 400 ( 8 进制 ) 同样,如需将 x 的后 6位全置 1 , 则只需将x = x | 077 即可.,00000000,00111111,11111111,11000000,077, 077,00000001,00000000,256,00000001,00000000,例12.2 取一整数a从右端开始的47位。(1) 先使 a 右移 4 位a
9、 ( 7 4 + 1 ) 即 a 4 (2) 设置一个低 4位全为 1,其余位全为 0 的数. ( 0 4 & ( 0 4 ),15,8,7,4,0,main( ) unsigned a,b,c,d;scanf(“%o”, 如输入: 331 输出为: 331 15 结论: 任意指定从右端 m 位 开始,取其右面的 n 位。只需: b=a(mn+1) c=(0n) d=b&c,11110000,11111111,00000000,00001111,例12.3 将一个整数a循环右移 n 位。所谓循环右移是将 a 最右端的位顺序移到a的最左端,而将 a中原左端的各位顺序右移到最右端。,1 0 0 0
10、 1 0 0 1,右移 2 位,0 1 1 0 0 0 1 0,(1) 将 a 左移 16 n 位并存入变量 b 中,这样 b 中最左端的n位就是原 a 最右端的 n 位。而 b 中最右端(16 n )位全为 0 。b=an (3) 将 c 与 b 按位或运算c=c|b 0|0=0,1|0=1,11011111,10101011,01100000,00000000,a,b,00011011,11110101,c,01111011,11110101,c,main( ) unsigned a,b,c; int n;scanf(“%o,%d”, 如输入: 157653 , 3 输出为: 15765375765同样可以实现循环左移.,11011111,10101011,01111011,11110101,