001 位运算

文章内容组成 = 大部分转载+自己思考

文章内容构成 = 是什么+怎么用+有什么用+优/缺点

转载部分http://www.cnblogs.com/911/archive/2008/05/20/1203477.html 

一:位运算是什么?

内存储存数据基本单位->字节(Byte),一个字节由8个位(bit)所组成。

位运算是->是按二进制位进行的运算, C语言提供了6个位操作。

运算符      描述
&按位与  : 若两个相应的二进制位都为1,则该位的结果值为1,否则为0
| 按位或  :  若两个相应的二进制位中只要有一个为1,该位的结果值为1
^按位异  : 若参加运算的两个二进制位值相同则为0,否则为1


~取反   : 是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0
<<左移   :   将一个数的各二进制位全部左移N位,右补0
>> 右移  :   将一个数的各二进制位全部右移N位,移到右端的低位被舍弃,对于无符号数,高位补0

二:位运算怎么用?

&运算

3&5 过程如下:

按位与运算过程:
 00000011(2)
&00000101(2)
 00000001(2)

|运算

48|15 过程如下:

  00110000
| 00001111
  00111111 

^运算

0∧0=0,0∧1=1,1∧0=1, 1∧1=0

~运算
将操作数各二进制位上的1变为0,0变为1。

<<运算
将一个数的各二进制位左移若干位,移动的位数由右操作数指定(右操作数必须是非负值),其右边空出的位用0填补,高位左移溢出则舍弃该高位。

例如:将a的二进制数左移2位,右边空出的位补0,左边溢出的位舍弃。若

a=15,即00001111(2),左移2位得00111100(2)。

>>运算
将一个数的各二进制位右移若干位,移动的位数由右操作数指定(右操作数必须是非负值),移到右端的低位被舍弃,对于无符号数,高位补0。

a的值是八进制数113755: 
   a:1001011111101101 (用二进制形式表示)
   a>>1: 0100101111110110 (逻辑右移时)
   a>>1: 1100101111110110 (算术右移时)

位运算赋值运算符

位运算符与赋值运算符可以组成复合赋值运算符。
例如: &=, |=, >>=, <<=, ∧=
例:  a & = b相当于 a = a & b     a << =2相当于a = a << 2
        

三:位运算有什么用

按位&:

作用:   (1) 目标数清零: 目标数 & 0 

      (2) 取目标数指定位: 目标数的指定位 & 指定位置为1    结果取出目标数的指定位

      (3) 保留目标数指定位: 目标数的指定位 & 指定位置为1  结果目标数保留指定位

(1)清零          

43 & 148过程
  00101011(2)
&10010100(2)
  00000000(2)

(2)取一个数中某些指定位
整数a(2byte)想要取其低字节,将a与8个1按位与即可。
a 00101100 10101100
b 00000000 11111111
c 00000000 10101100

(3)保留指定位:
数84想把从左边算起的第3,4,5,7,8位保留下来。
  01010100(2)
&00111011(2)
  00010000(2)

按位|:

作用:  (1) 目标数指定位置为1: 目标数 | 指定位置位1 

按位^:

作用:  (1) 目标数指定位反转: 目标数 ^ 指定位置位1 

       (2) 目标数指定位保留原值: 目标数 ^ 指定位置位0

按位~:

作用:    (1) 目标数指定位反转: 目标数 ~ 指定位置位1

具体应用:

判断一个变量i 是奇数还是偶数

if (i&1)

printf("奇数 ");

else

printf("偶数 ");

输入两个数,判断第一个数的第二数的位是不是1

scanf("%d", &i);
j = 2;
j = (i & 2) >> 1;   //将第0位变成0,第一位保留本身

printf("%d 第%d位是 %d ", i, 2, j);

int类型赋初值为十六进制3085CDCFB,将7-15位置为101011011

unsigned int i = 0x3085CDCFB;
unsigned int j = 0;

j = i & 0xFFFF007F; //将7到15位置为0

j = i | 0xFFFFADFF; //将7到15通过按位或,变成:101011011
printf("%d %d ", i, j);

// Result Display
140303611 -513

 

输入一个数,实现其低四位反转

scanf("%d", &i);
j = i;
i = i ^ 0xF;

printf("%d 低四位反转变为 %d ", j, i);

// Result Display
1
1 低四位反转变为 14
2
2 低四位反转变为 13
3
3 低四位反转变为 12
4
4 低四位反转变为 11

交换a、b两个值,不用临时变量

方法一:a = a ^ b;  b = a ^ b;  a = a ^ b;

方法二:a = a + b;  b = a - b;  a = a - b;

 

三:位运算优/缺点

缺点:

学习使用掌握比较麻烦

使用范围有限(这些运算符只能用于整型操作数)

位左右移动,可以溢出

优点:

位运算速度快

有时使用位运算比较方便计算

原文地址:https://www.cnblogs.com/huafan/p/4367615.html