久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C語(yǔ)言位域精解

 Frank__Library 2016-12-09
    有些信息在存儲(chǔ)時(shí),,并不需要占用一個(gè)完整的字節(jié),, 而只需占幾個(gè)或一個(gè)二進(jìn)制位。例如在存放一個(gè)開(kāi)關(guān)量時(shí),,只有0和1 兩種狀態(tài),,用一位二進(jìn)位即可。為了節(jié)省存儲(chǔ)空間,,并使處理簡(jiǎn)便,,C語(yǔ)言又提供了一種數(shù)據(jù)結(jié)構(gòu),稱為“位域”或“位段”,。所謂“位域”是把一個(gè)字節(jié)中的二進(jìn)位劃分為幾個(gè)不同的區(qū)域,,并說(shuō)明每個(gè)區(qū)域的位數(shù)。每個(gè)域有一個(gè)域名,,允許在程序中按域名進(jìn)行操作,。 這樣就可以把幾個(gè)不同的對(duì)象用一個(gè)字節(jié)的二進(jìn)制位域來(lái)表示。
一,、位域的定義和位域變量的說(shuō)明
位域定義與結(jié)構(gòu)定義相仿,,其形式為:
struct 位域結(jié)構(gòu)名
{ 位域列表 };
其中位域列表的形式為: 類型說(shuō)明符 位域名:位域長(zhǎng)度
例如:
struct bs
{
    int a:8;
    int b:2;
    int c:6;
};
位域變量的說(shuō)明與結(jié)構(gòu)變量說(shuō)明的方式相同。 可采用先定義后說(shuō)明,,同時(shí)定義說(shuō)明或者直接說(shuō)明這三種方式,。例如:
struct bs
{
    int a:8;
    int b:2;
    int c:6;
}data;
說(shuō)明data為bs變量,共占兩個(gè)字節(jié),。其中位域a占8位,,位域b占2位,位域c占6位,。對(duì)于位域的定義尚有以下幾點(diǎn)說(shuō)明:
1. 一個(gè)位域必須存儲(chǔ)在同一個(gè)字節(jié)中,,不能跨兩個(gè)字節(jié)。如一個(gè)字節(jié)所??臻g不夠存放另一位域時(shí),,應(yīng)從下一單元起存放該位域,。也可以有意使某位域從下一單元開(kāi)始,。
例如:
struct bs
{
    unsigned a:4;
    unsigned :0;
    unsigned b:4;
    unsigned c:4;
}
在這個(gè)位域定義中,a占第一字節(jié)的4位,,后4位填0表示不使用,,b從第二字節(jié)開(kāi)始,,占用
4位,c占用4位,。
2. 由于位域不允許跨兩個(gè)字節(jié),,因此位域的長(zhǎng)度不能大于一個(gè)字節(jié)的長(zhǎng)度,也就是說(shuō)不能超過(guò)8位二進(jìn)位,。
3. 位域可以無(wú)位域名,,這時(shí)它只用來(lái)作填充或調(diào)整位置。無(wú)名的位域是不能使用的,。例如:
struct k
{
    int a:1;
    int :2;
    int b:3;
    int c:2;
};
從以上分析可以看出,,位域在本質(zhì)上就是一種結(jié)構(gòu)類型, 不過(guò)其成員是按二進(jìn)位分配的,。

二,、位域的使用
位域的使用和結(jié)構(gòu)成員的使用相同,其一般形式為:
位域變量名·位域名
位域允許用各種格式輸出,。
main(){
    struct bs
        {
             unsigned a:1;
             unsigned b:3;
             unsigned c:4;
        } bit,*pbit;
    bit.a=1;
    bit.b=7;
    bit.c=15;
    printf("%d,%d,%d\n",bit.a,bit.b,bit.c);
    pbit=&bit;
    pbit->a=0;
    pbit->b&=3;
    pbit->c|=1;
    printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c);
}
上例程序中定義了位域結(jié)構(gòu)bs,,三個(gè)位域?yàn)閍,b,c。說(shuō)明了bs類型的變量bit和指向bs類型的指針變量pbit,。這表示位域也是可以使用指針的,。程序的9、10,、11三行分別給三個(gè)位域賦值,。( 應(yīng)注意賦值不能超過(guò)該位域的允許范圍)程序第12行以整型量格式輸出三個(gè)域的內(nèi)容。第13行把位域變量bit的地址送給指針變量pbit,。第14行用指針?lè)绞浇o位域a重新賦值,,賦為0。第15行使用了復(fù)合的位運(yùn)算符"&=",,該行相當(dāng)于:pbit->b=pbit->b&3位域b中原有值為7,,與3作按位與運(yùn)算的結(jié)果為3(111&011=011,十進(jìn)制值為3)。同樣,,程序第16行中使用了復(fù)合位運(yùn)算"|=".之所以要有透析基礎(chǔ)知識(shí)這么個(gè)分欄,就是告訴大家重 在細(xì)節(jié)的道理,粗略的東西誰(shuí)都懂,修煉內(nèi)功為高手的必經(jīng)之路.
前面的內(nèi)容存在缺陷,,具體還要參考如下文章:
C99規(guī)定int、unsigned int和bool可以作為位域類型,,但編譯器幾乎都對(duì)此作了擴(kuò)展,,允許其它類型類型的存在。

