• 微信号
  • 微信号
您当前的位置:首页 > 学海无涯 > 茑语花香>C语言位运算(按位与运算、或运算、异或运算、左移运算、右移运算)

C语言位运算(按位与运算、或运算、异或运算、左移运算、右移运算)

孤峰 C语言中文网 2023-06-15 174人阅读

所谓位运算,就是对一个比特(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

标签: