Delphi 4 的动态数组

传统的Pascal 语言其数组大小是预先确定的,当你用数组结构声明数据类型时,你必须指定数组元素的个数。专业程序员也许知道些许动态数组的实现技术,一般是采用指针,用手工分配并释放所需的内存。

Delphi 4中增加了非常简单的动态数组实现方法,实现过程效仿我前面讲过的动态长字符串。与长字符串一样,动态数组的内存动态分配并且引用记数,不过动态数组不支持 copy-on-write 技术。这不是个大问题,因为你可以把变量值设置为nil释放数组内存。

这样你就可以声明一个不指定元素个数的数组,并用SetLength 过程给数组分配一个特定大小的内存,SetLength 过程还可以改变数组大小而不影响其内容,除此外还有一些字符串过程也可用于数组,如Copy 函数。

以下摘录的代码突出了一点,这就是:定义数组后必须先为它分配内存,然后才能开始使用:

procedure TForm1.Button1Click(Sender: TObject);
varArray1: array of Integer;
beginArray1 [1] := 100; // errorSetLength (Array1, 100);Array1 [99] := 100; // OK...
end;

如果你只定义一个数组元素个数,那么索引总是从0开始。Pascal 中的普通数组既能用不为零的下标,也能用非整数的下标,但动态数组均不支持这两种下标。象普通数组一样,你可以通过Length、High和Low 函数了解到动态数组的状况,不过对于动态数组,Low 函数返回值总是0,High函数返回数组大小减1,这意味着空的动态数组其函数High返回值是-1,这是一个很怪的值,因为它比Low的返回值还小。

图 8.1: 例 DynArr 窗体

以上作了简短的介绍,现在举个简例,例名DynArr ,见图8.1。例子实在是很简单,其实动态数组没有什么特别复杂地方。我想通过该例说明几个程序员可能犯的错误。程序中声明了两个全程数组并在OnCreate 事件中初始化了第一个数组:

varArray1, Array2: array of Integer;procedure TForm1.FormCreate(Sender: TObject);
begin// allocateSetLength (Array1, 100);
end;

这样就把数组所有值设置为0。完成这段代码你马上就能读写数组元素的值,而不用害怕内存出错,当然条件是你没有试图访问超过数组上界的元素。为了更好地初始化,程序中添加了一个按钮,执行数组元素赋值操作:

procedure TForm1.btnFillClick(Sender: TObject);
varI: Integer;
beginfor I := Low (Array1) to High (Array1) doArray1 [I] := I;
end;

Grow 按钮用于修改数组大小,但并不影响数组内容。单击Grow 按钮后,你可以用Get value按钮进行检验:

procedure TForm1.btnGrowClick(Sender: TObject);
begin
  // grow keeping existing valuesSetLength (Array1, 200);
end;procedure TForm1.btnGetClick(Sender: TObject);
begin// extractCaption := IntToStr (Array1 [99]);
end;

Alias 按钮的OnClick 事件代码稍复杂些,程序通过 := 算子把一个数组拷贝给另一个数组,从而有效地创建了一个别名(一个新变量,但引用内存中同一数组)。从中可见,如果你改变了其中一个数组,那么另一个同样也会改变,因为它们指向同一个内存区:

procedure TForm1.btnAliasClick(Sender: TObject);
begin
  // aliasArray2 := Array1;
  // change one (both change)Array2 [99] := 1000;
  // show the otherCaption := IntToStr (Array1 [99]);

在btnAliasClick 事件中增加了两部分操作内容。第一部分是数组等同测试,不过并不是测试实际的数组元素,而是测试数组所引用的内存区,检测变量是不是内存中同一数组的两个别名:

procedure TForm1.btnAliasClick(Sender: TObject);
begin...if Array1 = Array2 thenBeep;
  // truncate first arrayArray1 := Copy (Array2, 0, 10);
end;

btnAliasClick 事件的第二部分内容是调用Copy 函数。该函数不仅把数据从一个数组移到另一个数组,而且用函数创建的新数组取代第一个数组,结果变量Array1 所引用的是11个元素的数组,因此,按Get value 和Set value 按钮将产生一个内存错误,并且触发一个异常(除非你把范围检查range-checking 选项关掉,这种情况下,错误仍在但屏幕上不会显示异常)。虽然如此,Fill 按钮仍能正常工作,因为需要修改的数组元素由数组当前的下标范围确定。

结束语

这一章内容暂时只包括动态数组,动态数组的确是内存管理的重要组成部分,但仅仅是其中的一部分,其它内容以后会逐步添加。

本章描述的内存结构属于典型的 Windows 编程内容,这方面内容将在下一章进行讨论。

下一章: Windows 编程

转载于:https://www.cnblogs.com/delphi2014/p/4012681.html

