C语言位运算(按位与运算、或运算、异或运算、左移运算、右移运算)
所谓位运算,就是对一个比特(Bit)位进行操作。在《数据在内存中的存储》一节中讲到,比特(Bit)是一个电子元器件,8个比特构成一个字节(Byte),它已经是粒度**小的可操作单元了。
C语言提供了六种位运算符:
9 & 5可以转换成如下的运算:0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001(9 在内存中的存储)
& 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101(5 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001(1 在内存中的存储)
-9 & 5可以转换成如下的运算:1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111(-9 在内存中的存储)
& 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101(5 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101(5 在内存中的存储)
-9 & 5
的结果是 5。
关于正数和负数在内存中的存储形式,我们已在VIP教程《整数在内存中是如何存储的,为什么它堪称天才般的设计》中进行了讲解。
-9&5为例,-9 的在内存中的存储和 -9 的二进制形式截然不同:1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111(-9 在内存中的存储)
-0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001(-9 的二进制形式,前面多余的 0 可以抹掉)
n & 0XFFFF运算(0XFFFF 在内存中的存储形式为 0000 0000 -- 0000 0000 -- 1111 1111 -- 1111 1111)。【实例】对上面的分析进行检验。
#include <stdio.h>
int **in(){
int n = 0X8FA6002D;
printf("%d, %d, %X\n", 9 & 5, -9 & 5, n & 0XFFFF);
return 0;
}
运行结果:
1, 5, 2D
9 | 5可以转换成如下的运算:0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001(9 在内存中的存储)
| 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101(5 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1101(13 在内存中的存储)
9 | 5
的结果为 13。又如,-9 | 5
可以转换成如下的运算:
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111(-9 在内存中的存储)
| 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101(5 在内存中的存储)
-----------------------------------------------------------------------------------
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111(-9 在内存中的存储)
-9 | 5
的结果是 -9。 按位或运算可以用来将某些位置 1,或者保留某些位。例如要把 n 的高 16 位置 1,保留低 16 位,可以进行n | 0XFFFF0000
运算(0XFFFF0000 在内存中的存储形式为 1111 1111 -- 1111 1111 -- 0000 0000 -- 0000 0000)。
【实例】对上面的分析进行校验。
#include <stdio.h>
int **in(){
int n = 0X2D;
printf("%d, %d, %X\n", 9 | 5, -9 | 5, n | 0XFFFF0000);
return 0;
}
运行结果:
13, -9, FFFF002D
9 ^ 5可以转换成如下的运算:0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001(9 在内存中的存储)
^0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101(5 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1100(12 在内存中的存储)
9 ^ 5
的结果为 12。又如,-9 ^ 5
可以转换成如下的运算:
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111(-9 在内存中的存储)
^0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0101(5 在内存中的存储)
-----------------------------------------------------------------------------------
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0010(-14 在内存中的存储)
-9 ^ 5
的结果是 -14。 按位异或运算可以用来将某些二进制位反转。例如要把 n 的高 16 位反转,保留低 16 位,可以进行n ^ 0XFFFF0000运算(0XFFFF0000 在内存中的存储形式为 1111 1111 -- 1111 1111 -- 0000 0000 -- 0000 0000)。
【实例】对上面的分析进行校验。
#include <stdio.h>
int **in(){
unsigned n = 0X0A07002D;
printf("%d, %d, %X\n", 9 ^ 5, -9 ^ 5, n ^ 0XFFFF0000);
return 0;
}
运行结果:
12, -14, F5F8002D
~9可以转换为如下的运算:~ 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001(9 在内存中的存储)
-----------------------------------------------------------------------------------
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0110(-10 在内存中的存储)
~-9可以转换为如下的运算:~ 1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111(-9 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1000(8 在内存中的存储)
~-9的结果为 8。【实例】对上面的分析进行校验。
#include <stdio.h>
int **in(){
printf("%d, %d\n", ~9, ~-9 );
return 0;
}
运行结果:
-10, 8
9<<3可以转换为如下的运算:<< 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001(9 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0100 1000(72 在内存中的存储)
(-9)<<3可以转换为如下的运算:<< 1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111(-9 在内存中的存储)
-----------------------------------------------------------------------------------
1111 1111 -- 1111 1111 -- 1111 1111 -- 1011 1000(-72 在内存中的存储)
所以(-9)<<3的结果为 -72
如果数据较小,被丢弃的高位不包含 1,那么左移 n 位相当于乘以 2 的 n 次方。
【实例】对上面的结果进行校验。
#include <stdio.h>
int **in(){
printf("%d, %d\n", 9<<3, (-9)<<3 );
return 0;
}
运行结果:
72, -72
9>>3可以转换为如下的运算:>> 0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 1001(9 在内存中的存储)
-----------------------------------------------------------------------------------
0000 0000 -- 0000 0000 -- 0000 0000 -- 0000 0001(1 在内存中的存储)
(-9)>>3可以转换为如下的运算:>> 1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 0111(-9 在内存中的存储)
-----------------------------------------------------------------------------------
1111 1111 -- 1111 1111 -- 1111 1111 -- 1111 1110(-2 在内存中的存储)
(-9)>>3的结果为 -2 如果被丢弃的低位不包含 1,那么右移 n 位相当于除以 2 的 n 次方(但被移除的位中经常会包含 1)。【实例】对上面的结果进行校验。
#include <stdio.h>
int **in(){
printf("%d, %d\n", 9>>3, (-9)>>3 );
return 0;
}
运行结果:
1, -2
转载:感谢您阅览,转载请注明文章出处“来源从小爱孤峰知识网:一个分享知识和生活随笔记录的知识小站”。
链接:C语言位运算(按位与运算、或运算、异或运算、左移运算、右移运算)http://www.gufeng7.com/niaolang/360.html
联系:如果侵犯了你的权益请来信告知我们删除。邮箱:119882116@qq.com
上一篇: 使用位运算对数据或文件内容进行加密
下一篇: C语言位域(位段)详解