平台为32位的kali以及windows11 64位

编译器为gcc (Debian ) 以及 mingw gcc


(资料图片)

注意:1,本文补零只是一个说法,大致意思就是填充,至于填充什么,我暂时以零算,所以叫补零

2,本文只是我个人探究得出结论,总体基本上都是在平台上测试过,如有不对的地方,还望大家指正,在这里叩谢了。

本文最佳阅读我个人觉得,可用先‘简单’阅读一下内容直到介绍4位与8位补齐,认真看一下位对齐策略4位8位补齐以及极限算法,然后再回过头重新看一遍,基本上就完事了。

下面开始!

核心:探究得出位域规律核心内容如下

整体趋向于最大的位数对齐(结构中位最大的类型)确定结构的对齐字节

“位域无法跨越字节”  当前类型位域能放下的放在一起 不能放下的 剩余字节位域补零 补零后在下一字节开始 存入下一成员 已存放类型位置不变

两参数临近存放 如果位域超过了前一个成员类型位域大小 先填入前面参数 字节的剩余位域补零 下一字节存放第二个成员 

到这里,没事,不要紧,你看不明白很正常,我总结的都费劲嫌自己啰嗦,更别说你只是看了,接下来才是重点,上面只是留个映像。

”重要!!!“总之记住下面这三点 括号内的看一眼有点映像就好了

1, 先找出位域最大的类型 这个结构体自能是该类型的倍数大小(包括一倍)

2,搞清楚位和字节的区别 当前平台下1字节等于8位 有8位补齐策略(还有4位补齐和极限算法,8位补齐意思就是不足八个,将8位中剩余几个补零,需要存的数据必须再八位以后存放  4位补齐就是不足4位的 把4位剩余几个补零,需要存的数据可再4位后存放)

3,“从前向后” 类型相同能挤就挤 

下面是例子:

1,能挤就挤

struct{

char a:3;

char b:4;

}   3+4<8 能挤下 就占一个字节,也就是8位

2,不能挤就当前类型字节补零 重开字节存储

struct{

char a:3;

char b:6;

}   3+6>8 不能挤 第一个参数存入 剩余字节位域补零 在当前类型下一个字节存放 

3,不相同就按最大的 但类型最大位域还是要遵守 

struct{

char a:3;

short b:4;

}   3+4<8 能挤下 就占一个字节 但结构必须是最大位域类型的倍数 不足的需要补零 所以当前就占两个字节(short是2个字节)除了放置数据的 其他位置全补零

4,不能挤下还有类型差

struct{

char a:3;

short b:6;

}   3+6>8 不能挤 第一个参数存入 剩余字节位域补零 在当前类型下一个字节存放 存放完补零 补完再补整体最大类型位域的空位 当前结构最大类型是short 就等于两个数据加起来位域必须得是short的位域倍数 不足的补零 a占一个字节 b占一个字节 刚好满足short位域倍数(1倍:16位)

5,不能挤

struct{

char a:3;

short b:12;

}   3+12>8 不能挤 第一个参数存入 剩余字节位域补零 在当前类型下一个字节存放 但b有12位 一个字节存不下 所以就提升到当前类型字节(char->short  8位变成16位) 存放完补零 补完再补整体最大类型位域的空位 当前结构最大类型是int 就等于两个数据加起来位域必须得是int的位域倍数 不足的补零 a占一个字节 b占一个字节 刚好满足short位域倍数(1倍:16位)

6,不能挤

struct{

char a:3;

short b:14;

}   3+14>8 不能挤 第一个参数存入 剩余字节位域补零 在当前类型下一个字节存放 但b有14位 一个字节存不下 所以就提升到当前类型字节(char->short  8位变成16位) 存放完补零 补完再补整体最大类型位域的空位 当前结构最大类型是short 就等于两个数据加起来位域必须得是short的位域倍数 不足的补零 a占一个字节 b占2个字节 整体补零一个字节 刚好满足2个short位域倍数(2倍:32位)

7,不能挤

struct{

char a:3;

int b:30;

}   再介绍一下这种情况 明显ab位域char的位域满足不了 所以a补齐8位 然后填入b的内容 b再补齐自己类型位域 最后执行整体位域补齐,当前整体位域开篇就说过,这里是int的倍数 而当前一个int位域肯定放不下 所以就两个 多的空域补零

8,不能挤

struct{

char a:3;

int b:30;

char c:3;

}   这个结构再我的环境下占12字节 为什么? 因为前面两个的两个int位根据开篇说的从前向后规则已经是定了的,而且b和c凑一起是大于int位域位数 所以挤不了 只能再开一片空间存储 这时候结构要执行整体位域补齐 所以c后面将整体补零满足要求 大致就是c占3位 填补5位 b占30位 填补2位 填补24位 c占3位 填补5位 填补24位 整体填补0位 最终占96位 12字节

9,后面可用挤

struct{

char a:3;

int b:30;

char c:2;

}   这种你以为还是和上面一样吗 不 这个的b和c刚好能执行极限算法 下面有介绍极限算法  a占3位 补5位 b占30位 c占2位 补0位 整体补24位  最终占64位 8字节

小重点啦!!!位对齐策略解释一下4位补齐与8位补齐策略区别

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字节 说明一下 这是两个short 不是提升到int了 开篇就说过 ,只能是最大类型的倍数 这种情况就是两个short位域大小  其中第21到24是short补齐 25到32 是整体补齐,满足最大类型倍数的要求

4位中 a+b>8 不能一起存放 a后面的位域要补零 补足4位 也就是a**0b*** ********最终2字节

大重点!!!最后再说一下一种极限算法 如今很多都是以这种为主 4位8位补齐是备选

struct{

char a:3;

short b:13;

}

极限算法:a**b**** ********  只要填不满 我就不添加类型位域空间 最终2字节

struct{

char a:3;

short b:14;

}

这种情况极限算法也没招 就看第二支持的是8位还是4位对齐了 

8位a**00000 b******* ******00 00000000

4位a**0b*** ******** **000000 00000000

现在你明白了吗?

还不明白 去看一下开篇的中心内容 三点要记下的东西 再看一下位对齐策略 最后去看一下例子

再不明白,集齐万赞或千币我出视频好吧。

辛苦了您,感谢阅读。

关键词: