turbopascal中的动态数组

turbopascal中的动态数组,pascal,dynamic-arrays,delphi,turbo-pascal,Pascal,Dynamic Arrays,Delphi,Turbo Pascal,我正在做我的学校项目,我想使用动态(而不是静态)数组。我使用ObjectPascal,所以我习惯了一些语法。但现在我正在使用旧的TurboPascal编程(我正在使用适用于Windows的TurboPascal7) 它似乎不知道ObjectPascal,所以我想,你不知道动态数组 谁能告诉我,我的理论对不对?我试着用谷歌搜索,但没有成功。 基本上,我是在问“在Turbo Pascal 7中,动态数组的性能如何?”? 谢谢大家的反应。正如MartynA所说,Turbo Pascal中没有动态数组类

我正在做我的学校项目,我想使用动态(而不是静态)数组。我使用ObjectPascal,所以我习惯了一些语法。但现在我正在使用旧的TurboPascal编程(我正在使用适用于Windows的TurboPascal7)

它似乎不知道ObjectPascal,所以我想,你不知道动态数组

谁能告诉我,我的理论对不对?我试着用谷歌搜索,但没有成功。 基本上,我是在问“在Turbo Pascal 7中,动态数组的性能如何?”?
谢谢大家的反应。

正如MartynA所说,Turbo Pascal中没有动态数组类型。您需要使用指针手动分配内存,如果使用范围检查,请小心

通常定义一个数组类型

TYPE
  TArrayT = array[0.. ((65535-spillbytes) div sizeof(T))-1] of T;
如果spillbytes是一个常量,用于一个小的推断,因为您不能使用整个64k,请查看编译器接受什么。(此扣减可能适用于64k块内的heapmanager结构)

然后定义一个指针

  PArrayT= ^TArrayT;
还有一个变量

  var 
     P : PArrayT;
      
使用getmem分配nElement元素

 getmem(P,SizeOf(T) * nrelements);
并可选地将其填充为零以进行初始化:

 fillchar(p^,SizeOf(T) * nrelements,#0);
您可以使用

 p^[index]
要释放它们,请使用与getmem行完全相反的freemem

 freemem(P,Sizeof(T)*nrelements);
这意味着您必须将分配的元素数量保存在某个位置。这在德尔福和FPC中得到了修复/解决

还要记住,你再也找不到范围检查的bug了

如果您想要大于64k的阵列,这是可能的,但只有在有限制的情况下,而且更重要的是使用哪个确切的TP目标(dos、dos保护或Windows),我建议您搜索具有许多示例的联机SWAG存档。当然,我建议你也去FreePascal/Lazarus,在那里你可以简单地做到:

 var x : array of t;
 begin
    setlength(x,1000000);

在不增加行的情况下使用它,忘记所有这些废话。

我使用的是Turbo Pascal 5.5,要创建一个动态数组,可能诀窍是声明一个零维数组,如下所示:

dArray = array [0..0] of integer;
ArrayPtr^[i]; { The index 'i' is of type integer}
然后声明指向该数组的指针:

pArray = ^dArray ;
最后,创建一个指针变量:

ArrayPtr : pArray;
您现在可以引用指针变量
ArrayPtr
,如下所示:

dArray = array [0..0] of integer;
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.  
接口 常数MaxVector=8000; //64k div SizeOf(浮动);适合64 K堆栈的浮点值数 向量错误:布尔值=False; //发生错误时切换。调用例程可以处理或中止 类型 向量=记录 长度:字; 数据:浮点数组[1..MaxVector]; 结束; VectorTyp=^VectorStruc; 过程CreateVector(var-Vec:vectoryp;长度:字;值:浮点); {生成长度向量并将所有元素设置为值} 程序向量(var-Vec:VectorTyp); {释放向量占用的内存} 过程设置向量元素(var-Vec:vectoryp;n:word;c:float); 函数getVectoreElement(const-Vec:vectoryp;n:word):float; 实施 var-ch:char; 函数WriteErrorMessage(文本:字符串):char; 开始 写(文本); 读取(写入错误消息); 向量错误:=真;//切换错误标记 结束; 过程CreateVector(var-Vec:vectoryp;长度:字;值:浮点); 变量 一:字; 开始 尝试 GetMem(Vec,长度*SizeOf(float)+SizeOf(word)+6); 除了 ch:=WriteErrorMessage('内存不足,无法创建向量'); 出口 结束; 向量长度:=长度; 对于i:=1到长度do 向量数据[i]:=值; 结束; 程序向量(var-Vec:VectorTyp); 变量 x:单词; 开始 x:=Vec^.Length*SizeOf(float)+SizeOf(word)+6; FreeMem(Vec,x); 结束; 函数向量长度(const-Vec:vectoryp):字; 开始 向量长度:=Vec^.Length; 结束; 函数getVectoreElement(const-Vec:vectoryp;n:word):float; 变量 s1,s2:字符串; 开始
if(n)你可以用指针实现一个“动态数组”。Google for it.TP7没有像Delphi中的ObjectPascal那样的动态数组。然而,当时的一个技巧是将数组声明为数组[0..0]对于整数,然后使用GetMem为任意大小的数组分配空间,并通过指针访问它。这可能是@darkl的想法。是的,我发现了带有指针的动态数组,但我一点也不喜欢,我在寻找更“优雅”的数组方法。感谢您的快速帮助。您需要使用TP7吗?@MartynA不确定他们为什么不使用免费Pascal。或者FPC许可证限制教育用途吗?TP7有对象,所以动态数组类型(对于一种类型)可以包装在对象中。这就是我要做的。隐藏所有难看的细节并使它们非常可用。对象可以有方法访问,例如
函数Get(Index):Integer
过程Put(Index,Value:Integer);
,等等。初始长度可以在构造函数中设置:
构造函数Init(Len:Integer);
等。可以使用TP-tcollection(它更像Delphi-TList,而不是Delphi-tcollection)但无论哪种方法都是对过时代码的投资,最好转向FPC,在FPC中,动态数组甚至可以在16位dos应用程序中工作。不过,我不想全部为负,所以这就是为什么会有这样的报道。但问题应该是清楚的,如果你要做以数据为中心的编码,就不要投资于TP。我同意FPC是一个更好的选择。我必须尝试这一点-推出TP7,DOSBox,输入代码,编译并运行。仅供参考,dArray可以是任何范围,只要开始和结束相同,[1..1](帮助Pascal的人保持1为基础,当然更新for循环)。