C語言位域淺析


   位段(bit-field)是以位為單位來定義結構體(或聯合體)中的成員變量所占的空間。含有位段的結構體(聯合體)稱為位段結構。采用位段結構既能夠節省空間,又方便於操作。

     位段的定義格式為:

     type  [var]: digits

      其中:

      type只能為int,unsigned int,signed int,char, unsigned char 五種類型之一,digits表示該位段所占的二進制位數

  位段長度digits不能超過類型type對應的數據類型占用的大小,如若type為char,則digits不能超過8,為int則digits不能超過32

      位段名稱var是可選參數,可以省略

     一、位域的定義

  位域定義與結構體定義相仿,其形式為: 
  struct 位域結構名 
  {

    位域列表

   }; 
  其中位域列表的形式為: type  [var]: digits

  例如:

 1 struct data{     
 2 
 3     int a : 32;          //位段a,占32位
 4 
 5     char b : 5;             //位段b,占5位
 6 
 7     char c : 2;            //位段c,占2位,和b存儲在同一個字節
 8 
 9     unsigned char : 6;          //無名位段,占6位
10 
11 };

注:位域可以無位域名,這時它只用來作填充或調整位置,無名的位域不能被訪問

  二、位段的使用

    位域的使用和結構成員的使用相同,其一般形式為:位域變量名·位段名,也可定義一個指向位域的指針p,然后p->位段名使用,使用時需要注意:

    ①不能對位段進行取地址操作

    ②若位段占的二進制位數為0,則這個位段必須是無名位段,下一個位段從下一個位段存儲單元開始存放

    ③若位段出現在表達式中,則會自動進行整型升級,自動轉換為int型或者unsigned int

    ④對位段賦值時,最好不要超過位段所能表示的最大范圍,否則可能會造成意想不到的結果

  三、位段在內存中的存儲模式

    使用位域的主要目的是壓縮存儲,其大致規則為:

  1) 如果相鄰位域字段的類型相同,且其位寬之和小於類型的sizeof大小,則后面的字段將緊鄰前一個字段存儲,直到不能容納為止;

  2) 如果相鄰位域字段的類型相同,但其位寬之和大於類型的sizeof大小,則后面的字段將從新的存儲單元開始,其偏移量為其類型大小的整數倍;

  3) 如果相鄰的位域字段的類型不同,則各編譯器的具體實現有差異,經實驗VC采取不壓縮方式,即即使前一個字段有空余位足夠容納后一個字段,后一個字段也當前一個字段           沒有空余位,從前一個字段類型大小之后的新字節開始存儲;

  4) 如果位域字段之間穿插着非位域字段,則不進行壓縮;

  5) 整個結構體的總大小為最寬基本類型成員大小的整數倍。:

 

  測試程序如下,環境vs3013,cfree 5.0

#include <stdio.h>

#include <stdlib.h>

struct data{     

    int a : 20;          //位段a,占20位

    char b : 3;             //位段b,占3位,不會和a壓縮存儲

    char : 0;           //無名位段

    unsigned char c : 5;  //位段c,占5位
};
int main()

{
    data test;
    data *ptest;
    ptest = &test;
    //兩種方式訪問位段
    test.a = 20;
    ptest->b = 5;

    //vc不壓縮存儲,占用8個字節,為其最寬基本類型成員大小的整數倍
    printf("sizeof(data): %d\n",sizeof(data));

    //test.b在輸出時自動轉化為整型,5(101)高位為1,擴展時高位連續補1,值為-3
    printf("test.a = %d\t test.b = %d\n",test.a, ptest->b);

    system("pause");
    return 0;

}

 

運行結果為:

sizeof(data): 8
test.a = 20 test.b = -3

 

  參考:

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

  http://blog.sina.com.cn/s/blog_3d8529400100istl.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM