程序中的所有数在计算机内存中都是以二进制的形式储存的。位运算说穿了,就是直接对整数在内存中的二进制位进行操作。比如,and运算本来是一个逻辑运算符,但整数与整数之间也可以进行and运算。举个例子,6的二进制是110,11的二进制是1011,那么6 and 11的结果就是2,它是二进制对应位进行逻辑运算的结果(0表示False,1表示True,空位都当0处理)。
位运算种类
C语言中提供了六种位运算,具体运算符如下:
位与运算
位于运算符号:&,这是一个双目运算符,功能是把两个参与运算的操作数按照二进制位与,规则是都为1的时候为1,有一个为0就为0.参与运算的数是以补码出现的。
例如:4&5就可以写成下面的形式:
00000100
&
00000101 = 00000100 = 4
位与运算的一个主要用途就是把某些位清零或者保留某些位,比如我们需要把某一个数保留低八位,前面的都清零,我们知道我们需要这样的一个二进制数:
0000 0000 0000 0000 0000 0000 1111 1111
那么以这个二进制为补码的十进制数是多少呢?算一算是255.
我们给出一个数640
它的二进制补码为:
0000 0000 0000 0000 0000 0010 0100 0000
那么结果该为:128 0000 0000 0000 0000 0000 0000 0100 0000
那么我们来看一个例子,创建bin_and.c编辑如下:
位或运算
位或运算的运算符为“|”,方法是参与运算的操作数对应的位上的二进制相或,规则是有1就为1,全零才为0,同样操作数依然是以补码运算的。
例如:
255 | 640
0000 0000 0000 0000 0000 0000 1111 1111
|
0000 0000 0000 0000 0000 0010 0100 0000
=
0000 0000 0000 0000 0000 0010 1111 1111
=767
功能显然是可以补1,我们看例子把上面的计算用程序实现一下,创建bin_or.c编辑如下:
异或、求反、左移、右移
下面的运算和上面的大同小异,在这里我们简单介绍:
位异或运算符号:^ 参与运算的操作数对应为相同时为1,不同时为0,同样以补码形式
位求反运算符号:~ 这是一个单目运算符 具有右结合性,功能对操作数按位取反,同样以补码形式
位左移运算符:<< 这也是单目运算,是将操作数的所有位向左移
位右移运算符:>> 这也是单目运算,是将操作数的所有位向右移
我们来看一个例子,我们拿一个数255我们先把它取反
0000 0000 0000 0000 0000 0000 1111 1111
取反后;
1111 1111 1111 1111 1111 1111 0000 0000
= -256
我们再把它向右移5位,结果应为
0000 0111 1111 1111 1111 1111 1111 1000
是-8
我们创建文件bin_mv.c编辑如下:
位域
位域是指信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几 个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。
与结构定义相仿,其形式为:
struct 位域结构名
{ 位域列表 };
其中位域列表的形式为: 类型说明符 位域名:位域长度
例如:
struct bs
{int a:8;int b:2;int c:6;};
在这里这个我们也不多说了,有兴趣的朋友可以来信我们交流。