当前位置:  开发笔记 > 编程语言 > 正文

如果在运行时间之前我不知道长度,我该如何声明一个数组?

如何解决《如果在运行时间之前我不知道长度,我该如何声明一个数组?》经验,为你挑选了1个好方法。

我最初有一个数组[1..1000]被定义为全局变量.但是现在我需要那个是n,而不是1000,直到后来才发现n.我知道在填充数组之前n是什么,但我需要它是全局的,因此需要一种方法来在运行时定义全局数组的大小.

Context使用文件中字节的线性转换填充数组.我不知道文件有多大,直到有人想要打开它并且文件可以是任何大小.



1> Rob Kennedy..:

从Delphi 4开始,Delphi支持动态数组.您可以在运行时修改它们的大小,它们将保留您存储在旧大小的其他元素中的数据.它们可以包含任何同类型的元素,包括记录和其他数组.您可以声明一个动态数组,就像声明普通的"静态"数组一样,但只是省略数组边界:

var
  ArthurArray: array of TForm;

虽然静态数组允许您指定下限和上限,但动态数组的低索引始终为零.高索引由High函数给出,它总是返回一个小于数组长度的函数.对于任何动态数组x,High(x) = Length(x)-1.

任何代码都可以访问全局变量,包括本地过程.

动态数组类型的全局变量将初始化为数组.它的长度为零,并且High调用该数组将为-1.Low在该数组上仍将返回零.

您可以随时调整动态数组的大小.使用该SetLength函数,就像使用字符串一样:

var
  NumElements: Integer;
begin
  NumElements := GetNumberOfArthurForms();
  SetLength(ArthurArray, NumElements);
end;

如果您有一个多维数组,可以在循环中设置它们的长度:

var
  matrix: array of array of Double;
  i: Integer;
begin
  SetLength(matrix, height);
  for i := 0 to height - 1 do
    SetLength(matrix[i], width);
end;

有一个快捷方式可以同时设置所有内部数组的长度:

begin
  SetLength(matrix, height, width);
end;

就像我提到的那样,动态数组在调整大小时会保留旧值:

var
  data: array of string;
begin
  SetLength(data, 2);
  data[1] := 'foo';
  SetLength(data, 20);
  Assert(data[1] = 'foo');
end;

但是如果你缩短数组,那么任何超出新的最后一个元素的元素都将永远消失:

begin
  SetLength(data, 20);
  data[15] := 'foo';
  SetLength(data, 2);
  // data[15] does not exist anymore.
  SetLength(data, 16);
  writeln(data[15); // Should print an *empty* line.
end;

我上面的演示使用了字符串.字符串在Delphi中很特别; 它们由编译器通过引用计数进行管理.因此,string类型的新动态数组元素被初始化为空.但是如果我使用了整数,那么就不能保证新元素的值.它们可能为零,但它们也可能是其他任何东西,就像独立局部变量的初始值一样.

我被告知,Delphi 7的帮助文件非常好.请阅读有关动态数组的更多信息.您可以在Delphi安装中提供的整个VCL和RTL源代码中找到它们的使用示例,以及过去10年中生成的几乎所有Delphi代码示例.


实际上,当你扩展动态数组时,数组中新条目的内存保证被清零,这意味着整数为0,指针为NIL,字符串(长字符串和短字符串)为空.我一直无法在帮助中找到它,但是当跟踪SetLength的代码时,它以调用FillChar结束,清除额外分配的内存.
+1,非常完整的答案。令人印象深刻。现在,请有人编辑问题摘要以包括“ Delphi”和“动态数组”,以便人们可以在搜索中找到它。
这是一个相对较新的开发,@ Heartware。如您所说,它没有以这种方式工作的文档,因此,就像我说的那样,这并不能保证,实际上,[该文档甚至说](http://docwiki.embarcadero.com/VCL/en/System .SetLength)。当前的实现采用简单的方法,并且总是初始化新元素。我敢肯定,以前的汇编程序实现使用数组的RTTI来确定需要进行哪些初始化。下一个实现可以回到这种方式。FillChar的新的更快的实现也许消除了汇编程序版本。
我需要将以前的评论修改为@Heartware。在我发布该文档时,链接的文档说“新分配空间的内容未定义”。*现在*,它表示“新分配的空间设置为0或nil”。它在Delphi 2010和Delphi XE2之间进行了更改。据我所知,实际的*行为*永远都是一样的。
推荐阅读
黄晓敏3023
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有