我正在做我的学校项目,我想使用动态(非静态)数组。我使用过 ObjectPascal,所以我习惯了一些语法。但现在我在旧的 TurboPascal 中编程(我使用的是 Turbo Pascal 7 for Windows)。
它似乎不知道 ObjectPascal,所以我想,你 Turbo Pascal 不知道动态数组。
谁能告诉我,我的理论是否正确?我试图谷歌,但我没有成功。基本上我在问“Turbo Pascal 7 中的动态数组怎么样”?谢谢大家的反应。
我正在做我的学校项目,我想使用动态(非静态)数组。我使用过 ObjectPascal,所以我习惯了一些语法。但现在我在旧的 TurboPascal 中编程(我使用的是 Turbo Pascal 7 for Windows)。
它似乎不知道 ObjectPascal,所以我想,你 Turbo Pascal 不知道动态数组。
谁能告诉我,我的理论是否正确?我试图谷歌,但我没有成功。基本上我在问“Turbo Pascal 7 中的动态数组怎么样”?谢谢大家的反应。
正如 MartynA 所说,Turbo Pascal 中没有动态数组类型。您需要使用指针手动分配内存,并且在使用范围检查时要小心。
通常你定义一个数组类型
TYPE
TArrayT = array[0.. ((65535-spillbytes) div sizeof(T))-1] of T;
其中spillbytes 是一个小扣除的常数,因为您不能使用整个64k,请查看编译器接受的内容。(可能这个推论是针对 64k 块内的堆管理器结构)
然后你定义一个指针
PArrayT= ^TArrayT;
和它的一个变量
var
P : PArrayT;
并且您使用 getmem 分配 nreelement 元素;
getmem(P,SizeOf(T) * nrelements);
并且可以选择用零填充它们以初始化它们:
fillchar(p^,SizeOf(T) * nrelements,#0);
您可以使用访问元素
p^[index]
要释放它们,请使用与 getmem 行完全相反的 freemem。
freemem(P,Sizeof(T)*nrelements);
这意味着您必须将分配的元素数量保存在某处。这在 Delphi 和 FPC 中已修复/解决。
还要记住,您再也找不到范围检查的错误了。
如果您想要大于 64k 的数组,这是可能的,但仅限于限制,并且更重要的是确切的 TP 目标(dos、dos-protected 或您使用的 Windows)我建议您搜索具有许多示例的在线 SWAG 存档. 当然,我也建议您去 FreePascal/Lazarus,您可以简单地执行以下操作:
var x : array of t;
begin
setlength(x,1000000);
并在没有额外的行的情况下完成它,忘记所有这些废话。
我正在使用 Turbo Pascal 5.5 并创建一个动态数组,也许诀窍是声明一个零维数组,如下所示:
dArray = array [0..0] of integer;
然后声明一个指向该数组的指针:
pArray = ^dArray ;
最后,创建一个指针变量:
ArrayPtr : pArray;
您现在可以ArrayPtr
按如下方式引用指针变量:
ArrayPtr^[i]; { The index 'i' is of type integer}
请参阅下面的完整示例:
{
Title: dynarr.pas
A simple Pascal program demonstrating dynamic array.
Compiled and tested with Turbo Pascal 5.5.
}
program dynamic_array;
{Main Program starts here}
type
dArray = array [0..0] of integer;
pArray = ^dArray ;
var
i : integer;
ArrayPtr : pArray;
begin
for i := 0 to 9 do { In this case, array index starts at 0 instead of 1. }
ArrayPtr^[i] := i + 1;
writeln('The Dynamic Array now contains the following:');
writeln;
for i := 0 to 9 do
writeln(ArrayPtr^[i]);
end.
在此示例中,我们将数组声明为:
array[0..0] of integer;
因此,索引从 0 开始,如果我们有 n 个元素,则最后一个元素位于索引 n-1,这类似于 C/C++ 中的数组索引。
常规 Pascal 数组从 1 开始,但在这种情况下,它从 0 开始。
unit Vector;
interface
const MaxVector = 8000;
// 64 k div SizeOf(float); number of float-values that fit in 64 K of stack
VectorError: boolean = False;
// toggle if error occurs. Calling routine can handle or abort
type
VectorStruc = record
Length: word;
Data: array [1..MaxVector] of float;
end;
VectorTyp = ^VectorStruc;
procedure CreateVector(var Vec: VectorTyp; Length: word; Value: float);
{ Generates a vector of length Length and sets all elements to Value }
procedure DestroyVector(var Vec: VectorTyp);
{ release memory occupied by vector }
procedure SetVectorElement(var Vec: VectorTyp; n: word; c: float);
function GetVectorElement(const Vec: VectorTyp; n: word): float;
implementation
var ch: char;
function WriteErrorMessage(Text: string): char;
begin
Write(Text);
Read(WriteErrorMessage);
VectorError := True; // toggle the error marker
end;
procedure CreateVector(var Vec: VectorTyp; Length: word; Value: float);
var
i: word;
begin
try
GetMem(Vec, Length * SizeOf(float) + SizeOf(word) + 6);
except
ch := WriteErrorMessage(' Not enough memory to create vector');
exit;
end;
Vec^.Length := Length;
for i := 1 to Length do
Vec^.Data[i] := Value;
end;
procedure DestroyVector(var Vec: VectorTyp);
var
x: word;
begin
x := Vec^.Length * SizeOf(float) + SizeOf(word) + 6;
FreeMem(Vec, x);
end;
function VectorLength(const Vec: VectorTyp): word;
begin
VectorLength := Vec^.Length;
end;
function GetVectorElement(const Vec: VectorTyp; n: word): float;
var
s1, s2: string;
begin
if (n <= VectorLength(Vec)) then
GetVectorElement := Vec^.Data[n]
else
begin
Str(n: 4, s1);
Str(VectorLength(Vec): 4, s2);
ch := WriteErrorMessage(' Attempt to read non-existent vector element No ' +
s1 + ' of ' + s2);
end;
end;
procedure SetVectorElement(var Vec: VectorTyp; n: word; C: float);
begin
if (n <= VectorLength(Vec)) then
Vec^.Data[n] := C
else
ch := WriteErrorMessage(' Attempt to write to non-existent vector element');
end;
end.
只要您的数据适合堆栈,即小于 64 kB,任务就相对简单。我唯一不知道的是 6 位额外尺寸的去向,但是它们是必需的。