我最初有一个被定义为全局变量的数组[1..1000]。但是现在我需要将其设为 n,而不是 1000,并且直到稍后我才知道 n。在填充数组之前我知道 n 是什么,但我需要它是全局的,因此需要一种在运行时定义全局数组大小的方法。
上下文正在用文件中字节的线性变换填充数组。我不知道文件有多大,直到有人想要打开它并且文件可以是任意大小。
我最初有一个被定义为全局变量的数组[1..1000]。但是现在我需要将其设为 n,而不是 1000,并且直到稍后我才知道 n。在填充数组之前我知道 n 是什么,但我需要它是全局的,因此需要一种在运行时定义全局数组大小的方法。
上下文正在用文件中字节的线性变换填充数组。我不知道文件有多大,直到有人想要打开它并且文件可以是任意大小。
从 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 中是特殊的;它们由编译器通过引用计数进行管理。因此,字符串类型的新动态数组元素被初始化为空。但如果我改用整数,则无法保证新元素的值。它们可能为零,但也可能是其他任何值,就像独立局部变量的初始值一样。
有人告诉我,Delphi 7 帮助文件非常好。请在此处阅读有关动态数组的更多信息。您可以在 Delphi 安装中提供的 VCL 和 RTL 源代码以及过去 10 年产生的几乎所有 Delphi 代码示例中找到它们使用的演示。
首先,这是您问题第一部分的一般答案:
如果您的数组不再是静态的,您可能需要考虑使用 TList、TStringList 或 Contnrs 单元中的许多容器类之一。
它们可能更好地代表您正在做的事情,提供您可能需要的其他功能,例如排序或名称/值对,它们会根据您的需要动态增长,并且已经过很好的优化。
然后你说:
“上下文正在用文件中字节的线性变换填充数组。我不知道文件有多大,直到有人想要打开它并且文件可以是任意大小。”
对于您的具体问题,我将使用以下方法加载文件中的字节:
MyFileStream := TFileStream.Create(Filename, fmOpenRead or fmShareDenyWrite); Size := MyFileStream.Size - MyFileStream.Position; SetLength(Buffer, Size); MyFileStream.Read(Buffer[0], Size);
然后,您可以轻松地使用 PChar 指针逐个遍历缓冲区中的每个字符甚至每个字节,并按照您需要的方式对其进行转换。