Delphi動態陣列介紹

2021-04-20 08:55:38 字數 2793 閱讀 6308

從 delphi4起,開始了內建各種型別的動態陣列支援。但是,對我們來說動態陣列支援似乎做的不夠徹底,因為delphi竟然連刪除、插入、移動連續元素的函式都沒有提供,讓人使用起來總覺得不夠爽!!!

j。作為一名程式設計師,我們當然要有自己解決問題的能力,下面就讓我們簡單介紹一下delphi 下的動態陣列。

在delphi中,陣列型別有靜態陣列(a : array[0..1024] of integer)、動態陣列(var a : array of integer)、指標陣列(即指向靜態陣列的指標)和開放陣列(僅用於引數傳遞)。靜態陣列、指標陣列有速度快的好處,動態陣列有大小可變的優勢,權衡之下就有了折衷的辦法,那就是定義的動態陣列在必要時轉換為指標。

動態陣列宣告之後,只有下面幾個函式可供操作:

1.設定陣列大小,可以任意縮減或增加陣列大小

procedure setlength(var s ; newlength : integer);

2.取出連續元素,複製給另乙個陣列變數

function copy(s;index,count : integer) : array ;

3.取得陣列大小及上下限

function length(s):integer;

function high(x):integer;

function low(x):integer;

值得注意的是,不加const或var修飾的動態陣列會被作為形參傳遞,而動態陣列用const修飾並不意味著你不能修改陣列裡的元素(不信你可以字自己在程式中試試。還有一點是high函式呼叫了length 函式,所以我們在獲取陣列上限時最好直接用 length(s) 函式。

動態陣列在記憶體空間中占用4個位元組.   動態陣列在記憶體中的分配表如下:

偏移量                                     內容

-8                                   32-bit 引用計數

-4                                   32-bit 陣列長度

0..陣列長度 * (元素尺寸) - 1 陣列元素    元素尺寸=sizeof(元素型別)

根據上面的分配情況,可以得到如下結果:

如果我們想要清空乙個動態陣列只需要把「陣列長度」和「引用計數」清空即可。」引用上面的一句話就是:「權衡之下就有了折衷的辦法,那就是定義的動態陣列在必要時轉換為指標。」下面是清空動態陣列的函式:

procedure dynarraysetzero(var a);

varp: plongint; //占用4個位元組,正好符合 32 位記憶體排列

begin

p := plongint(a); // 指向 a 的位址

dec(p); //p 位址偏移量是 sizeof(a),指向了陣列長度

p^ := 0; // 長度清空

dec(p); // 指向引用計數

p^ := 0; //計數清空。

end;

上面的函式就這麼簡單,而且效率也非常高。

下面讓我們再來看看怎樣刪除動態陣列中的元素,函式體如下:

procedure dynarraydelete(var a; elsize: longint; index, count: integer);

varlen, maxdelete: integer;

p : plongint; //4 個位元組的長整形指標

begin

p := plongint(a);// 取的 a 的位址

if p = nil then

exit;

len := plongint(pchar(p) - 4)^; // 變數的長度 ,偏移量 -4

if index >= len then //要刪除的位置超出範圍,退出

exit;

maxdelete := len - index; // 最多刪除的數量

count := min(count, maxdelete); // 取得乙個較小值

if count = 0 then // 不要求刪除

exit; 

dec(len, count);// 移動到要刪除的位置

movememory(pchar(p)+index*elsize , pchar(p)+(index + count)*elsize , (len-index)*elsize); //移動記憶體

dec(p); //移出 「陣列長度」位置

dec(p); //移出「引用計數」 位置

//重新再分配調整記憶體,len 新的長度. sizeof(longint) * 2 = 2*dec(p)

reallocmem(p, len * elsize + sizeof(longint) * 2);

inc(p); // 指向陣列長度

p^ := len; // new length

inc(p); // 指向陣列元素,開始的位置

plongint(a) := p;

end;

對上面的例子,我們需要注意的是 elsize 引數 ,它必須是 sizeof(dyarray_name),表示元素所占用的位元組數。

相信看了上面的例子後,對於動態陣列的拷貝,移動想必也可以自己實現了吧

j後續:

其實,delphi 對許多態別的記憶體分配都很相似,比如 string 型別,其實它和動態陣列是很相似的,我們完全可以把它拿來當成動態陣列。實質上 string 是 pchar 的簡易版本。不管怎麼說,了解一些記憶體的分配對我們這些開發人員來說還是有一些好處的。

詳細參考:http://www.codes51.com/article/detail_100322.html

Delphi 動態陣列

1 動態陣列是指標嗎?動態陣列通常會表現出指標功能,先看下面的例子 procedure dymarrtest vara,b array of integer begin setlength a,3 a 0 0 b a b 0 1 showmessage inttostr a 0 end 在以上程式中...

Delphi7 動態陣列

初學delphi,感覺.這感覺就是寫 太費勁了,已經習慣了c 那種信手拈來,不能說pascal不適應只能說還是費勁,可能是d7太老了,也可能是我還沒有上道兒,就這麼著吧,下面簡單的寫倆函式作為參考,修改修改可以當c 中的list 用arr array of string procedure add ...

Delphi中的動態陣列總結

今天做的乙個專案中要使用一大串資料進行處理。如何對這一系列的資料進行儲存成為乙個首要的問題。唉,delphi啊,你何時才能支援泛型啊。在c c 這都不是問題了啊。在delphi裡只有tstringlist這個容器可以使用,但是它是處理字串的。一進一出,需要大量的typecast時間。用鍊錶?不值得。...