C語言結(jié)構(gòu)體位域,一次講清楚
平臺為32位的kali以及windows11 64位
編譯器為gcc (Debian 13.1.0-6) 13.1.0 以及 mingw gcc

注意:1,本文補零只是一個說法,大致意思就是填充,至于填充什么,我暫時以零算,所以叫補零
? ? ? ? ? ?2,本文只是我個人探究得出結(jié)論,總體基本上都是在平臺上測試過,如有不對的地方,還望大家指正,在這里叩謝了。
本文最佳閱讀我個人覺得,可用先‘簡單’閱讀一下內(nèi)容直到介紹4位與8位補齊,認真看一下位對齊策略4位8位補齊以及極限算法,然后再回過頭重新看一遍,基本上就完事了。
下面開始!
核心:探究得出位域規(guī)律核心內(nèi)容如下
整體趨向于最大的位數(shù)對齊(結(jié)構(gòu)中位最大的類型)確定結(jié)構(gòu)的對齊字節(jié)
“位域無法跨越字節(jié)”? 當前類型位域能放下的放在一起 不能放下的 剩余字節(jié)位域補零 補零后在下一字節(jié)開始 存入下一成員 已存放類型位置不變
兩參數(shù)臨近存放 如果位域超過了前一個成員類型位域大小 先填入前面參數(shù) 字節(jié)的剩余位域補零 下一字節(jié)存放第二個成員?
到這里,沒事,不要緊,你看不明白很正常,我總結(jié)的都費勁嫌自己啰嗦,更別說你只是看了,接下來才是重點,上面只是留個映像。

”重要!??!“ 總之記住下面這三點 括號內(nèi)的看一眼有點映像就好了
1, 先找出位域最大的類型 這個結(jié)構(gòu)體自能是該類型的倍數(shù)大?。òㄒ槐叮?/span>
2,搞清楚位和字節(jié)的區(qū)別 當前平臺下1字節(jié)等于8位 有8位補齊策略(還有4位補齊和極限算法,8位補齊意思就是不足八個,將8位中剩余幾個補零,需要存的數(shù)據(jù)必須再八位以后存放? 4位補齊就是不足4位的 把4位剩余幾個補零,需要存的數(shù)據(jù)可再4位后存放)
3,“從前向后” 類型相同能擠就擠?

