[英]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.