在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C語言中一個位域結構占多少個字節呢

冬至子 ? 來源:Linux碼農 ? 作者:Linux碼農 ? 2022-11-16 16:44 ? 次閱讀

c語言中提供一個一種叫 “位域” 或者 “位段” 的數據結構。它的存在是為了更加的節省空間。因為在有些實際需求中,并不需要占用一個完整的字節,而只是需要一個或者幾個二進制位。比如存在一個開關量時,只有 0 和 1 兩種狀態,只需要一個二進制位存儲即可。

位域的定義如下:

struct 位域結構名{ 位域列表 };

其中位域列表的形式為:類型說明符 位域名:位域長度

例如,

struct test{
   int a:3; 
   int b:2; 
   int c:6;
};

位域的變量的說明 與結構體的方式一樣,有三種方式:先定義后說明、同時定義說明、直接說明。

在聲明時,位段成員必須是整形或枚舉類型(通常是無符號類型)。

結構中也可以包含無名位域,作為相鄰成員之間的填充或調整位置。無名位域無法被引用,它們的內容在運行時是不可預測的。

struct s{
   unsigned int a:4; //a存放結構的前4個位中 
   unsigned int :2;  // a后面的2個位填充
   unsigned int b:2;  
};

位域的定義有如下限制

1、一個位域必須存儲在同一個字節中,不能跨兩個字節。

比如當一個字節所剩的空間不夠下一個位域存儲時,則從下一個存儲單元的起始位置開始存放;也可以專門讓某個位域從下一個存儲單元的起始位置開始。

struct s{
   unsigned int a:4; //a存放結構的前4個位中 
   unsigned int :2;  // a后面的2個位填充
   unsigned int b:6;  // 剩余的2位不夠存儲,從下一個存儲單元開始存放
   unsigned int :0; //空位域,把該unsigned int剩余空間自動全部填充0
   unsigned int c:5; //從下一個單元存儲,也即是從下一個 unsigned int 開始

}ss;

在這個位域中,a 占第一個字節的前 4 位,a 后面 2 位進行填充,第一個字節剩余的 2 位不夠 b 存儲,因此 b 從下一個字節開始存儲,b 后面的位域填充 0,c 從下一個單元存儲,該下一個單元指的是下一個 unsigned int,因為空位域 0 會把 b 后面 unsigned int 所剩的空間全部填充 0, 因此 sizeof(ss) = 8。

2、位域可以是無名域,無名域就是類似于 unsigned int : 0; 或者 unsigned int : 2; 雖然兩者只是 0 和非 0 的區別,但是作用卻是不同的。若無名域的位數為 0,則下一個位域將會強制從下一個單元開始(這里的一個單元指的不是下一個字節,而是跨過跨過一次數據類型的自然邊界);如果無名位域為非 0,則意味著這個無名位域占著空間,不能被使用。

struct test{
   unsigned int a:3;  //a占3位
   unsigned int :0;  //對于unsigned int 類型 a 后面的剩余未全填充0
   unsigned int b:2;  //b 從下一個unsigned int 類型開始
}tt;

在該例子中 a 占 unsigned int類型所占字節的3位,a 后面的無名域會把 a 后面的所有位填充 0,因此對于 unsigned int 類型所占的 4 字節空間,除 a 的 3 位外,其他位均為0,b 從下一個 unsigned int 類型開始,所以 sizeof(tt) 為 8。

struct test{
   unsigned int a:3;  //a占3位
   unsigned int :2;  //a后面的2個位填充
   unsigned int b:2;  // b 跟著無名域后面
}tt;

a后面無名域占 2 位,b跟在無名域后面,所以 a 和 b共占用一個字節。因此sizeof(tt) 為 4。

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

struct  test {
    unsigned char a:3;
    unsigned char b:4;
} t;

a 和 b 所占的寬度之和小于 sizeof(unsigned char)大小,因此 a和b共同使用一個字節,所以 sizeof(t) 為 1;

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

struct  test {
    unsigned int a:15;
    unsigned int b:20; //從下一個unsigned int開始
} t;

由于 a 和 b 寬度之和大于 sizeof(unsigned int)大小,因此b從下一個 unsigned int 處開始,所以 sizeof(t) 為 8。

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

struct  test {
    unsigned char a : 3;
    unsigned char b : 4;
    unsigned char c : 3;
    unsigned int  d : 5;
} t;

整個結構體的總大小為 unsigned int 類型的整數倍。

6、如果相鄰的位域字段的類型不同,則各編譯器的具體實現有差異,VC6采取不壓縮方式,Dev-C++采取壓縮方式。(跟編譯器有較大的關系,使用時要慎重,盡量避免)

struct  test {
    unsigned char a : 3;
    unsigned char b : 4;
    unsigned char c : 3;
    unsigned int  d : 5;
} t;

對于該類型,不壓縮時,a和b類型相同會占用一個字節,c會占用一個字節,d會單獨存放,不會和共占用一個字節,因為整個結構體的總大小為最寬基本類型成員大小的整數倍,因此 sizefo(t)為 8。

若壓縮時(gcc下),c 和 d 共占用一個字節,因為整個結構體的總大小為最寬基本類型成員大小的整數倍,因此 sizefo(t)為 4。

7、 如果位域字段之間穿插著非位域字段,則不進行壓縮;(不針對所有的編譯器,跟編譯器有較大的關系,使用時要慎重,盡量避免)

struct test{
    unsigned int m: 12;
    unsigned int ch;
    unsigned int p: 4;
}t;

sizeof(t) 大小為 12。

8、當使用有符號類型來定義位域,并且無意中使用到了正負(有意或者無意)特性時,可能出現不是想要的結果

struct test
{
    char a : 2;
    char b : 3;
    char c : 3;
};

struct test t;

// 位域賦值
t.a = 0x3;   // 11
t.b = 0x5;   // 101
t.c = 0x2;   // 010

printf("%d,%d,%d\\n", t.a, t.b, t.c); //結果為 -1, -3, 2

可見,當為域的最高位是 1 的時候,會進行符號擴展,而且這也取決于編譯器的實現,因此,為避免此類問題,最好使用無符號類型定義位域。

9、取地址操作符 & 不能應用在位域字段上,因此不存在位域的指針。

10、位域字段不能是靜態成員。

11、不能用來指定位數的類型。

若 struct 成員是指針變量類型不能用來指定所占的位數,在 64 位系統中指針固定占 8 字節,在 32 位系統中指針固定占 4 字節。

若 struct 成員是 double 或 float 類型,不能指定位數,否則編譯出錯,位域類型無效。

審核編輯:劉清

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7616

    瀏覽量

    137887
  • 編譯器
    +關注

    關注

    1

    文章

    1642

    瀏覽量

    49318
收藏 人收藏

    評論

    相關推薦

    編程語言中一奇怪的代碼結構

    C語言C++等編程語言中,我們常常會遇到奇怪的代碼
    發表于 11-01 10:24 ?491次閱讀
    編程<b class='flag-5'>語言中一</b><b class='flag-5'>個</b>奇怪的代碼<b class='flag-5'>結構</b>

    結構解析

    ;上例的結構定義了關于工人的信息。其中有兩個位結構成員, 每個位
    發表于 03-26 10:30

    C結構體之

    ,共個字節。其中a8,
    發表于 12-10 20:35

    一個字節有8,也就是8bit,那么串數據如何看出是多少個字節??

    一個字節有8,也就是8bit,那么串數據如何看出是多少個字節??
    發表于 07-31 14:07

    為什么結構體與聯合體起使用?

    /*本例程是C語言操作示例這里為什么結構
    發表于 07-14 06:23

    是怎樣去定義的

    描述存放開關量或者其他開關狀態時,用一位二進位即可。為了減少嵌入式內存資源的開銷,可
    發表于 12-15 07:47

    如何利用C語言操作去實現對寄存器每一位的控制

    對寄存器每一位的控制。什么是?所謂“”是把一個字節中的二進位劃分為幾
    發表于 02-25 06:41

    能不能在C語言中像操作寄存器那樣直接操作一個字節的單獨一位

    ?? 在C語言中通常操作只有真假兩種狀態的的數據時使用布爾bool變量比較多,如果需要同時觀察多個狀態,這時候選擇操作效率會更高,用一個字節的8
    發表于 02-25 06:13

    c語言中段)是如何去定義的?有哪些限制

    c語言中提供種叫 “” 或者 “
    發表于 07-01 15:52

    C語言結構體之

    所謂""是把一個字節中的二進位劃分為幾個不同的區域,并說明每個區域的位數。每個域名,
    的頭像 發表于 11-08 08:38 ?7878次閱讀

    如何才能給C語言增加幾個位操作函數

    在匯編語言中有直接對位進行操作的指令,如置、復位、取反、測試某一位等,這對于硬件操作十分方便,在C
    的頭像 發表于 05-05 15:40 ?2309次閱讀

    C語言中是什么?

    是什么? 有些數據在存儲時并不需要占用完整的字節,只需要占用
    的頭像 發表于 01-13 16:23 ?2991次閱讀

    C語言中Linux字節對齊的問題

    ,于是經過排查,是因為傳遞消息的結構體沒有考慮字節對齊的問題。 隨手整理C語言中字節對齊的問
    的頭像 發表于 08-16 11:25 ?2542次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言中</b>Linux<b class='flag-5'>字節</b>對齊的問題

    C語言使用

    對寄存器每一位的控制。什么是?所謂“”是把一個字節中的二進位劃分為幾
    發表于 01-12 20:47 ?6次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>之<b class='flag-5'>位</b><b class='flag-5'>域</b>使用

    C語言中典型的實例

    所謂""是把一個字節中的二進位劃分為幾個不同的區域,并說明每個區域的位數。每個域名,
    發表于 03-04 11:29 ?521次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言中</b>的<b class='flag-5'>位</b><b class='flag-5'>域</b>典型的實例
    主站蜘蛛池模板: 天天看天天射天天碰 | 黑人破乌克兰美女处 | 毛片免| 日本特级黄录像片 | 黄色大成网站 | 玖玖在线精品 | 国产叼嘿视频网站在线观看 | 女人张开腿双腿让男人桶 | 天天操伊人 | 色女人在线 | 天天射天天做 | 色噜噜狠狠狠综合曰曰曰 | 一级骚片超级骚在线观看 | 高清在线免费观看 | 综合久 | 亚洲九色 | 日韩美女拍拍免费视频网站 | 天天干天天干天天干天天干天天干 | 男人cao女人视频在线观看 | 国产精品任我爽爆在线播放6080 | 男人天堂网在线 | 国产免费播放一区二区三区 | 亚洲国产欧美视频 | 天天色天天色天天色 | 欧美黄色录象 | 男女性接交无遮挡免费看视频 | 亚洲国产成人久久一区久久 | 在线三级播放 | 四虎永久在线精品影院 | 免费爱做网站在线看 | 亚洲91在线视频 | 亚洲最新 | 五月天婷婷亚洲 | 欧美线人一区二区三区 | 五色网| 在线免费黄色网址 | 精品黄色片 | 国产在线精品一区免费香蕉 | 免费黄色网址网站 | 色女人综合| 毛茸茸成熟妇女亚洲人 |