簡體   English   中英

Turbo Pascal 中的動態數組

[英]Dynamic array in Turbo Pascal

我正在處理我的學校項目,我想使用動態(非靜態)數組。 我使用過 ObjectPascal,所以我習慣了一些語法。 但是現在我正在使用舊的 TurboPascal 進行編程(我在 Windows 上使用 Turbo Pascal 7)。

它似乎不知道 ObjectPascal,所以我想,你 Turbo Pascal 不知道動態數組。

誰能告訴我,我的理論是否正確? 我試圖谷歌,但我沒有成功。 基本上我是問“Turbo Pascal 7 中的動態數組怎么樣”? 謝謝大家的反應。

正如 MartynA 所說,Turbo Pascal 中沒有動態數組類型。 您需要使用指針手動分配內存,並且在使用范圍檢查時要小心。

通常你定義一個數組類型

TYPE
  TArrayT = array[0.. ((65535-spillbytes) div sizeof(T))-1] of T;

其中溢出字節是一個小扣除的常數,因為您不能使用整個 64k,看看編譯器接受什么。 (可能這個推論是針對 64k 塊內的 heapmanager 結構的)

然后你定義一個指針

  PArrayT= ^TArrayT;

和一個變量

  var 
     P : PArrayT;
      

然后使用 getmem 分配 nrelement 元素;

 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 位的額外大小去哪里了,但是它們是必需的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM