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的返回值还小。

以上作了简短的介绍,现在举个简例,例名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 按钮仍能正常工作,因为需要修改的数组元素由数组当前的下标范围确定。

转载于:https://www.cnblogs.com/youshan/archive/2011/07/09/2101838.html

我学Delphi心得及笔记----内存(第七讲)相关推荐

  1. 我学Delphi心得及笔记----字符串操作(第六讲)

    Delphi 中字符串的操作很简单,但幕后情况却相当复杂.Pascal 传统的字符串操作方法与Windows 不同,Windows吸取了C语言的字符串操作方法.32位Delphi中增加了长字符串类型, ...

  2. 我学Delphi心得与笔记-------在控件上如何禁用Ctrl+V

    项目中用到一个TJamShellList组件,此组件实现绑定查询图片,发现在使用Ctrl+C的同时也可以使用Ctrl+V结果将一个图处复制了多份,这样就不行了:( 于是,想了一个办法,禁用了Ctrl+ ...

  3. 孙鑫VC学习笔记:第七讲

    七.对话框 2006年8月5日 14:25 因为笔记是用OneNote做的,上传以后为看不到图片,于是我截图放到相册上面, 相册地址为:http://photo.163.com/photos/good ...

  4. 【清风数学建模笔记】第七讲 多元回归分析

    回归分析是数据分析中最基础也是最重要的分析工具,绝大多数的数据分析问题,都可以使用回归的思想来解决.回归分析的任务就是,通过研究自变量X和因变量Y的相关关系,尝试去解释Y的形成机制,进而达到通过X去预 ...

  5. MySQL实战45讲学习笔记:第七讲

    一.两阶段锁 1.持有哪些锁,以及在什么时候释放 我先给你举个例子.在下面的操作序列中,事务 B 的 update 语句执行时会是什么现象呢? 假设字段 id 是表 t 的主键. 这个问题的结论取决于 ...

  6. 学java怎么做笔记?如何整理java笔记?java学习笔记

    许多开始学Java编程的朋友,都是跟着视频学习的,知道要记笔记,但又不知如何下手.其实笔记主要的还是记框架以及自己能感觉到不懂得地方方便巩固加深印象,笔记不要记得密密麻麻的看着就让人感觉头疼,学习编程 ...

  7. Linux内核笔记--内存管理之用户态进程内存分配

    内核版本:linux-2.6.11 Linux在加载一个可执行程序的时候做了种种复杂的工作,内存分配是其中非常重要的一环,作为一个linux程序员必然会想要知道这个过程到底是怎么样的,内核源码会告诉你 ...

  8. 大学计算机课感悟100字,停课不停学的心得100字 停课不停学的感想

    提到停课不停学的心得100字-你怎样做好停课不停学作文200字,相信大家对停课不停学的感想非常感兴趣,许多人想知道停课不停学,小学电子教材与<课时学练测>教辅和停课不停学的心得100字-你 ...

  9. 【零基础学Java】—对象的内存图(八)

    [零基础学Java]-对象的内存图(八) 一.一个对象的内存图 二.两个对象的内存图 三.使用对象类型作为方法的参数 public class PhoneParam {public static vo ...

最新文章

  1. matlab plot3d_号称轻量级MATLAB的数学工具—Maple 2019.2
  2. 执子之手,与子偕老。你同意么?
  3. SpringBoot AOP完全讲解一:基础概念
  4. leetcode 877. Stone Game | 877. 石子游戏(递归/动态规划/数学解法)
  5. 《Python Cookbook 3rd》笔记(1.4):查找最大或最小的N个元素
  6. JAVA两个视图层_MVC - 管理帐户 . 一个视图有两个局部视图和两个模型
  7. Shiro——RememberMe
  8. 4种基于像素分割的文本检测算法
  9. aws ec2 选择可用区_在AWS EC2上配置SQL Server Always On可用性组
  10. static 关键字
  11. [bzoj 1452] [JSOI2009]Count
  12. Java中的代理模式--静态代理和动态代理
  13. 在售后技术服务里,Kubernetes到底是什么? | 凌云时刻
  14. 整合SSH 遇到错误之一
  15. ajax实现form表单提交
  16. SAP 独立系统的传输请求
  17. 软件工程总结笔记——软件详细设计(五)
  18. 用Andriod studio学习制作APP
  19. 59. 螺旋矩阵 II(中等 数组)
  20. retrofit 解析百度地图api 返回数据_基于百度地图API的城市数据采集方式

热门文章

  1. java 反射解读理解
  2. html如何调整打印区域,怎么调整excel打印区域_教你调整excel打印区域的方法-系统城...
  3. yolov3损失函数改进_YOLO V3 深度解析 (下)
  4. python matplotlib 保存图片失真_Python matplotlib线框失真
  5. 常见机器学习算法思想简单梳理
  6. hdfs读写流程_一篇文章搞清楚 HDFS 基本原理
  7. matlab memorySian,matlab内存溢出的解决方案
  8. 相机姿态估计(六)--EPnP
  9. 数字信号处理--7.3--基础篇
  10. python内容限制_Python --类,实例和访问限制