书接上回昂,上次讲完了结构体的对其,今天我们接着来了解结构体的相关知识
总结:函数在传参的时候,参数是需要压栈的,会有时间和空间上的系统开销;如果我们传递一个结构体对象的时候,结构体过大,参数压栈时的系统开销就会过大,从而导致我们性能的下降。所以我们在结构体传参的时候,尽量选择传址调用
结构体的位段是什么呢?对于大家来说,这貌似是一个全新的概念,有一点像我们的声明,但是有所区别:
1 . 位段的成员必须是 int、unsigned int 或 signed int,在我们 C99 中位段成员的类型也可以选择其他类型
2 . 位段成员名后面有一个冒号(:)和一个数字
大家看一下,上面就是我们结构体的位段,在我们实现结构体位段之前,大小为 16 个字节,在实现位段之后,帮我们压缩了一些内存,但这里为什么大小是 8 个字节呢?不急,接下来我们慢慢来深入了解
(2 . 1)位段的成员是整型类型,例如:int、unsigned int、signed int 还有 char(这里有同学疑惑,不是说整型么?为什么会有 char 类型呢?实际上我们的 char 类型代表的字符,底层逻辑不就是 ASCLL 码值嘛,这一系列数字实质上也是我们的整型)
(2 . 2)位段在空间上是按照需要以 4 个字节(int)或者 1 个字节(char)的方式来开辟的
(2 . 3)位段涉及很多不确定因素,且位段是不跨平台的,注重可移植性的程序应该避免使用位段
如图,这里举了一个例子,光是干瘪的文字太过生硬了,我为了帮助大家理解,用图文的形式为诸君做了剖析:
大家可以看到,我们例子中的成员是 char 类型的,所以我们结构体开辟空间就是以 1 个字节 1 个字节的开辟,一个字节不够用了,再给一个字节,且是从左到右的这种形式。结构体实现位段的过程我相信已经在这张图上为诸君解释的很清楚了昂,如果大家对此有疑问的话,欢迎评论区或者私信跟我交流哦,这没什么不好意思的,我第一次接触这部分知识,也是画了一些时间才理解到的
在我们上一节中提到过了结构体的对其,它的核心思想是牺牲一些空间来换取效率,而我们今天的结构体位段在某种程度上来说就恰恰相反:牺牲效率换取空间
(4 . 1)int 位段被当做有符号还是无符号这是不确定的(也就是说我们 int 所开辟的 4 个字节也就是 32 个比特位,这个最高位的符号位是正还是负是不确定的)
(4 . 2)位段中的最大位的数目是不确定的(例如在早期的 16 位机器上最大为 16,现在的机器普遍是 32 位,那么我们第一个例题中的 d:30,这段代码如果写在 16 位机器上就是会出错的)
(4 . 3)位段中的成员在内存中是从左向右还是从右向左分配这是不确定的,标准尚未定义(刚刚我们在例题的演示中只是假设了一种情况而已)
(4 . 4)当一个结构体包含两个及多个位段时,下一个位段成员较大,无法容纳于第一个位段所剩余的位时,是舍弃还是继续利用,这是不确定的(刚刚在例题当中我们也是假设它是舍弃的情况)
总结:我们在例题中假设的情况刚好符合,这只证明我们的假设符合于当前运行环境,在其他编译器环境下不一定是这样的,所以位段是有很多不确定因素的,我们不能跨平台使用,很容易出错
这时候有的同学就要问了,位段既然这么不稳定,那我们要怎么用?什么时候才会运用到位段呢? 位段并不是像我们肤浅地认为那样一无是处,例如我们的接发信息,在我们的网络传输中,位段能发挥巨大的作用
下图是网络协议中,IP数据报的格式,我们可以看到其中很多的属性只需要几个 bit 位就能描述,这里我们使用位段,能够实现我们想要的效果,也可以最大程度的节省空间,这样我们的网络传输的数据报大小会相对小很多,对网络数据的通畅有很大的帮助
OKK,有关于结构体的部分知识咱们就聊到这儿了昂,结构体对齐和位段时比较重要的知识,诸君当勤勉励,也没啥说的了,咱们就下期再见吧!与诸君共勉!!!
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- hids.cn 版权所有 赣ICP备2024042780号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务