当前位置:首页>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 编程 -- 五谈数组

最新文章

随机文章