位域运算符

目录

位域的定义和位域变量的说明

对于位域的定义尚有以下几点说明

位域的使用

无符号和有符号的区别


        首先援引百度来的简单引题:“有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1两种状态,用1位二进位即可。为了节省存储空间并使处理简便,C语言又提供了一种数据结构,称为"位域"或"位段"。”从这段话可以看出,位域的概念是来自于C语言的。而其目的是为了节省内存空间。位域在本质上就是一种结构类型,不过其成员是按二进位分配的。

位域的定义和位域变量的说明

        所谓"位域"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。从这段话可以读出,位域中的位指的是二进位,或者可以理解成比特,而非我们最常见的字节。

        位域定义与结构定义相仿,其形式为:

        其中位域列表的形式为:“类型说明符位域名: 位域长度”,例如:

        表示:data为bs变量,共占两个字节(=8+2+6),其中位域a占8位,位域b占2位,位域 c 占6位。

        再举例说明:

         如上,我定义了一个结构位域,一个结构体。那么检查他们所占用内存的大小发现:

         通过对这个分析,就可以看出结构位域是个怎么玩法了:

        首先,我在结构体位域里面,设定了两个int类型的1比特,按理说我测量data1的时候,我真正使用的也就两个比特啊,为啥一下子测出data1所占用的空间是4个字节(32个比特),再对比前面的记述,就可以得出位域的运行规则了,在data1中,我真正使用的就2个比特,剩下的30个比特我是不用的,但内存分配内存的时候,是按类型来给内存的,我设置了一个int类型,默认的就是分配4个字节给我用,虽然我用不着这么多,但也得这么分。所以,当我测算data1所占的内存大小的时候,还是4个字节,这里需要强调的是,此位域中我相当于占了一个int类型所分配的内存数量的前两个比特位。剩下的没用,就空在那了。

对于位域的定义尚有以下几点说明

        1.一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域(即如果当前的这个字节不够放一个位域,那就把当前剩下的空间给空着,然后,从下一个字节开始存放这个位域)。也可以有意使某位域从下一单元开始。例如:

         在这个位域定义中,一个int类型一共4个字节(32位的比特),a占第一字节的4位,后28位填0表示不使用,b从第二int类型开始,占用4位,c占用4位。

        从内存的角度描述就是,首先定义了一个bs1类型的data1变量,计算机先扫描这个变量所有的语句,以好给它分配内存空间,其先扫描到第一句,发现这是个位域的结构,就明白了,给其分配一个int类型的所占用空间的长度,再从头往后分,将这个a变量所占据的内存空间(4比特)放到最开头,接着,发现一个没指明所变量名但要求分28个比特的长度的变量,计算机明白,这是想把当前这个int类型所分的32个比特位给填满了,好一会儿再开一个其他类型的空间,存放其他变量。再然后,定义了一个变量b,也指明了只分4个比特,计算机看到b的类型是int,就知道了,再给它分配int长度的空间,让他们再去分,所以,后面来的b变量和c变量就都在第二次新分的int类型的内存空间中存着,剩下用不完的部分,就在那空着,弄完这个后,这个data1变量总共所占用的长度就是8个字节了(即64个比特)。

         2. 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8位二进位。

        如果最大长度大于计算机的整数字长,一些编译器可能会允许域的内存重叠,另外一些编译器可能会把大于一个域的部分存储在下一个字中。

        3. 位域可以是无名位域,这时它只用来作填充或调整位置。无名的位域是不能使用的(如上面的第10行,就是个无名位域)。

位域的使用

        位域的使用和结构成员的使用相同,其一般形式为:

        位域变量名.位域名

        位域指针名->位域名

        其中,位域允许用各种格式输出。

         运行结果:

        如上,变量将只使用4位(位域指定的长度)来存储这个值,如果您试图使用超过4位,则无法完成。当指定数值输入到8的时候,就不行了,说明,预留的是4位,但只能满足第一位为0的情况。

无符号和有符号的区别

        在上面的例子中的,但我输入8的时候,明明二进制转换应位1000,还是属于四位比特的范围,却带了一个负号,这是为啥呢?这就牵扯到有符号整型和无符号整型的区别了!

        简单点说就是,int类型的16个比特位,第一个比特位是被符号位所占的,表示符号,不表示数值,但是,在位域这里第一位貌似既表示符号,又表示数值了(这就是为啥上面int类型调用的时候,出现的值是-8,而非8了,这是因为输入的8,转换位二进制为1000,那第一位是符号位,1表示负,故输出就为负了!

        在探究的具体些:

        在计算机中,整数是以原码的形式存储的,而负数是以补码的形式存储的,原码大家都知道也就是它对应的二进制码,那什么是补码呢,就是原码的反码加1,反码就是原码的各位取反,例如-1的补码是:

        首先1的原码是:00000 00000001

        其次取它的反码是:1111111 11111110

        最后在其反码的基础上加上1:1111111 11111111

        得到-1的补码是:1111111 11111111

        从上可以看出,int用15位来表示一个数字,第1位被符号位占用了,其实大家应该不难看出在数学中-1是负数中最大的整数,所以这里看到它的各个位都置1,对应于二进制来讲就是最大的数了,计算机就是按照符号位来识别该数是正是负,所以第一位只起到标识的作用并不作为数据位来使用,而其余的15位才是真正的数据位。以补码的形式来存储有个好处那就是计算机将负数的运算当作加法来处理了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值