位域是指信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几 个不同的区域, 并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。 这样就可以把几个不同的对象用一个字节的二进制位域来表示。


位域的定义

struct 位域名

{

    位域列表

};

其中位域列表的形式为: 类型说明符 位域名:位域长度


按位分解,如何分解,从高位到低位还是从低位到高位?看下面例子

wKioL1c343mRxl00AACAYEKe1B8304.png

运行结果:

   wKioL1c343mQA4adAAAULFi5GQg031.png

可以看出是从地位到高位分解的()

高位——————低位    高位——————低位

   10101110             10011110

   x4x3x2x1             x4x3x2x1

   

   

位域的几点说明

1. 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;

2. 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;

3.如果相邻的两个位域字段的类型不同,则各个编译器的具体实现有差异,VS2013采取不压缩方式,GCC采用压缩方式;

4. 整个结构体的总大小为最宽基本类型成员大小的整数倍。

5. 如果位域字段之间穿插着非位域字段,则不进行压缩;(不针对所有的编译器)

6.宽度为 0 的一个未命名位域强制下一位域对齐到其下一type边界,其中type是该成员的类型。


具体例子:

#include <stdio.h>
                                                                                
struct A
{      
      unsigned char x1:2;
      unsigned char x2:2;   
      unsigned char x3:2;
      unsigned char x4:2;   
}data1;
       
struct B
{      
        char a  : 6;
        int b  : 26; 
        char c  : 7;
}data2;
       
struct C
{      
        char a  : 6;  
        int b  : 30;  
        char c  : 7;  
}data3;
 
 struct D
{       
        char a  : 6;  
        int b  : 12;                                                            
        char c  : 7;  
}data4; 
        
struct E
{       
    char a:2;
    double i;
    int c:4;
}data5; 
        
struct F
{       
    char a:2;
    int c:4;
}data6; 

struct G
{       
    char a;                                                                     
    double i;
    int c;
}data7; 
        
struct Z 
{   
     char a : 2;
     int c : 4;
}ZZ;

union U 
{       
    int b;
    struct T
    {   
       char a : 2;
       int c : 4;
    }tmp;
}data8; 
        
int main()
{       
    printf("%d\n",sizeof(data1));
    printf("%d\n",sizeof(data2));
    printf("%d\n",sizeof(data3));
    printf("%d\n",sizeof(data4));                                                    
    printf("%d\n",sizeof(data5));
    printf("%d\n",sizeof(data6));
    printf("%d\n",sizeof(data7));
    printf("Z=%d\n",sizeof(ZZ));
    data8.b=183;
    printf("data8=%d\n",sizeof(data8));
    printf("tmp=%d\n",sizeof(data8.tmp));
    printf("c=%d,a=%d\n",data8.tmp.c,data8.tmp.a);
        
    return 0;
}

这是在gcc编译器运行的结果:

wKioL1c4csKAFAl5AAAKHRD5uvE734.png

这是在VS2013下运行的结果:

wKioL1c4c1fSLg0EAAALQm6P0D4074.png



还不错的一个博客:http://www.cnblogs.com/pure/archive/2013/04/22/3034818.html


<完>