下面是例子:
1,能擠就擠
struct{
char a:3;
char b:4;
}? ?3+4<8 能擠下 就占一個字節(jié),也就是8位
2,不能擠就當前類型字節(jié)補零 重開字節(jié)存儲
struct{
char a:3;
char b:6;
}? ?3+6>8 不能擠 第一個參數(shù)存入 剩余字節(jié)位域補零 在當前類型下一個字節(jié)存放?
3,不相同就按最大的 但類型最大位域還是要遵守?
struct{
char a:3;
short b:4;
}? ?3+4<8 能擠下 就占一個字節(jié) 但結(jié)構(gòu)必須是最大位域類型的倍數(shù) 不足的需要補零 所以當前就占兩個字節(jié)(short是2個字節(jié))除了放置數(shù)據(jù)的 其他位置全補零
4,不能擠下還有類型差
struct{
char a:3;
short b:6;
}? ?3+6>8 不能擠 第一個參數(shù)存入 剩余字節(jié)位域補零 在當前類型下一個字節(jié)存放 存放完補零 補完再補整體最大類型位域的空位 當前結(jié)構(gòu)最大類型是short 就等于兩個數(shù)據(jù)加起來位域必須得是short的位域倍數(shù) 不足的補零 a占一個字節(jié) b占一個字節(jié) 剛好滿足short位域倍數(shù)(1倍:16位)
5,不能擠
struct{
char a:3;
short b:12;
}? ?3+12>8 不能擠 第一個參數(shù)存入 剩余字節(jié)位域補零 在當前類型下一個字節(jié)存放 但b有12位 一個字節(jié)存不下 所以就提升到當前類型字節(jié)(char->short? 8位變成16位) 存放完補零 補完再補整體最大類型位域的空位 當前結(jié)構(gòu)最大類型是int 就等于兩個數(shù)據(jù)加起來位域必須得是int的位域倍數(shù) 不足的補零 a占一個字節(jié) b占一個字節(jié) 剛好滿足short位域倍數(shù)(1倍:16位)
6,不能擠
struct{
char a:3;
short b:14;
}? ?3+14>8 不能擠 第一個參數(shù)存入 剩余字節(jié)位域補零 在當前類型下一個字節(jié)存放 但b有14位 一個字節(jié)存不下 所以就提升到當前類型字節(jié)(char->short? 8位變成16位) 存放完補零 補完再補整體最大類型位域的空位 當前結(jié)構(gòu)最大類型是short 就等于兩個數(shù)據(jù)加起來位域必須得是short的位域倍數(shù) 不足的補零 a占一個字節(jié) b占2個字節(jié) 整體補零一個字節(jié) 剛好滿足2個short位域倍數(shù)(2倍:32位)
7,不能擠
struct{
char a:3;
int b:30;
}? ?再介紹一下這種情況 明顯ab位域char的位域滿足不了 所以a補齊8位 然后填入b的內(nèi)容 b再補齊自己類型位域 最后執(zhí)行整體位域補齊,當前整體位域開篇就說過,這里是int的倍數(shù) 而當前一個int位域肯定放不下 所以就兩個 多的空域補零
8,不能擠
struct{
char a:3;
int b:30;
char c:3;
}? ?這個結(jié)構(gòu)再我的環(huán)境下占12字節(jié) 為什么? 因為前面兩個的兩個int位根據(jù)開篇說的從前向后規(guī)則已經(jīng)是定了的,而且b和c湊一起是大于int位域位數(shù) 所以擠不了 只能再開一片空間存儲 這時候結(jié)構(gòu)要執(zhí)行整體位域補齊 所以c后面將整體補零滿足要求 大致就是c占3位 填補5位 b占30位 填補2位 填補24位 c占3位 填補5位 填補24位 整體填補0位 最終占96位 12字節(jié)
9,后面可用擠
struct{
char a:3;
int b:30;
char c:2;
}? ?這種你以為還是和上面一樣嗎 不 這個的b和c剛好能執(zhí)行極限算法 下面有介紹極限算法? a占3位 補5位 b占30位 c占2位 補0位 整體補24位? 最終占64位 8字節(jié)

小重點啦?。?! 位對齊策略 解釋一下4位補齊與8位補齊策略區(qū)別
struct{
char a:3;
short b:6;
}?
8位中 a+b>8 不能一起存放 a后面的位域要補零 補足8位 二進制也就是a**00000 b******00
4位中 a+b>8 不能一起存放 a后面的位域要補零 補足4位 二進制也就是a**0 b** ***0000000
問有什么作用?來看
struct{
char a:3;
short b:12;
}?
8位中 a+b>8 不能一起存放 a后面的位域要補零 補足8位 也就是a**00000 b******* ****0000 00000000? 最終4字節(jié) 說明一下 這是兩個short 不是提升到int了 開篇就說過 ,只能是最大類型的倍數(shù) 這種情況就是兩個short位域大小? 其中第21到24是short補齊 25到32 是整體補齊,滿足最大類型倍數(shù)的要求
4位中 a+b>8 不能一起存放 a后面的位域要補零 補足4位 也就是a**0b*** ******** 最終2字節(jié)

大重點?。?! 最后再說一下一種極限算法 如今很多都是以這種為主 4位8位補齊是備選
struct{
char a:3;
short b:13;
}
極限算法:a**b**** ********? 只要填不滿 我就不添加類型位域空間 最終2字節(jié)
struct{
char a:3;
short b:14;
}
這種情況極限算法也沒招 就看第二支持的是8位還是4位對齊了?
8位 a**00000 b******* ******00 00000000
4位 a**0b*** ******** **000000 00000000

現(xiàn)在你明白了嗎?
還不明白 去看一下開篇的中心內(nèi)容 三點要記下的東西 再看一下位對齊策略 最后去看一下例子
再不明白,集齊萬贊或千幣我出視頻好吧。
辛苦了您,感謝閱讀。?