使用位域的主要目的是壓縮存儲(chǔ),,其大致規(guī)則為:
1) 如果相鄰位域字段的類型相同,,且其位寬之和小于類型的sizeof大小,則后面的字
段將緊鄰前一個(gè)字段存儲(chǔ),直到不能容納為止,;
2) 如果相鄰位域字段的類型相同,,但其位寬之和大于類型的sizeof大小,則后面的字
段將從新的存儲(chǔ)單元開(kāi)始,,其偏移量為其類型大小的整數(shù)倍,;
3) 如果相鄰的位域字段的類型不同,則各編譯器的具體實(shí)現(xiàn)有差異,,VC6采取不壓縮方
式,,Dev-C++采取壓縮方式;
4) 如果位域字段之間穿插著非位域字段,,則不進(jìn)行壓縮,;
5) 整個(gè)結(jié)構(gòu)體的總大小為最寬基本類型成員大小的整數(shù)倍。

typedef struct  AA
{
       unsigned char b1:5;
       unsigned char b2:5;
       unsigned char b3:5;
       unsigned char b4:5;
       unsigned char b5:5;
}AA;

sizeof(AA) 5; 但實(shí)際上只用了25位,,即4個(gè)字節(jié),,

(1)typedef struct  AA
{
       unsigned int b1:5;
       unsigned int b2:5;
       unsigned int b3:5;
       unsigned int b4:5;
       unsigned int b5:5;
}AA;

 

(2)typedef struct  AA
{
       unsigned int b1:5;
       unsigned int b2:5;
       unsigned int b3:5;
       unsigned int b4:5;
       unsigned int b5:5;
       unsigned int b6:5;
       unsigned int b7:5;
}AA;

(1)是5個(gè)成員,按第一條規(guī)則,共占25位,按第五條規(guī)則,即sizeof(AA)=4
現(xiàn)把成員加到7個(gè),參考(2),按第一條規(guī)則,共占35位,按第五條規(guī)則,即sizeof(AA)=8,

 

再看一個(gè)例子:

 struct test1

{

char a:1;

char :2;

long b:3;

char c:2;

};

int len = sizeof(test1);

對(duì)于上述例子,,len的值應(yīng)該是12.解釋如下: 

首先以最長(zhǎng)的類型位寬做為偏移量,,最長(zhǎng)的是long型,占4位,,所以不同類型之間應(yīng)該是4個(gè)字節(jié)的偏移,,即test1應(yīng)該是4字節(jié)的整數(shù)倍?!?/p>

char a:1,; //用一個(gè)字節(jié)去存儲(chǔ)

char :2;  //空域,。因?yàn)榕c前面的a的類型相同,,而兩個(gè)位域的位寬相加仍然少于8位,所以依然用1個(gè)字節(jié)表示

long b:3,; //long類型的位寬是4個(gè)字節(jié),,與前面的char類型不同,所以b與a之間偏移4個(gè)字節(jié),,它們之間自動(dòng)補(bǔ)充3個(gè)字節(jié) 

char c:2,; //因?yàn)閏與b又不同型,以test1中的最長(zhǎng)的long類型的位寬進(jìn)行偏移,,所以雖然char只用1個(gè)字節(jié)就夠了

//但依然要占4個(gè)字節(jié),。

總共是12字節(jié)。

 

 

///////////////////////

struct s1

  {

  int i: 8;

  int j: 4;

  int a: 3;

  double b;

  };

  struct s2

  {

  int i: 8;

  int j: 4;

  double b;

  int a:3;

  };

  printf("sizeof(s1)= %d\n", sizeof(s1));

  printf("sizeof(s2)= %d\n", sizeof(s2));

  result: 16, 24

  第一個(gè)struct s1

  {

  int i: 8;

  int j: 4;

  int a: 3;

  double b;

  };

  理論上是這樣的,,首先是i在相對(duì)0的位置,,占8位一個(gè)字節(jié),然后,j就在相對(duì)一個(gè)字節(jié)的位置,,由于一個(gè)位置的字節(jié)數(shù)是4位的倍數(shù),因此不用對(duì)齊,,就放 在那里了,,然后是a,要在3位的倍數(shù)關(guān)系的位置上,,因此要移一位,,在15位的位置上放下,目前總共是18位,,折算過(guò)來(lái)是2字節(jié)2位的樣子,,由于 double是8 字節(jié)的,因此要在相對(duì)0要是8個(gè)字節(jié)的位置上放下,,因此從18位開(kāi)始到8個(gè)字節(jié)之間的位置被忽略,,直接放在8字節(jié)的位置了,因此,,總共是16字節(jié),。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多