C语言 位域



  • 位域

    假设您的C程序包含许多TRUE/FALSE变量,这些变量按称为status的结构体分组,如下所示-
    
    struct {
       unsigned int widthValidated;
       unsigned int heightValidated;
    } status;  
    
    
    这种结构需要8个字节的存储空间,但实际上,我们将在每个变量中存储0或1。在这种情况下,C编程语言提供了一种更好的利用内存空间的方法。如果在结构内部使用此类变量,则可以定义变量的宽度,该宽度告诉C编译器您将仅使用那些字节数。例如,上面的结构可以重写如下:
    
    struct {
       unsigned int widthValidated : 1;
       unsigned int heightValidated : 1;
    } status;  
    
    
    上面的结构需要4个字节的存储空间用于status变量,但是只有2位将用于存储值。如果最多使用32个变量,每个变量的宽度为1位,则status结构也将使用4个字节。但是,一旦有了33个变量,它将分配内存的下一个插槽,并开始使用8个字节。让我们检查以下示例以了解概念-
    
    #include <stdio.h>
    
    #include <string.h>
    
    /* define simple structure */
    struct {
       unsigned int widthValidated;
       unsigned int heightValidated;
    } status1;
    
    /* define a structure with bit fields */
    struct {
       unsigned int widthValidated : 1;
       unsigned int heightValidated : 1;
    } status2;
     
    int main( ) {
       printf( "Memory size occupied by status1 : %d\n", sizeof(status1));
       printf( "Memory size occupied by status2 : %d\n", sizeof(status2));
       return 0;
    }
    
    
  • 位域声明

    位域的声明在结构内部具有以下形式-
    
    struct {
       type [member_name] : width ;
    };  
    
    
    下表描述了位域的变量元素-
    • type - 一个整数类型,用于确定如何解释位字段的值。type可以是int,signed int或unsigned int。
    • member_name - 位字段的名称。
    • width - 位字段中的位数。该宽度必须小于或等于指定类型的位宽度。
    用预定义宽度定义的变量称为位域。一个位域可以容纳一个以上的位;例如,如果您需要一个变量来存储从0到7的值,则可以定义一个宽度为3位的位字段,如下所示:
    
    struct {
       unsigned int age : 3;
    } Age;
    
    
    上面的结构体定义指示C编译器Age变量将仅使用3位来存储值。如果您尝试使用3个以上的位,则将不允许您这样做。让我们尝试以下示例-
    
    #include <stdio.h>
    
    #include <string.h>
    
    struct {
       unsigned int age : 3;
    } Age;
    
    int main( ) {
    
       Age.age = 4;
       printf( "Sizeof( Age ) : %d\n", sizeof(Age) );
       printf( "Age.age : %d\n", Age.age );
    
       Age.age = 7;
       printf( "Age.age : %d\n", Age.age );
    
       Age.age = 8;
       printf( "Age.age : %d\n", Age.age );
    
       return 0;
    }
    
    
    编译上面的代码时,将编译警告,执行时,将产生以下结果-
    
    Sizeof( Age ) : 4
    Age.age : 4
    Age.age : 7
    Age.age : 0