| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> 自定义类型的很多精华 -> 正文阅读 |
|
[C++知识库]自定义类型的很多精华 |
结构体类型1 结构体类型的不完成声明这种声明只能使用一次 了解就行 如 struct { char c; int a; }a,b; struct { char c; int a; } *p; &a == p;//编译器会报错,编译器会认为是两种类型,是非法的,所以最好别这样声明 最好别这样使用 2 结构体的初始化使用大括号 要善于使用memset
若里面嵌套的是一个结构体数组呢,那就不好初始化了呢 直接用前面提到的memset,如 struct A { B stu[20]; char c; int a; }C; 用memset初始化C 先看看这个函数memset如何使用吧(我们上cplusplus.com - The C++ Resources Network上面可查找函数使用) ptr 传入要初始化数据的首地址,value要初始化的值,num初始化的大小 所以这里我们可以这样做 memset(&c, 0, sizeof(C)); 这里就将sizeof(C)那么个字节大小的内存,每个内存都初始化为0; 如何求结构体类型的大小先看看
P的大小是多少,先猜一猜,首先是不是觉得是1+4+8=13字节?恭喜你错了 首先,要知道内存对齐,这是求结构大小的关键方法 offsetof(),这是查数据的偏移量,知道偏移量,才能更好介绍内存对齐
? 这就是结构体成员在内存中的放置位置,根据偏移量来放置 3 对齐数对齐数是编译器默认的对齐数与该成员变量大小的较小值 如 当默认对齐数为4时, char a; a 的大小是1字节,默认对齐数是4,那选一个较小值,那a的默认对齐数就是1 double c; c的大小是8字节,默认对齐数是4,那c默认对齐数是4; ? VS默认对齐数是8 Linux下无默认对齐数 用#pragam pack()可修改默认对齐数()里面修改的默认对齐数(一般改为2的n次方) #pragam pack ()一般放在要修改的结构体定义之前 内存对齐的规则1 结构体内的第一个成员放在结构体变量偏移量为0的地址处 ? 2 第二个及之后的成员变量要放到它们自己的对齐数的整数倍处 b的对齐数是4,4是4的整数倍,且偏移量为4处未被占,那b就从偏移量为4处开始放 ? 同样,c的偏移量为1,8是1的8倍,那就从8开始放入c。 ? 3 结构体的总大小要为最大对齐数(成员和默认对齐数中最大的那个)的整数倍(含镶嵌结构体的对齐数) 看,结构体是从0偏移量数完,占9个字节,最大对齐数是4,那4的整数倍是12,那还要再拿出 3个空间来放着构成12个字节 所以这个结构体最终大小为12 ? 来,去vs检测一下算的对不对 ? 4 如果成员里结构体A包含结构体B(8字节),求A大小 如果镶嵌结构体B,B的当前对齐数(B中求出来的最大对齐数就是B的当前对齐数)和默认对齐数比,求出对齐数,方法和前三条一样 ? A的大小是多少呢? 首先,我们上次算出struct P大小位 12 byte,最大对齐数是4 , int b 大小是4,对齐数4 double c 大小是8,vs的默认对齐数是8,那它对齐数就是8; 然后画图来看 ? 欧克,vs下检验一遍 ? 如果结构体里面有个成员是数组,像char arr[20]; 他的对齐数怎么求呢? 注意不是拿20比哈 他是char类型的,1字节,默认对齐数为8,那对齐数就是1,占12个字节 其他类型的以此类推 为什么要有内存对齐,内存对齐的作用
不是所有硬件都能访问到任意地址处的任意数据,某些硬件只能在某些地址处访问到特定的某种类型的数据,否则可能硬件异常,所以为了硬件方便读取,存储对齐将特定类型的数据放在特定的位置处方便硬件读取 ? ?2. 性能原因 数据结构(尤其是栈)应该尽可能的在自然边界上对齐。因为为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问 如图 ? 总之,结构体的内存对齐是以空间换取时间 在设计结构体的时候,尽可能的将大小差不多数据类型放一堆,集中在一起,节约空间 结构体传参结构体传参时最好传地址,函数传参时,参数是会压栈的,会有时间与空间的开销,如果传的结构体对象过大,参数压栈的系统开销比较大,会导致性能下降,所以结构体传参时最好传地址 位段1 .what is 位段 ?位段就是在结构体数据成员名后面加一个冒号:and 一个数字; 哦,位段的成员只能是int ,unsigned int,singed int,char Like this picture ? 2.how to calculate 位段大小?其实最简单的也就是一个sizeof就算出来了,但是还是还是必须知道这个计算逻辑的 位段的空间是按照需求以4个字节(int)或者1个字节(char)开辟的,先开辟一次,用完或者不够再开辟一次 位段冒号: 后面那个数字是所需要的比特位 来复习一下,一个字节是多少比特位,忘了把我头打爆,说明好久没学了 8个哦 好,回来继续,看题
字有点多,但全是精华。 malloc开辟了多大的空间; 首先,第一个是char 类型,先开辟一个字节,一个成员需要4个比特位,那还剩4个,第二个成员需要2个比特位 还剩下两个,第三个成员是结构体成员,需要一个字节,直接开辟,目前两个字节了 最后一个成员需要一个比特位,之前还剩两个比特位,但由于已经新开辟了一个字节 数据在内存中是按顺序放的,所以只能再开辟一个字节,占一个比特位, 还剩7个 总共开辟了三个字节,这个结构体占3字节sizeof(struct _Record_Struct)== 3,之后是预处理,直接 替换3*A+B ,最后算出来9字节,所以开辟了9个的大小空间 3.what's meaning for 位段?首先,一定程度上节省空间,列如 struct A { int a:2; // } 当a存储的数据数据状态只为:00,01,10,11 只需要两个比特位就能保存,但一个整型4字节,32比特位过于浪费,所以就可以用位段 像年龄,分数这样用位段就挺好 其次,数据的传输,用位段很好节省空间和时间 但是,位段有一定缺点 跨平台问题 1 int位段的数据被当成有符号数还是无符号数是不是确定的 2 位段在不同机器下的最大位的数目是不能确定的,在16位机器下一个int最大是16位,32位机器下最大位是32位 如果在冒号后写了个24这样的数,在32位机器下没问题,但到了16位机器就会处问题 3 位段成员在内存中的数据分配是从左到右,还是从右到左这是尚未定义的,不知的,取决于编译器, 注意!!!这不是大小端字节序,大小段是在以字节位单位情况下看的,既然这厮位段,位那就是比特位,所以与 大小端区分开 4 当一个结构包含两个位段时,第一个位段成员比较小,第二个比较大,当第一个成员使用一定内存后,还剩一定位, 再开辟新的位容纳第二个,之前的剩余的位是使用还是舍去,这是不确定的。 总之,与结构相比,位段可以达到同样的功能和效果时,位段可以很好节省空间,但是有跨平台的问题。 枚举类型1.定义这个东西应该算自产自销吧。。 列如
枚举里面的内容是有一定值的,默认从0开始,一次增加1 像 ? 枚举最开始可以在枚举体里面,给枚举变量赋初值的,之后出去就改不了 如: ? 2.枚举的优点增加代码可读性和可维护性 与#define定义的标识符相比他是有类型的,更加严谨 便于携带调试,在预处理时,#define定义的标识符直接被替换了,调试时就已经换成对应的值了 使用方便,一次可定义多个常量 联合体(共用体)1.定义这种自定义类型也包含一系列成员,这些成员共用一块空间 看看这个代码 ? 联合体成员共用最大的那个空间,他在同一时间内只能用一个。 判断当前机器为是否大小段 用联合体来判断
2.联合体大小的计算联合体的大小至少是最大对齐数的整数倍 当最大成员的大小不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍; 如 ?嗯,终于写完了,会尽快补齐之前到项目和笔记的,懒狗的泪,之前欠的以后总要还的,为了以后不还,只能现在还了如果,哪位大佬看到发现错误,也请斧正,真的谢谢你!!! |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 3:17:38- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |