• 正文
    • 1 結(jié)構(gòu)體位域
    • 2 __attribute__((packed))
    • 3 聯(lián)合使用
  • 相關(guān)推薦
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

結(jié)構(gòu)體位域和__attribute__ ((__packed__))一起用

02/03 08:55
1430
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

1 結(jié)構(gòu)體位域

1.1 位域

位域是一種節(jié)省空間的數(shù)據(jù)結(jié)構(gòu),是把一個(gè)數(shù)據(jù)類(lèi)型按照二進(jìn)制(二進(jìn)位)劃分為幾個(gè)不同的區(qū)域,并說(shuō)明每個(gè)區(qū)域的位數(shù)。

比如有一個(gè)字節(jié),每一位表示一個(gè)開(kāi)關(guān)狀態(tài),就可以使用位域,解析也方便。

struct test{

unsigned char test1:1;

unsigned char test2:1;

unsigned char test3:1;

unsigned char test4:1

unsigned char test5:1;

unsigned char test6:1;
unsigned char test7:1;
unsigned char test8:1;

}

這樣收到1字節(jié)數(shù)據(jù)賦值給test,解析每個(gè)位的狀態(tài)直接使用test.test1.....test.test6就可以,不需要再進(jìn)行相應(yīng)的位與操作之類(lèi)的。還可以節(jié)省空間。要注意大小端,小端的test1是低位。

1.2位域的具體存儲(chǔ)規(guī)則如下:

1) 如果相鄰位域字段的類(lèi)型相同,且其位寬之和小于類(lèi)型的sizeof大小,則后面的字段將緊鄰前一個(gè)字段存儲(chǔ),直到不能容納為止。

2)如果相鄰位域字段的類(lèi)型相同,但其位寬之和大于類(lèi)型的sizeof大小,則后面的字段將從新的存儲(chǔ)單元開(kāi)始。

struct test{
unsigned char test1:1;
unsigned char test2:4;
unsigned char test3:4;
unsigned char test4:1;
unsigned char test5:1;
unsigned char test6:1;
unsigned char test7:1;
unsigned char test8:1;
}

舉例,這個(gè)test結(jié)構(gòu)體,成員test3+test2+test1的位寬為9,大于char的8位,那從test3開(kāi)始就要從第2個(gè)字節(jié)開(kāi)始存。

編輯切換為居中

添加圖片注釋?zhuān)怀^(guò) 140 字(可選)

3)如果相鄰的位域字段的類(lèi)型不同,則各編譯器的具體實(shí)現(xiàn)有差異,不建議使用,也沒(méi)啥使用的必要。

4)如果位域字段之間穿插著非位域字段,則不進(jìn)行壓縮。

5)整個(gè)結(jié)構(gòu)體的總大小為最寬基本類(lèi)型成員大小的整數(shù)倍,和普通結(jié)構(gòu)體一樣。

2 __attribute__((packed))

__attribute__ ((packed)) 的作用就是告訴編譯器取消結(jié)構(gòu)在編譯過(guò)程中的優(yōu)化對(duì)齊,按照實(shí)際占用字節(jié)數(shù)進(jìn)行對(duì)齊,是GCC特有的語(yǔ)法。

__attribute__關(guān)鍵字主要是用來(lái)在函數(shù)或數(shù)據(jù)聲明中設(shè)置其屬性。

3 聯(lián)合使用

對(duì)于一些特殊的協(xié)議,比如sbus,sbus一個(gè)通道占11位,那按照位域的規(guī)則,下屬代碼中的channel3就要在存儲(chǔ)在下一個(gè)unsigned int中了。就不滿(mǎn)足我們直接利用編譯器解析數(shù)據(jù)的目的了。

struct sbus_test

{

unsigned int channel1: 11;

unsigned int channel2: 11;

unsigned int channel3: 11;

unsigned int channel4: 11;

unsigned int channel5: 11;

...

} __attribute__ ((__packed__));

使用__attribute__ ((__packed__))處理,是可以使數(shù)據(jù)一個(gè)挨著一個(gè),直接讀取數(shù)據(jù)了。對(duì)于一些這種特殊協(xié)議的,這樣聯(lián)合使用比較方便。

 

相關(guān)推薦