Delphi 之 第八课 动态数组
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 之 第八课 动态数组相关推荐
- 《C语言精讲第八课》——数组,超级详细且容易理解
<C语言精讲第八课>--数组,超级详细且容易理解 文章目录 <C语言精讲第八课>--数组,超级详细且容易理解 前言
- 第十八课.动态图模型
目录 动态图模型的共同特征 模型间的区别 动态图模型的重点问题 动态图模型的共同特征 关于贝叶斯网络的经典实例:隐马尔科夫模型,卡尔曼滤波器,粒子滤波器:这三个有向图具有一个统一的名称:动态图模型,并 ...
- Delphi动态数组中删除元素的重要函数Delete
System.Delete从字符串中删除一个子串,或者从动态数组中删除元素,并返回修改后的数组. 在Delphi代码中,Delete从字符串或数组S中删除一个由Count字符组成的子串,从S[Inde ...
- Delphi泛型动态数组的扩展,归属 武稀松 所有!
武稀松真的是Delphi 界里的一个大银才,他写的博客文章非常新颖和实用,如今竟然将泛型数组封装的如此有声有色. 我对这个泛型动态数组的扩展爱不释手,在他开源的代码上,增加了排序和搜索两个小功能,纯属 ...
- Delphi 指针, 静态数组, 动态数组
https://www.cnblogs.com/shangdawei/archive/2013/04/30/3051656.html指针 : 指针是一个特殊的变量, 它里面存储的数值被解释成为内存里的 ...
- Delphi动态数组详解
获取动态数组的首地址时,要加索引号如:arr:array of byte;在move blockread等函数中使用时要加[0]索引,如:move(arr[0],newarr[0],length)等.
- HDU ACM 1181 变形课 (广搜BFS + 动态数组vector)-------第一次使用动态数组vector
http://acm.hdu.edu.cn/showproblem.php?pid=1181 题意:给我若干个单词,若单词A的结尾与单词B的开头相同,则表示A能变成B,判断能不能从b开头变成m结尾. ...
- 打印循环换行_科学向日葵在线课堂 ——张老师讲Python 第八课 周而复始为循环2...
点击蓝字关注我们 张老师讲编程--和爸爸妈妈一起学Python Python 的编辑器有很多,例如 PyCharm.Spyder.Notepad++等等,大家根据需要选择一个就好,初期程序代码量不大, ...
- NeHe OpenGL第二十八课:贝塞尔曲面
NeHe OpenGL第二十八课:贝塞尔曲面 贝塞尔曲面: 这是一课关于数学运算的,没有别的内容了.来,有信心就看看它吧. 贝塞尔曲面 作者: David Nikdel ( ogapo@ithink. ...
最新文章
- NLP新秀prompt跨界出圈,清华刘知远最新论文将它应用到VLM图像端
- 基于Pyhton的图像隐写术--如何隐藏图像中的数据
- HDU 1693(状态压缩 插头DP)
- linux安装pytorch教程,centos下通过conda安装pytorch
- 201521123004《软件工程》个人阅读作业1
- ipad和iphone切图_如何在iPhone,iPad和Mac上使消息静音
- webpack打包生成的map文件_一站式搞明白webpack中的代码分割
- define定义的是什么类型_为什么Django 3后建议使用Field.choices枚举类型定义choices选项...
- try-catch 异常处理的执行过程
- 一个25岁董事长给程序员的18条忠告
- AVA + Spectron + JavaScript 对 JS 编写的客户端进行自动化测试
- c语言作业大全,C语言练习题(答案)
- 偏微分方程数值解法pdf_数值模拟偏微分方程的三种方法:FDM、FEM及FVM
- 2012 IMF 全球人均gdp排名
- 不是二进制MAT文件,请尝试执行 load -ASCII 以便以文本形式读取
- dsp版win10和普通版区别_Windows10各个版本有什么不同,如何选择适合自己的Win10系统...
- 自动化测试 - 12306火车票网站自动登录工具
- 数据库SQLserver(课本)
- 【Linux】系统维护命令
- java魔界战记魔女_魔界战记风格RPG《魔女传说》最新公开!
热门文章
- @RequestMapping报404错误问题解决
- Spring Data Jpa、Jpa、Hibernate、JDBC四者之间的关系
- Eclipse 安装Spring tool suite 解决官网下载jar文件无法安装/安装过程出错,及如何下载对应版本zip文件等问题,避坑
- 人大金仓数据库sql语句_人大金仓数据库总结(SQL和JDBC)
- c位边上还有什么位_c位是什么意思?明星站c位旁边是什么位?有什么含义【图】...
- Centos7.9禁用密码登录
- [BX] 和 loop指令
- java的final也并不是那么高冷
- 狂神说mysql笔记_Mybatis学习笔记(狂神说)
- 2.2.3 操作系统之调度算法的评价指标(cpu利用率、系统吞吐量、周转时间、等待时间、响应时间)