眼镜 商城 网站建设,中铁三局招聘信息2021,手机网站判断跳转代码怎么写,做旅游的网站 优帮云你是真的“C”——结构体中的精髓剖析【内存对齐】 【位段】 #x1f60e;前言#x1f64c;结构体内存对齐#xff1a;#x1f60a;结构体内存对齐存在的意思是什么#xff1f;#x1f618;内存对齐例子详细剖析#xff1a;#x1f618;结构体中的位段#xff1a; 【位段】 前言结构体内存对齐结构体内存对齐存在的意思是什么内存对齐例子详细剖析结构体中的位段什么是位段位段的内存分配2.3 位段的跨平台问题2.4 位段的应用总结撒花博客昵称博客小梦 最喜欢的座右铭全神贯注的上吧 作者简介一名热爱C/C算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主 博主小留言哈喽各位CSDN的uu们我是你的博客好友小梦希望我的文章可以给您带来一定的帮助话不多说文章推上欢迎大家在评论区唠嗑指正觉得好的话别忘了一键三连哦 前言 哈喽各位友友们我今天又学到了很多有趣的知识现在迫不及待的想和大家分享一下我仅已此文和大家分享你是真的“C”——结构体中的精髓剖析【内存对齐】 【位段】。都是精华内容可不要错过哟 结构体属于一种自定义的结构体类型。是对于我们内置数据类型的一个补充它的应用是非常广的。想必大家在学校已经学习了对结构体有了一定的了解你以为你已经掌握了。其实你只是初识了一下结构体而已。你听说过结构体内存对齐吗听说过位段吗我相信大家都听说过游戏中的段位~ 如果没有那就说明你还没有真真了解结构体。废话不多说接下来我就围绕着着两个核心要点和大家分享我对结构体的认知和了解。
结构体内存对齐
结构体内存对齐存在的意思是什么
很多的参考资料是这样阐述的 平台原因(移植原因) 不是所有的硬件平台都能访问任意地址上的任意数据的某些硬件平台只能在某些地址处取某些特 定类型的数据否则抛出硬件异常。性能原因 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。 原因在于为了访问未对齐的内存处理器需要作两次内存访问而对齐的内存访问仅需要一次访 问。 3.总的来说结构体的内存对齐是拿空间来换取时间的做法。 我们知道任何数据类型都有大小而言。那么结构体的大小是多少呢4byte8byte… 其实要计算结构体的大小首先需要搞明白结构体中的内存对齐。
既然结构体内存对齐有那么大的价值咋废话不多讲我们直击主题结构体内存对齐的几条核心法则
标准规定结构体的首成员存放在相对于起始地址的0偏移处。接下来的成员依次放在其对应对齐数的整数倍偏移量处。对齐数 取 默认对齐数 和自身内存大小之中的较小者。默认对齐数与环境有关在vs环境下默认对齐数是8而在gcc环境下没有默认对齐数。成员的自身大小就是对齐数。当结构体的所有成员都放进内存中后结构体的大小 max每成员的对齐数的整数倍。即使不用那么多空间也需要浪费空间来进行分配进行内存对齐。当结构体中嵌套一个结构体成员结构体的大小还是按照取最大对齐数的整数倍这里的对齐数是包含结构体中的对齐数的在这些之中取出最大的那个。其余按照上述法则。
究竟是否像上述法则所说这样来进行内存对齐呢接下来我通过几个例子来分析一波帮助大家理解一下。
内存对齐例子详细剖析
例题一
struct S1
{char c1;int i;char c2;
};上述的结构体大小是多少呢
咱们画图分析
所以答案应该是12 。是不是呢我们在编译器中运行检验一下
程序运行结果图 果然是12。说明我们的法则是对的刚才的画图分析也是正确哒~
例题二
struct S2
{char c1;char c2;int i;
};咱们画图分析 程序运行结果
发现一个问题结构体S1和S2的成员都是一样的只是放的位置不同而已但是S1分配的空间却比S2要多这显然是浪费更多的空间了。
结论那在设计结构体的时候我们既要满足对齐又要节省空间如何做到让占用空间小的成员尽量集中在一起。
结构体中的位段
什么是位段
相比大家对于游戏段位还是很了解的但位段和段位可不一样哦~ 位段属于一种自定义的数据类型。位段的声明和结构体是类似的有两个不同 1.位段的成员必须是 int、unsigned int 或signed int整形家族都行只是int 用到的频率比较高 。 2.位段的成员名后边有一个冒号和一个数字。后面的数字表示的是bit。 举个栗子让大家感受一下位段的魅力
struct A
{int _a:2;int _b:5;int _c:10;int _d:30;
};那位段A的大小是多少 程序运行结果 大家看到如果没有位段的话这个结构体的大小肯定大于8个字节的。位段的作用起到节省空间的作用。
位段的内存分配
位段的成员可以是 int unsigned int signed int 或者是 char 属于整形家族类型位段的空间上是按照需要以4个字节 int 或者1个字节 char 的方式来开辟的。位段涉及很多不确定因素位段是不跨平台的注重可移植的程序应该避免使用位段。
举个栗子
空间是如何开辟的
struct S
{char a : 3;char b : 4;char c : 5;char d : 4;
};
int main()
{struct S s { 0 };s.a 10;s.b 12;s.c 3;s.d 4;
}
画图分析 程序运行结果 2.3 位段的跨平台问题
int 位段被当成有符号数还是无符号数是不确定的。位段中最大位的数目不能确定。16位机器最大1632位机器最大32写成27在16位机器会出问题。位段中的成员在内存中从左向右分配还是从右向左分配标准尚未定义。当一个结构包含两个位段第二个位段成员比较大无法容纳于第一个位段剩余的位时是舍弃剩余的位还是利用这是不确定的。
总结跟结构相比位段可以达到同样的效果但是可以很好的节省空间但是有跨平台的问题存在。
2.4 位段的应用
在网路协议中用处很广例如如下图所示 这里的数字表示的都是bit其实就是运用了位段的知识。 网络中就像下图所示数据是在网络中传输的。如果太大就会造成网络堵塞影响效率。网络中的数据是十分庞大的因此位段的价值就体现出来啦
总结撒花 本篇文章旨在分享结构体中鲜有人知的“秘密”。希望大家通过阅读此文有所收获如果我写的有什么不好之处请在文章下方给出你宝贵的意见。如果觉得我写的好的话请点个赞赞和关注哦~