c语言中位段

来源:互联网 发布:xboxone有线网络设置 编辑:程序博客网 时间:2024/06/10 04:48
位段以位为单位定义结构体(或共用体)中成员所占存储空间的长度。
 含有位段的结构体类型称为位段结构。

位段结构也是一种结构体类型,只不过其中含有以位为单位定义存储长度的整数类型位段成员。采用位段结构既节省存储空间,又可方便操作。

位段结构中位段的定义格式为:
         unsigned <成员名>:<二进制位数>
例如:
struct bytedata
{unsigned a:2;   /*位段a,占2位*/
 unsigned:6;  /*无名位段,占6位,但不能访问*/
 unsigned:0;     /*无名位段,占0位,表下一位段从下一字边界开始*/
 unsigned b:10;  /*位段b,占10位*/
 int i;          /*成员i,从下一字边界开始*/
}data;

位段数据的引用:
同结构体成员中的数据引用一样,但应注意位段的最大取值范围不要超出二进制位数定的范围,否则超出部分会丢弃。
例如:data.a=2;   但  data.a=10;就超出范围(a占2位,最大3)

关于位段数据,注意以下几点:

(1)一个位段必须存储在同一存储单元(即字)之中,不能跨两个单元。如果其单元空间不够,则剩余空间不用,从下一个单元起存放该位段。
(2)可以通过定义长度为0的位段的方式使下一位段从下一存储单元开始。
(3)可以定义无名位段。
(4)位段的长度不能大于存储单元的长度。许多编译器把位段成员的字长限制在一个int的长度范围之内;
(5)位段无地址,不能对位段进行取地址运算。
(6)位段可以以%d,%o,%x格式输出。
(7)位段若出现在表达式中,将被系统自动转换成整数

1、位段成员只有三种类型,int,unsigned int 和 signed int 这三种,位段使用unsigned int或者unsigned声明,二者是等价的,这里定义unsigned int的意思是开辟一个整形数据空间,然后分配给位段a 2个二进制位

2、位段成员的内存分配
例1、
struct test1 {
   unsigned f1:1;
   unsigned f2:1;
   unsigned f3:1;
   unsigned type:4;
   unsigned index:9;
}:
该结构体定义了五个成员,第一个成员f1,时unsigned
类型,紧跟在该成员之后的:1规定了它以1位存放,类似的,标志f2和f3被定义为长

度只有1位,定义成员type占有4位,成员index占有9位。c编译器自动的把上面的位段定义压缩在一起。位段划分如图所示。



在深入的讨论一下位段,如果使用下面的结构定义:
struct test2 {
    unsigned f1:1;
    int word;
    unsigned f2:1;
};

那么,位段时怎么样被压缩的呢?由于成员word的出现,故f1,f2不会压缩在同一个字内,c编译器不会重新安排位段定义来试图优化存储空间。如图:



可以指定无名位段,使得一个字中的某些位被“跳过”,因此定义
strcut test3 {
    unsigned type:4;
    unsigend :3;
    unsigend cout :9;
};

定义一个结构体test3,它包含两个位段变量type和cout,而无名位段规定了tyoe和cout间隔三位。如图:



定义位数为0的无名位段.
struct test3 {
    unsigend f1:1;
    unsigned :0;
    unsigned f2:1;
};

定义一个结构体test4,它包含两个位段变量f1和f3,而无名位段规定了f1和f3间隔4个字节。如图:




有位段时的对齐规则是这样:同类型的、相邻的可连续在一个类型的存储空间中存放的位段成员作为一个该类型的成员变量来对待,不是同类型的、相邻的位段成员,分别当作一个单独得该类型的成员来对待,分配一个完整的类型空间,其长度为该类型的长度,其他成员的分配规则不变,仍然按照前述的对齐规则进行。

原创粉丝点击