| |
|
开发:
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语言结构体中的柔性数组成员 -> 正文阅读 |
|
[C++知识库]C语言结构体中的柔性数组成员 |
考虑如下问题,我们试图定义一个名为Student的结构,这个结构应包括学生的姓名,学生已修课程的数量以及已修课程各科的分数。实践中,每个学生已修课程的数目是不一样的,这使得我们在定义用于存储分数的结构成员时面临两难的局面:
解决方案之一是把分数数组成员定义为一个指向float的指针,如下述C语言代码所示:
上述程序的执行结果为:
第5 ~ 9行:定义了Student结构,其包含3个数据成员,分别是20个字节的学生姓名sName,4个字节的已修课程数量n,8个字节的分数”数组“指针scores。其3个成员的字节数相加,等于一个Student对象的尺寸32个字节。 对于Student结构而言,scores跟其它成员一样,只是数据成员,只不过类型特殊,是float*。
第12行:s对象的初始化中,将s.n初始化为4,s.scores初始化为空指针。
第17行:s.scores只是一个指针,要往s.scores”数组“里存分数前,需要手动申请需要的内存空间。这行代码为其申请了s.n,即4个float的空间。必要时,如果希望往s.scores“数组”中存入超过4个的分数,可以通过realloc()函数重新调整其动态内存的大小。
第19 ~ 23行:在分配了内存空间之后,s.scores指针便可以当成”数组“来使用。使用过程中,程序员会注意避免下标越界。这几行代码先把4个分数填入s.scores”数组”,然后再计算平均分并打印出来。
第25行:释放calloc()申请的动态内存。 这种使用指针成员来管理不定尺寸空间的方法需要程序员手动申请及释放内存,程序会变得比较零散。另外一个解决方案是使用结构的柔性数组成员(flexible array member)。请阅读下述C语言程序:
上述程序的执行结果为:
说明:在读者的计算机上,执行结果中的地址很可能与本书不同。
第5 ~ 9行:scores数组成员即为Student结构的柔性数组成员。柔性数组成员的定义要满足如下要求。
第12 ~ 13行:现假设我们要存4门课程的分数,通过一个Student的对象大小加上4个float的对象大小得到需要的内存字节数nBytes。然后,通过malloc()函数分配nBytes的堆空间,并把地址传给指针s。
第14 ~ 16行:通过执行结果可以看到,sName成员占20个字节,n成员占4个字节。虽然我们事实上给s所指向的Student对象申请了nBytes = 40个字节的空间,但在编译器看来,*s,即s所指向的Student对象的大小只有24个字节。
第18行:把s,s->scores按地址格式输出。根据执行结果,我们可以画出该Student对象的内存结构图。
如果我们直接定义类型为Student的变量s1,编译器会为s1分配sizeof(Student) = 24个字节的空间。但即便如此,s1.scores仍然会等于s1的地址+24。如果我们强行通过s1.scores进行数据访问,事实上访问的是不属于s1对象的空间,这是程序员需要小心避免的。
第20 ~ 25行:给s的柔性数组成员赋值,然后计算平均分并打印。由于我们确信s->scores所对应的内存空间属于s指向的结构对象,上述操作是安全的。
第27行:一定不要忘了释放动态分配的内存空间。 请读者注意,将带有柔性数组成员的结构对象赋值给另外一个同类型对象是危险的:
对于编译器而言,s1和s都只有sizeof(Student) = 24字节的空间。从s到s1的赋值,只会拷贝前24个字节。同样的危险也会发生在函数传值时,函数的传值,可以认为是从实际参数到形式参数的赋值。 为了帮助更多的年轻朋友们学好编程,作者在B站上开了两门免费的网课,一门零基础讲Python,一门零基础C和C++一起学,拿走不谢! 如果你觉得纸质书看起来更顺手,目前Python有两本,C和C++在出版过程中。 |
|
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/23 12:56:28- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |