淺談C語言中的位段

來源:互聯網
上載者:User

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

位段的定義格式為:

type  [var]: digits

其中type只能為int,unsigned int,signed int三種類型(int型能不能表示負數視編譯器而定,比如VC中int就預設是signed int,能夠表示負數)。位段名稱var是選擇性參數,即可以省略。digits表示該位段所佔的二進位位元。

   那麼定義一個位段結構可以像下面這段代碼去定義:

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位
};

 

一.位段的使用

    使用位段需注意一下幾點:

    1)位段的類型只能是int,unsigned int,signed int三種類型,不能是char型或者浮點型;

2)位段占的二進位位元不能超過該基本類型所能表示的最大位元,比如在VC中int是佔4個位元組,那麼最多隻能是32位;

    3)無名位段不能被訪問,但是會佔據空間;

    4)不能對位段進行取地址操作;

    5)若位段占的二進位位元為0,則這個位段必須是無名位段,下一個位段從下一個位段儲存單元(這裡的位段儲存單元經測試在VC環境下是4個位元組)開始存放;

    6)若位段出現在運算式中,則會自動進行整型升級,自動轉換為int型或者unsigned int。

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

    8)位段不能出現數組的形式。

二.位段結構在記憶體中的儲存方式

    對於位段結構,編譯器會自動進行儲存空間的最佳化,主要有這幾條原則:

   1)如果一個位段儲存單元能夠儲存得下位段結構中的所有成員,那麼位段結構中的所有成員只能放在一個位段儲存單元中,不能放在兩個位段儲存單元中;如果一個位段儲存單元不能容納下位段結構中的所有成員,那麼從剩餘的位段從下一個位段儲存單元開始存放。(在VC中位段儲存單元的大小是4位元組).

   2)如果一個位段結構中只有一個佔有0位的無名位段,則只佔1或0位元組的空間(C語言中是佔0位元組,而C++中佔1位元組);否則其他任何情況下,一個位段結構所佔的空間至少是一個位段儲存單元的大小;

  測試程式:

#include<iostream>
using namespace std;

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 
{
    unsigned int a:1;
    char b;                //在一個位段儲存單元中能夠存下所有的成員,所以佔4Byte
    int c:1;
    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;
}

 

 

執行結果為:

1 -1 -2 3
4 1 8 12 4
請按任意鍵繼續. . .
當列印s4的各個位段時,列印的結果與賦的初始值不同。

由於c只佔1位,那麼沒有資料位元,此時進行符號擴充直接在高位添加1,所以列印的結果為-1;

由於d佔2位,那麼當將2賦給d時,記憶體中儲存的內容為10,此時進行符號擴充,高位補1,則為0XFF FF FF FE,那麼其真值則為-2.

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.