位段(bit-field)

一、位段结构

struct node
{
    unsigned int a:4;     //位段a,占4位
    unsigned int  :0;     //无名位段,占0位
    unsigned int b:4;     //位段b,占4位
    int c:32;             //位段c,占32位
    int  :6;              //无名位段,占6位
    char g;
};

二、位段的使用

使用位段需注意一下几点:

    1)位段的类型只能是int,unsigned int,signed int三种类型,不能是char型或者浮点型;

    2)位段占的二进制位数不能超过该基本类型所能表示的最大位数,比如在VC中int是占4个字节,那么最多只能是32位;

    3)无名位段不能被访问,但是会占据空间;

    4)不能对位段进行取地址操作

    5)若位段占的二进制位数为0,则这个位段必须是无名位段,下一个位段从下一个位段存储单元开始存放;

    6)若位段出现在表达式中,则会自动进行整型升级,自动转换为int型或者unsigned int。

    7)对位段赋值时,最好不要超过位段所能表示的最大范围,否则可能会造成意想不到的结果

    8)位段不能出现数组的形式。

三、位段内存中存储方式

对于位段结构,编译器会自动进行存储空间的优化,主要有这几条原则:

   1)如果一个位段存储单元能够存储得下位段结构中的所有成员,那么位段结构中的所有成员只能放在一个位段存储单元中,不能放在两个位段存储单元中;如果一个位段存储单元不能容纳下位段结构中的所有成员,那么从剩余的位段从下一个位段存储单元开始存放。

   2)如果一个位段结构中只有一个占有0位的无名位段,则只占1或0字节的空间(C语言中是占0字节,而C++中占1字节);否则其他任何情况下,一个位段结构所占的空间至少是一个位段存储单元的大小;

四、位段使用实例

eg 1:

/*测试位段*/ 
#include<stdio.h>

typedef struct node
{
    unsigned int a:1;      //存在一个非0位的位段,则至少占4Byte 
}S; 

typedef struct node1       //在C++中占1字节的空间 ,在C中占0字节 
{
    unsigned int :0;
}S1;

typedef struct node2
{
    unsigned int a:1;
    unsigned int  :0;     //下一个位段放在一个新的位段存储单元 ,所以占4+4=8Byte 
    unsigned c:32;         
}S2;

typedef struct node3
{
    unsigned int a:4;
    unsigned int  :0;
    int :6;               //这个位段放在一个新的位段存储单元 
    unsigned c:32;        //由于6+32>32,所位段c也放在一个新的位段存储单元,所以占4+4+4=12Byte 
}S3;

typedef struct node4  
{
    int a:1;
    char b;                //在一个位段存储单元中能够存下所有的成员,所以占4Byte 
    int c:1;
    unsigned int d:2;
    unsigned int e:2;
}S4;


int main(int argc, char *argv[])
{
    S4 s4;
    s4.a=1;
    s4.c=1;
    s4.d=2;              
    s4.e=3;
    printf("%d %d %d %d\n",s4.a,s4.c,s4.d,s4.e);
    printf("%d %d %d %d %d\n",sizeof(S),sizeof(S1),sizeof(S2),sizeof(S3),sizeof(S4));
    return 0;
}

OUTPUT:

注意仔细思考:为什么输出结果为 -1 -1 2 3 ????

想想上一篇博客提到的符号位扩展的问题。(若位段出现在表达式中,会自动进行整型升级)

由于c只占用1位,没有数据位,直接进行符号位扩展,高位添1,

(1111  1111  1111  1111  1111  1111  1111  1111)补    -》 (ox FF FF  FF FF FF FF FF FF)补    -》  (ox 80 00 00 00 00 00 00 01)原    -》 (-1)真值

eg 2:

struct test{
  int a:1;
  int b:1;
  int c:1;
}

void main()
{
  test t;
  t.a = 1;
  t.b = 0;
  t.c = -1;
  
  printf("%d,%d,%d,%d",t.a,t.b,t.c,sizeof(t));
}

OUTPUT:

-1,0,-1,4


备注:

参考链接:

http://www.cnblogs.com/dolphin0520/archive/2011/10/14/2212590.html

http://blog.csdn.net/andy205214/article/details/4975636

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值