源码技术
php
java
python
Linux
行业商讯
当前位置:
首页
>
java
>Delphi 编程 -- 六谈数组
Delphi 编程 -- 六谈数组
2026-10-21 13:28:25
Delphi 编程 -- 六谈数组
写完前面 5 篇讨论数组的文章,感觉意犹未尽。
我们前面说过,静态数组是一个线性内存区域,数组元素以行序为主顺序存放,数组元素地址的计算公式为(以三维数组为例):
事实果真如此吗?下面就来验证一下。
看一个简单例子:
这是一个简单的静态数组的例子。我们要验证的是,通过指针而不是数组元素的寻址方式来对数组元素 d3[1,2,3] 赋值。
首先,我们声明 d3 为一个三维的、基类型为双精度浮点数的静态数组,i、j、k 为三个下标,offset 为要赋值的数组元素距离数组起始地址的偏移量,p 为指针。
在执行语句部分,首先取静态数组 d3 的起始地址赋给指针 p,然后给下标赋值,下面根据以上的公式计算偏移量 offset,然后是用 Inc 函数给指针 p 增加 offset,以使其指向目标元素。
再下面就是给指针指向的位置赋值,因为 p 为通用指针,所以要通过 PDouble 将其转换为指向 double 类型的指针,再通过 ^ 运算符对指针解引用(dereference),并将 3.5 赋给它。
最后一行是输出 da[1,2,3] 的值。程序编译和运行结果如下:
结果正如我们所预期的。这说明,我们前文给出的计算静态数组元素地址的公式是正确的。
这是静态数组的情况。因为静态数组的尺寸、边界等信息在编译时都已知,而且在程序运行期间这些信息都不会改变,所以数组内部不存在复杂的结构以维护数组的边界和尺寸。整个数组,不管多少维,都只是一片线性的内存区域,数组元素都以行序为主顺序排列,每个元素的地址都可以根据公式计算出来。
以上是静态数组的优点,关于静态数组的缺点,以前讲过,就是数组结构的静态所导致的使用上的限制。与另外一个问题联系起来,就是内存区域的浪费。这另外一个问题就是:因为数组的内存区域是编译期间分配的,在程序运行期间也不会释放这些内存。所以即使数组只在程序开始时使用一次,数组的内存区域也会一直存在(即使不再使用,也会一直占用),直到程序运行结束。这一点,我们从下面 fpc 生成的汇编列表中看得更清楚:
可以看出,编译器为 d3(U_$P$DATEST4_$$_D3 是编译器为 d3 生成的内部名称) 分配了 480 个字节的内存区域。这片内存处于 BSS 区域,因此是静态的,属于程序静态空间的一部分,不会在运行期间释放(运行期间可以释放的只能是在堆上动态分配的内存)。
从这点上来看,静态数组适合于使用频繁的小规模数组,因为使用频繁,数组元素的静态寻址更有性能上优势,因为规模小,由于数组空间空闲导致的浪费也不会很大。
下面看动态数组。
在这个例子中,我们定义了一个三维动态数组类型 TDouble3D,然后声明了一个 d3d 变量,接着是 i、j、k 下标变量,最后是一个指针变量 p。
在执行的语句部分,首先用 SetLength 为 d3d 构造数组,三维的尺寸分别是 3、4、5,这样,d3d 就是一个 array[0..2, 0..3, 0..4] of double 类型的动态数组。
接下来设置下标为 1、2、3,我们的目的是通过指针为数组元素 d3d[1,2,3] 赋值。
下面取 d3d 的地址,然后取该地址内容赋给指针变量 p,此时 p 指向动态数组的内存区起始地址。通过 Inc 向指针 p 增加 i * SizeOf(Pointer) 的偏移量,使指针 p 指向 d3d[i] 的位置。
然后再取指针 p 的内容,因为 d3d[i] 本身就是一个指针,此时 p 指向 d3d[i] 下一维的首地址,Inc 向指针 p 增加 j * SizeOf(Pointer) 的偏移量,使 p 指向 d3d[i,j] 的位置。
同理,取 p 的内容,使 p 指向 d3d[i,j] 所指向的下一维的首地址,Inc 向指针 p 增加 k * SizeOf(Double) 的偏移量,使 p 指向 d3d[i,j,k] 的位置。为什么是 k * SizeOf(Double)?因为此时指针指向的不再是指针,而是具体的数组元素了。
此时,解引用指针 p,向其所指向的地址赋值 3.5。
最后,输出 d3d[1,2,3] 的内容来检查前面的步骤是否正确。下面是编译和执行的结果:
结果正如我们所预期的。
由上面指针的遍历所体现出的动态数组的结构可以示意如下:
由代码及示意图,我们看出,访问动态数组的元素,都要从数组的头指针(数组名 d3d)开始,沿着指针链遍历,一直到最后一维,才能访问到真正的数组元素。这种访问的开销还是相当大的。
相关阅读
Delphi 编程 -- 谈谈数组
Delphi 编程 -- 再谈数组
Delphi 编程 -- 三谈数组
Delphi 编程 -- 四谈数组
Delphi 编程 -- 五谈数组
本文来自网友投稿或网络内容,如有侵犯您的权益请联系我们删除,联系邮箱:596563534@qq.com 。
CodeFree | 手把手教学!图生代码快速实现前端页面开发
学编程一定要死磕这个软件
最新文章
CodeFree | 手把手教学!图生代码快速实现前端页面开发
2025 年度总结|以编程为桥,融学科之智,共赴 2026 教育新程
代码规范对AI编码的重要性远超想象
编程筑梦 竞绽芳华——锦山第一小学在自治区青少年编程赛事中勇创佳绩
4-3:放射性药物的制备(代码377)
编程,演进:AI 编程助手时代的经验与观察
代码已死,工程永生:AI时代程序员的进阶之路
模板编程—模板编程处理Partial application
n8n+LangChain组合:无需代码,快速搭建AI知识机器人实战教程
阳光编程,智控未来
热门文章
只靠阅读学会Python编程,Python编程的基础知识 #工程数字化003
IATA、ICAO、呼号、机票代码都是什么?
阳光编程,智控未来
不会写代码,也能拥有一支产品研发团队
快速识别解决燃气表故障代码(厂商:浙江松川)
零代码实现表单校验与用户引导——WorkFine 实战技巧
2025年C++编程等级认证三级真题汇总
UG2412三轴编程教程---加工坐标系
救命!谁能想到学 Python爬虫能搞这么多事
速收藏!数据科学-Python数据挖掘实训营精华内容全汇总
随机文章
10个月宝宝每天需要喝多少奶粉?
实训项目介绍 | 数据科学-Python数据挖掘实训营
小白易懂的一张总结python最强大的第三方库的图!
别人打游戏时你在学Python,毕业工资差三倍真的公平吗?
2026保姆级Python入门教程,从零基础入门到精通(非常详细)
这才是正确学习Python的顺序
看一师附小的芳香少年 用Python创造出怎样的学习世界?
太卷了!清华大佬终于把python整理成了漫画书!看漫画学python,简直不要太轻松!
小白学python第39天之列表集合字典推导式(上)
【第35期】21天养成编程习惯:Python刷题第18天
学Python看这10页纸就够了!(邪修版)