C语言:结构体(自定义类型)
目录1. 声明1.1 结构体的声明1.2 结构体自引用2. 结构体内存对齐热门考点2.1 对齐规则2.3 修改默认对齐数3.结构体传参4. 结构体实现位段4.1 位段4.2 内存分配4.3 跨平台问题4.4 位段的应用IP数据报4.5 注意事项结构体是自定义类型就像一个生产线定义了一个结构体后后续就可以用这个 “模板” 批量生产出多个结构体变量产品。1. 声明1.1 结构体的声明struct tag { member - list; }variable - list;参数tag标签结构体类型的名称类似int的作用用于后续声明变量时指明类型。可以省略但省略后就无法在其他地方复用这个结构体类型。member-list成员列表结构体的“内部零件”由若干个数据类型 成员名组成定义了结构体包含哪些信息。variable-list变量列表用这个结构体直接创建的一个或多个变量名。可以省略等需要时再单独创建。*和python的字典用法很像都是把多个数据打包在一起。举个例子描述一个学生struct Stu { char name[20]; //姓名 int age; //年龄 char gender[5]; //性别 char id[20]; //学号 } stu1; //这个结构体变量名是stu1特殊声明匿名结构体不推荐声明结构体的时候可以省略结构体类型标签tagstruct { int a; char b; float c; }x;但是这样就无法创建结构体指针了如果没有对tag重命名基本只能用一次。解决方案不要使用匿名结构体。1.2 结构体自引用结构体内部不能再次包含同类型结构体因为这样会导致结构体大小无穷大俄罗斯套娃。但是我们可以包含同类型的结构体指针这样就可以实现自引用了struct example { int data; struct example* ptr; };易错如果使用typedef来对结构体重命名又在内部提前使用了这个名称是不可行的typedef struct example { int data; struct EX* ptr; }EX;因为结构体中重命名是在结构体创建之后才进行的如果提前在结构体内部使用了重命名程序就会报错。更正typedef struct example { int data; struct example* ptr; }EX;应用链表包含数据域和指针域2. 结构体内存对齐热门考点内存对齐是拿空间换取时间的方法减少了访问时间但占用的内存增加了。Q为什么会有内存对齐平台 / 移植原因某些硬件平台只能在特定地址取出特定类型的数据。性能原因数据结构应尽可能对齐自然边界可以减少访问次数。2.1 对齐规则理论有点抽象这里举个例子S1的第一个成员是c1对齐到内存偏移量为0的位置剩下的成员逐个与默认对齐数8作比较取较小数并存放在内存中的整数倍处计算总大小取成员最大对齐数4的整数倍由于存放c1i c2时占用了9个字节4*2 8 大小不够因此总大小为4*3 12个字节。结构体嵌套的例子struct S2 { char c3; struct S1; //12字节上个例子已计算 double d1; };S2的第一个成员是c3对齐到内存偏移量为0的位置嵌套的结构体单独计算出总大小再放入内存中的整数倍处12d1是8个字节取整数倍后与8*3 24处对齐S2总大小取嵌套结构体S1中成员的最大对齐数i为4和自己的成员比较再取最大成员的整数倍d18得出S2共占8*4 32个字节。总结如果要尽量节省结构体的空间就要让占用空间小的成员尽量集中在一起。2.3 修改默认对齐数#pragma pack (num) //设置默认对齐数为num #pragma pack () //恢复默认对齐数#pragma 可以修改默认对齐数。3.结构体传参结构体传参要传结构体的地址避免时间和空间开销过大。struct S { int arr[1000]; int num; }; struct S s1 {{1, 2, 3 ,4}, 100}; void print(struct S* ps) //参数为地址 { printf(%d\n, ps - num); } int main() { print(s1); //传引用 return 0; }4. 结构体实现位段4.1 位段介绍位段的成员必须是intunsigned int 或signed int在C99中可以为char。位段的成员名后面有一个冒号和一个数字来自定义所占的bite位。作用通过自定义大小来节省空间。4.2 内存分配char原本是8个bit现在结构体S中分别将char型变量a, b, c, d修改为3454个bit第9行初始化结构体变量为010~13行存入数据注意存储的是二进制位由于变量a的空间不足二进制位被截断。4.3 跨平台问题和结构体相比位段可以达到同样的效果并且可以节省空间但存在跨平台问题4.4 位段的应用IP数据报使用位段可以很好的打包数据数据报中的许多属性仅需几个bit就能描述大大节省了空间提高了传输效率对网络畅通很有帮助4.5 注意事项位段的几个成员共有同一个字节内存中每个字节分配一个地址字节内部的bit是没有地址的因此不能对位段成员使用操作符不能使用scanf直接给位段成员输入值需要先将输入放在一个变量中再赋值给位段成员egstruct A { int _a: 2; int _b: 3; int _c: 4; int _d: 5; }; int main() { struct A sa {0}; int b 0; scanf(%d\n, b); sa._b b; //合法 return 0; }//感谢你能看到这里点个赞再走叭~(*/ω*)
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2450691.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!