Delphi 之 第八课 动态数组相关推荐

  1. 《C语言精讲第八课》——数组,超级详细且容易理解

    <C语言精讲第八课>--数组,超级详细且容易理解 文章目录 <C语言精讲第八课>--数组,超级详细且容易理解 前言

  2. 第十八课.动态图模型

    目录 动态图模型的共同特征 模型间的区别 动态图模型的重点问题 动态图模型的共同特征 关于贝叶斯网络的经典实例:隐马尔科夫模型,卡尔曼滤波器,粒子滤波器:这三个有向图具有一个统一的名称:动态图模型,并 ...

  3. Delphi动态数组中删除元素的重要函数Delete

    System.Delete从字符串中删除一个子串,或者从动态数组中删除元素,并返回修改后的数组. 在Delphi代码中,Delete从字符串或数组S中删除一个由Count字符组成的子串,从S[Inde ...

  4. Delphi泛型动态数组的扩展,归属 武稀松 所有!

    武稀松真的是Delphi 界里的一个大银才,他写的博客文章非常新颖和实用,如今竟然将泛型数组封装的如此有声有色. 我对这个泛型动态数组的扩展爱不释手,在他开源的代码上,增加了排序和搜索两个小功能,纯属 ...

  5. Delphi 指针, 静态数组, 动态数组

    https://www.cnblogs.com/shangdawei/archive/2013/04/30/3051656.html指针 : 指针是一个特殊的变量, 它里面存储的数值被解释成为内存里的 ...

  6. Delphi动态数组详解

    获取动态数组的首地址时,要加索引号如:arr:array of byte;在move blockread等函数中使用时要加[0]索引,如:move(arr[0],newarr[0],length)等.

  7. HDU ACM 1181 变形课 (广搜BFS + 动态数组vector)-------第一次使用动态数组vector

    http://acm.hdu.edu.cn/showproblem.php?pid=1181 题意:给我若干个单词,若单词A的结尾与单词B的开头相同,则表示A能变成B,判断能不能从b开头变成m结尾. ...

  8. 打印循环换行_科学向日葵在线课堂 ——张老师讲Python 第八课 周而复始为循环2...

    点击蓝字关注我们 张老师讲编程--和爸爸妈妈一起学Python Python 的编辑器有很多,例如 PyCharm.Spyder.Notepad++等等,大家根据需要选择一个就好,初期程序代码量不大, ...

  9. NeHe OpenGL第二十八课:贝塞尔曲面

    NeHe OpenGL第二十八课:贝塞尔曲面 贝塞尔曲面: 这是一课关于数学运算的,没有别的内容了.来,有信心就看看它吧. 贝塞尔曲面 作者: David Nikdel ( ogapo@ithink. ...

最新文章

  1. NLP新秀prompt跨界出圈,清华刘知远最新论文将它应用到VLM图像端
  2. 基于Pyhton的图像隐写术--如何隐藏图像中的数据
  3. HDU 1693(状态压缩 插头DP)
  4. linux安装pytorch教程,centos下通过conda安装pytorch
  5. 201521123004《软件工程》个人阅读作业1
  6. ipad和iphone切图_如何在iPhone,iPad和Mac上使消息静音
  7. webpack打包生成的map文件_一站式搞明白webpack中的代码分割
  8. define定义的是什么类型_为什么Django 3后建议使用Field.choices枚举类型定义choices选项...
  9. try-catch 异常处理的执行过程
  10. 一个25岁董事长给程序员的18条忠告
  11. AVA + Spectron + JavaScript 对 JS 编写的客户端进行自动化测试
  12. c语言作业大全,C语言练习题(答案)
  13. 偏微分方程数值解法pdf_数值模拟偏微分方程的三种方法:FDM、FEM及FVM
  14. 2012 IMF 全球人均gdp排名
  15. 不是二进制MAT文件,请尝试执行 load -ASCII 以便以文本形式读取
  16. dsp版win10和普通版区别_Windows10各个版本有什么不同,如何选择适合自己的Win10系统...
  17. 自动化测试 - 12306火车票网站自动登录工具
  18. 数据库SQLserver(课本)
  19. 【Linux】系统维护命令
  20. java魔界战记魔女_魔界战记风格RPG《魔女传说》最新公开!

热门文章

  1. @RequestMapping报404错误问题解决
  2. Spring Data Jpa、Jpa、Hibernate、JDBC四者之间的关系
  3. Eclipse 安装Spring tool suite 解决官网下载jar文件无法安装/安装过程出错,及如何下载对应版本zip文件等问题,避坑
  4. 人大金仓数据库sql语句_人大金仓数据库总结(SQL和JDBC)
  5. c位边上还有什么位_c位是什么意思?明星站c位旁边是什么位?有什么含义【图】...
  6. Centos7.9禁用密码登录
  7. [BX] 和 loop指令
  8. java的final也并不是那么高冷
  9. 狂神说mysql笔记_Mybatis学习笔记(狂神说)
  10. 2.2.3 操作系统之调度算法的评价指标(cpu利用率、系统吞吐量、周转时间、等待时间、响应时间)