被骗去国外做网站网站推广,php 网站制作的意义,直播网站开发框架,有人有免费的片资源吗前言 前面讲了结构体的概念#xff0c;定义#xff0c;赋值#xff0c;访问等知识#xff0c;本节内容小编将讲解结构体的内存大小的计算以及通过结构体实现位段#xff0c;话不多说#xff0c;直接上干货#xff01;#xff01;#xff01; 1.结构体内存对齐
说到计…前言 前面讲了结构体的概念定义赋值访问等知识本节内容小编将讲解结构体的内存大小的计算以及通过结构体实现位段话不多说直接上干货 1.结构体内存对齐
说到计算结构体的大小就要了解结构体内存对齐原则。
结构体内存对齐是指在内存中存储结构体变量时根据结构体成员的类型和大小按照一定的规则进行内存对齐以提高内存访问效率。
1.1对齐规则 1. 结构体的第一个成员对齐到和结构体变量起始位置偏移量为0的地址处 2. 其他成员变量要对齐到某个数字对齐数的整数倍的地址处。 对齐数 编译器默认的一个对齐数与该成员变量大小的较小值。 - VS 中默认的值为 8 - Linux中 gcc 没有默认对齐数对齐数就是成员自身的大小 3. 结构体总大小为最大对齐数结构体中每个成员变量都有一个对齐数所有对齐数中最大的的整数倍。 4. 如果嵌套了结构体的情况嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处结构体的整体大小就是所有最大对齐数含嵌套结构体中成员的对齐数的整数倍。 举例说明
例1 struct S1
{char c1;//1int i;//4char c2;//1
};
printf(%d\n, sizeof(struct S1)); 12字节为最大对齐数4的倍数所以结构体大小为12 例2 struct S3
{double d;char c;int i;
};
printf(%d\n, sizeof(struct S3)); 16个字节刚好为最大对齐数double的整数倍所以结构体大小为16 例3结构体嵌套 struct S4
{char c1;struct S3 s3;double d;
};
printf(%d\n, sizeof(struct S4)); 32字节为最大对齐数8的倍数所以结构体大小为32 1.2为什么存在内存对齐 1. 平台原因 (移植原因) 不是所有的硬件平台都能访问任意地址上的任意数据的某些硬件平台只能在某些地址处取某些特定 类型的数据否则抛出硬件异常。 2. 性能原因 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于为了访问未对齐的内存处理器需要作两次内存访问而对齐的内存访问仅需要一次访问。假设一个处理器总是从内存中取8个字节则地 址必须是8的倍数。如果我们能保证将所有的double类型的数据的地址都对⻬成8的倍数那么就可以用一个内存操作来读或者写值了。否则我们可能需要执行两次内存访问因为对象可能被分放在两个8字节内存块中。 总体来说结构体的内存对齐是拿空间来换取时间的做法。 那在设计结构体的时候我们既要满足对齐又要节省空间如何做到 让占用空间小的成员尽量集中在一起 struct S1 { char c1;//1 int i;//4 char c2;//1 }; struct S2 { char c1;//1 char c2;//1 int i;//4 }; printf(%d\n, sizeof(struct S1)); printf(%d\n, sizeof(struct S2)); S1 和 S2 类型的成员一模一样但是 S1 和 S2 所占空间的大小有了一些区别。 S112,S28 1.3修改默认对齐数 #pragma 这个预处理指令可以改变编译器的默认对齐数。 #include stdio.h
#pragma pack(1)//设置默认对⻬数为1
struct S
{char c1;int i;char c2;
};
#pragma pack()//取消设置的对⻬数还原为默认
int main()
{//输出的结果是什么printf(%d\n, sizeof(struct S));return 0;
} 对齐数设置为1时,大小为6 结构体在对齐方式不合适的时候我们可以自己更改默认对齐数。 2.结构体传参 #include stdio.h
struct S
{int data[1000];int num;
};
struct S s {{1,2,3,4}, 1000};
//结构体传参
void print1(struct S s)
{for(int i0;i4;i){printf(%d ,s.data[i]);}printf(\n%d\n, s.num);
}
//结构体地址传参
void print2(struct S* ps)
{for(int i0;i4;i)printf(%d ,ps-data[i]);printf(\n%d\n, ps-num);
}
int main()
{print1(s); //传结构体print2(s); //传地址return 0;
} 上面的 print1 和 print2 函数哪个好些 答案是首选print2函数。 原因 函数传参的时候参数是需要压栈会有时间和空间上的系统开销。 如果传递一个结构体对象的时候结构体过大参数压栈的的系统开销比较大所以会导致性能的下降。 结论 结构体传参的时候要传结构体的地址。 3.结构体实现位段 3.1什么是位段 位段Bit-fields是一种在C语言中用于节省内存的技术它允许程序员定义一个结构体或联合体中的成员变量这些成员变量的大小以位为单位而不是以字节为单位。位段可以用来表示那些只需要少量位来存储的数据例如标志位或者状态位。 位段的定义方式是在结构体或联合体中使用冒号:指定成员变量所占用的位数。 位段的声明和结构是类似的有两个不同 1. 位段的成员必须是 int、unsigned int 或signed int 在C99中位段成员的类型也可以 选择其他类型。 2. 位段的成员名后边有一个冒号和一个数字。 struct A
{int _a:2;//占2个两个bit位int _b:5;int _c:10;int _d:30;
};位段式结构中的位可以理解二进制位
在C语言中位段的大小取决于编译器和硬件平台的具体实现。通常位段的大小是按照字节对齐的但是位段内部的位数是按照定义的位数来分配的。 上述位段占了47位对齐6个字节也就是48位但是用sizeof测试时出来是8字节 在大多数系统中位段会按照最接近的字节边界对齐。由于这个结构体总共占用了47位它可能会被对齐到6个字节48位因为这是最接近47位的字节数并且可以容纳所有的位段。 然而位段的确切大小和对齐方式取决于编译器和硬件平台的具体实现。在某些系统上如果位段不能恰好填充到一个字节编译器可能会分配额外的位来填充到下一个字节边界。此外如果位段的大小超过了单个整数类型通常是32位或64位的位数编译器可能会将它们分割到多个整数中。 3.2位段的内存分配 1. 位段的成员可以是 int unsigned int signed int 或者是 char 等类型 2. 位段的空间上是按照需要以4个字节 int 或者1个字节 char 的方式来开辟的。 3. 位段涉及很多不确定因素位段是不跨平台的注重可移植的程序应该避免使用位段。 struct S
{char a:3;char b:4;char c:5;char d:4;
};
struct S s {0};
s.a 10;
s.b 12;
s.c 3;
s.d 4;
接下来通过画图来看内存空间的开辟分配 1.在申请的一块内存中bit位是从左到右还是从右到左使用是不确定的VS是从右到左 2.剩余的空间不足下一个成员使用的时候是浪费还是继续使用VS采取浪费 ok回到最上面那个位段求大小 struct A { int _a:2;//占2个两个bit位 int _b:5; int _c:10; int _d:30; }; 一次性申请4个字节第一次用17个bit位剩余15个不够用根据VS的规则采取浪费所以再次申请4个字节存取剩下的_d数据。
即该位段大小为8 3.3位段的跨平台问题 1. int 位段被当成有符号数还是无符号数是不确定的。 2. 位段中最大位的数目不能确定。16位机器最大1632位机器最大32写成27在16位机器会出问题。 eg32位或者64位int的长度占4个字节16位int是2个字节 3. 位段中的成员在内存中从左向右分配还是从右向左分配标准尚未定义。 4. 当一个结构包含两个位段第二个位段成员比较大无法容纳于第一个位段剩余的位时是舍弃剩余的位还是利用这是不确定的。 总结 跟结构相比位段可以达到同样的效果并且可以很好的节省空间但是有跨平台的问题存在。 所以需要根据不同的平台写不同的代码。 3.4位段的应用 IP数据报的格式我们可以看到其中很多的属性只需要几个bit位就能描述这里使用位段能够实现想要的效果也节省了空间这样网络传输的数据报大小也会较小一些对网络的畅通是有帮助的。 3.5位段使用的注意事项 位段的几个成员共有同一个字节这样有些成员的起始位置并不是某个字节的起始位置那么这些位 置处是没有地址的。内存中每个字节分配一个地址一个字节内部的bit位是没有地址的。 所以不能对位段的成员使用操作符这样就不能使用scanf直接给位段的成员输入值只能是先输入放在一个变量中然后赋值给位段的成员。 struct A {int _a : 2;int _b : 5;int _c : 10;int _d : 30;
};
int main() {struct A sa {0};scanf(%d, sa._b);//这是错误的
//正确的⽰范int b 0;scanf(%d, b);sa._b b;return 0;
} 下面是搜集的位段注意事项的其他总结 1. 可移植性问题位段的行为和大小可能因编译器和硬件平台而异。因此位段不具有可移植性应该避免在需要跨平台兼容的代码中使用位段。 2. 对齐和大小位段的对齐方式和大小取决于编译器的实现。编译器可能会将位段对齐到字节边界这可能导致额外的填充位。因此不应该假设位段的确切大小除非编译器文档明确说明了位段的行为。 3. 位段类型位段通常使用 unsigned int 或 int 类型定义但编译器可能会允许其他整数类型。然而使用非标准类型可能会降低代码的可移植性。 4. 位段操作位段的操作不如普通变量直观因为它们涉及到位的操作。在访问和修改位段时需要小心处理位操作以避免错误。 5. 位段顺序位段在内存中的存储顺序可能因编译器而异。有些编译器可能按照位段的定义顺序存储而其他编译器可能按照相反的顺序存储。 6. 位段跨越字节边界如果一个位段的大小超过了单个字节的位数它将会被分割到两个字节中。这可能会导致难以预测的内存布局。 7. 位段的符号性如果使用 int 类型定义位段位段可能是带符号的。这意味着位段的最高位可能被解释为符号位这可能会导致意外的行为。为了确保位段是无符号的应该使用 unsigned int 类型。 8. 位段的访问在某些平台上访问位段可能比访问普通变量更慢因为位段需要额外的位操作。 9. 位段的初始化和赋值位段的初始化和赋值可能需要特殊的位操作因为它们不是以字节为单位进行操作的。 10. 位段的限制位段不能用于数组或指针也不能用于结构体或联合体的嵌套定义。 在使用位段时应该仔细考虑这些注意事项并确保代码的可读性、可维护性和正确性。如果可能应该考虑使用其他技术如位掩码或位操作函数来代替位段以提高代码的可移植性和可读性。 OK,本节内容到此结束支持小编的留下你的关注评论和点赞吧 文章转载自: http://www.morning.lzbut.cn.gov.cn.lzbut.cn http://www.morning.sjqml.cn.gov.cn.sjqml.cn http://www.morning.plqqp.cn.gov.cn.plqqp.cn http://www.morning.ghslr.cn.gov.cn.ghslr.cn http://www.morning.kgxrq.cn.gov.cn.kgxrq.cn http://www.morning.xjkr.cn.gov.cn.xjkr.cn http://www.morning.cywf.cn.gov.cn.cywf.cn http://www.morning.cbndj.cn.gov.cn.cbndj.cn http://www.morning.knrgb.cn.gov.cn.knrgb.cn http://www.morning.zpyh.cn.gov.cn.zpyh.cn http://www.morning.tkqzr.cn.gov.cn.tkqzr.cn http://www.morning.pbwcq.cn.gov.cn.pbwcq.cn http://www.morning.phxns.cn.gov.cn.phxns.cn http://www.morning.clccg.cn.gov.cn.clccg.cn http://www.morning.rykmz.cn.gov.cn.rykmz.cn http://www.morning.yrlfy.cn.gov.cn.yrlfy.cn http://www.morning.ktmbp.cn.gov.cn.ktmbp.cn http://www.morning.hyhqd.cn.gov.cn.hyhqd.cn http://www.morning.jwdys.cn.gov.cn.jwdys.cn http://www.morning.tmjhy.cn.gov.cn.tmjhy.cn http://www.morning.zwwhq.cn.gov.cn.zwwhq.cn http://www.morning.jzklb.cn.gov.cn.jzklb.cn http://www.morning.lfjmp.cn.gov.cn.lfjmp.cn http://www.morning.xkwyk.cn.gov.cn.xkwyk.cn http://www.morning.rcqyk.cn.gov.cn.rcqyk.cn http://www.morning.kmjbs.cn.gov.cn.kmjbs.cn http://www.morning.rbrhj.cn.gov.cn.rbrhj.cn http://www.morning.mqghs.cn.gov.cn.mqghs.cn http://www.morning.jqbmj.cn.gov.cn.jqbmj.cn http://www.morning.zzgkk.cn.gov.cn.zzgkk.cn http://www.morning.rhlhk.cn.gov.cn.rhlhk.cn http://www.morning.grxsc.cn.gov.cn.grxsc.cn http://www.morning.zqcdl.cn.gov.cn.zqcdl.cn http://www.morning.lsjgh.cn.gov.cn.lsjgh.cn http://www.morning.pcngq.cn.gov.cn.pcngq.cn http://www.morning.fblkr.cn.gov.cn.fblkr.cn http://www.morning.qxdrw.cn.gov.cn.qxdrw.cn http://www.morning.wgqtj.cn.gov.cn.wgqtj.cn http://www.morning.qsdnt.cn.gov.cn.qsdnt.cn http://www.morning.dansj.com.gov.cn.dansj.com http://www.morning.shprz.cn.gov.cn.shprz.cn http://www.morning.jghty.cn.gov.cn.jghty.cn http://www.morning.grcfn.cn.gov.cn.grcfn.cn http://www.morning.fjmfq.cn.gov.cn.fjmfq.cn http://www.morning.wschl.cn.gov.cn.wschl.cn http://www.morning.gwyml.cn.gov.cn.gwyml.cn http://www.morning.sacxbs.cn.gov.cn.sacxbs.cn http://www.morning.wgrm.cn.gov.cn.wgrm.cn http://www.morning.rrqbm.cn.gov.cn.rrqbm.cn http://www.morning.cnbdn.cn.gov.cn.cnbdn.cn http://www.morning.fosfox.com.gov.cn.fosfox.com http://www.morning.qkqhr.cn.gov.cn.qkqhr.cn http://www.morning.ddgl.com.cn.gov.cn.ddgl.com.cn http://www.morning.mnsts.cn.gov.cn.mnsts.cn http://www.morning.dwrbn.cn.gov.cn.dwrbn.cn http://www.morning.sbncr.cn.gov.cn.sbncr.cn http://www.morning.lgxzj.cn.gov.cn.lgxzj.cn http://www.morning.gstg.cn.gov.cn.gstg.cn http://www.morning.kzbpx.cn.gov.cn.kzbpx.cn http://www.morning.djpgc.cn.gov.cn.djpgc.cn http://www.morning.qfcnp.cn.gov.cn.qfcnp.cn http://www.morning.jjxxm.cn.gov.cn.jjxxm.cn http://www.morning.rwbh.cn.gov.cn.rwbh.cn http://www.morning.tgyzk.cn.gov.cn.tgyzk.cn http://www.morning.jrlgz.cn.gov.cn.jrlgz.cn http://www.morning.fqklt.cn.gov.cn.fqklt.cn http://www.morning.lizimc.com.gov.cn.lizimc.com http://www.morning.kzqpn.cn.gov.cn.kzqpn.cn http://www.morning.plqhb.cn.gov.cn.plqhb.cn http://www.morning.mjats.com.gov.cn.mjats.com http://www.morning.xjpnq.cn.gov.cn.xjpnq.cn http://www.morning.ldzxf.cn.gov.cn.ldzxf.cn http://www.morning.ccyjt.cn.gov.cn.ccyjt.cn http://www.morning.nsppc.cn.gov.cn.nsppc.cn http://www.morning.tygn.cn.gov.cn.tygn.cn http://www.morning.qkdcb.cn.gov.cn.qkdcb.cn http://www.morning.xymkm.cn.gov.cn.xymkm.cn http://www.morning.lxdbn.cn.gov.cn.lxdbn.cn http://www.morning.prjns.cn.gov.cn.prjns.cn http://www.morning.cxnyg.cn.gov.cn.cxnyg.cn