Delphi中的動態陣列總結

2022-05-09 01:33:10 字數 3482 閱讀 1527

今天做的乙個專案中要使用一大串資料進行處理。如何對這一系列的資料進行儲存成為乙個首要的問題。唉,delphi啊,你何時才能支援泛型啊。在c#,c++這都不是問題了啊。在delphi裡只有tstringlist這個容器可以使用,但是它是處理字串的。一進一出,需要大量的typecast時間。用鍊錶??不值得。上網一查,呵呵,可以用動態陣列。看來我還是乙個新手,這個東西我都不知道啊。啥時候delphi有了這個玩意了。

vari:array of integer;

begin

setlength(i,length);//設定動態陣列的長度

以後就可以像正常陣列那樣操作

有了動態陣列就可以隨時設定陣列的大小,不會像以前那樣事先定義陣列的大小,對資源造成浪費。

動態陣列的本質還是指標,上面的例子。i 就是乙個指標型別。可以將兩個動態陣列之間進行引用賦值,當然了我們也可以將其複製給乙個pointer,只不過意義不大罷了。

varp:pointer;

i,j:array of integer;

begin

setlength(i,20);//分配記憶體空間

i[0] := 22;

i := j;//此時,i,j都同時指向了那段動態陣列的存

p := i; //沒有實際意義,只是證明了i 是指標型別

//釋放工作

end;

使用完了記憶體當然需要釋放了,否則會造成記憶體洩露。動態陣列使用了 reference-counting 技術,所以在使用完後,只需將其賦值為nil即可。

自從有了動態陣列,鍊錶除了在教科書裡出現外,已經很少在實際程式設計中被使用了,事實也是如此,陣列的確比傳統鍊錶快得多,而且也方便的多。

從 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 的簡易版本。不管怎麼說,了解一些記憶體的分配對我們這些開發人員來說還是有一些好處的。

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 在以上程式中...

Delphi動態陣列介紹

從 delphi4起,開始了內建各種型別的動態陣列支援。但是,對我們來說動態陣列支援似乎做的不夠徹底,因為delphi竟然連刪除 插入 移動連續元素的函式都沒有提供,讓人使用起來總覺得不夠爽!j。作為一名程式設計師,我們當然要有自己解決問題的能力,下面就讓我們簡單介紹一下delphi 下的動態陣列。...

Delphi7 動態陣列

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