delphi中的指標

2021-04-12 19:02:52 字數 3855 閱讀 8133

從最初的

pascal

發展至今

的object pascal

,可以說在指標運用上,絲毫不會遜色於

c語言的指標。

以下內容分為八個部分,分別是

一、型別指標的定義

二、無型別指標的定義

三、指標的解除引用

四、取位址(指標賦值)

五、指標運算

六、動態記憶體分配

七、字元陣列的運算

八、函式指標

對於指向特定型別的指標,在

c中是這樣定義的:

int *ptr; char *ptr;

與之等價的

object pascal

是如何定義的呢?

var ptr : ^integer; ptr : ^char;

其實也就是符號的差別而已。c中有

void *

型別,也就是可以指向任何型別資料的指標。

object pascal

為其定義了乙個專門的型別:

pointer

。於是,

ptr : pointer; 就與c

中的void *ptr;

等價了。

要解除指標引用(即取出指標所指區域的值),

c 的語法是

(*ptr)

,object pascal

則是ptr^

。取某物件的位址並將其賦值給指標變數,

c 的語法是

ptr = &object; object pascal

則是ptr := @object;

也只是符號的差別而已。在c

中,可以對指標進行移動的運算,如:

char a[20]; char *ptr=a; ptr++; ptr+=2;

當執行ptr++;

時,編譯器會產生讓

ptr前進

sizeof(char)

步長的**,之後,

ptr將指向

a[1]

。ptr+=2;

這句使得

ptr前進兩

個sizeof(char)

大小的步長。同樣,我們來看一下

object pascal

中如何實現:

var a : array [1..20] of char; ptr : pchar; //pchar

可以看作

^char begin ptr := @a; inc(ptr); //

這句等價於c 的

ptr++; inc(ptr, 2); //

這句等價於c 的

ptr+=2; end; c

中,使用

malloc()

庫函式分配記憶體,

free()

函式釋放記憶體。如這樣的**:

int *ptr, *ptr2; int i; ptr = (int*) malloc(sizeof(int) * 20); ptr2 = ptr; for (i=0; i<20; i++) free(ptr2); object pascal

中,動態分配記憶體的函式是

getmem()

,與之對應的釋放函式為

freemem()

(傳統pascal

中獲取記憶體的函式是

new()

和dispose()

,但new()

只能獲得物件的單個實體的記憶體大小,無法取得連續的存放多個物件的記憶體塊)。因此,與上面那段

c的**等價的

object pascal

的**為:

var ptr, ptr2 : ^integer; i : integer; begin getmem(ptr, sizeof(integer) * 20); //

這句等價於c的

ptr = (int*) malloc(sizeof(int) * 20); ptr2 := ptr; //

保留原始指標位置

for i := 0 to 19 do begin ptr^ := i; inc(ptr); end; freemem(ptr2); end;

對於以上這個例子(無論是

c版本的,還是

object pascal

版本的),都要注意乙個問題,就是分配記憶體的單位是位元組(

byte

),因此在使用

getmem

時,其第二個引數如果想當然的寫成

20,那麼就會出問題了(記憶體訪問越界)。因為

getmem(ptr, 20);

實際只分配了

20個位元組的記憶體空間,而乙個整形的大小是四個位元組,那麼訪問第五個之後的所有元素都是非法的了(對於

malloc()

的引數同

樣)。c

語言中,是沒有字串型別的,因此,字串都是用字元陣列來實現,於是也有一套

str打頭的庫函式以進行字元陣列的運算,如以下**:

char str[15]; char *pstr; strcpy(str, "teststr"); strcat(str, "_testok"); pstr = (char*) malloc(sizeof(char) * 15); strcpy(pstr, str); printf(pstr); free(pstr);

而在object pascal

中,有了

string

型別,因此可以很方便的對字串進行各種運算。但是,有時我們的

pascal

**需要與

c的**互動(比如:用

object pascal

的**呼叫c寫的

dll或者用

object pascal

寫的dll

準備允許用

c寫客戶端的**)的話,就不能使用

string

型別了,而必須使用兩種語言通用的字元陣列。其實,

object pascal

提供了完全相似

c的一整套字元陣列的運算函式,以上那段**的

object pascal

版本是這樣的:

var str : array [1..15] of char; pstr : pchar; //pchar

也就是^char begin strcopy(@str, 'teststr'); //在c

中,陣列的名稱可以直接作為陣列首位址指標來用//但

pascal

不是這樣的,因此

str前要加上取位址的運算子

strcat(@str, '_testok'); getmem(pstr, sizeof(char) * 15); strcopy(pstr, @str); write(pstr); freemem(pstr); end;

在動態呼叫

dll中的函式時,就會用到函式指標。假設用

c寫的一段**如下:

typedef int (*pvfn)(int); //

定義函式指標型別

int main()

就我個人感覺來說,

c語言中定義函式指標型別的

typedef

**的語法有些晦澀,而同樣的**在

object pascal

中卻非常易懂:

type pvfn = function (para : integer) : integer; var fn : pvfn; //

也可以直接在此處定義,如:

fn : function (para:integer):integer; hm : hmodule; begin hm := loadlibrary('test.dll'); fn := getprocaddress(hm, 'function1'); fn(2); freelibrary(hm); end;

delphi中的指標

從最初的 pascal 發展至今 的object pascal 可以說在指標運用上,絲毫不會遜色於 c語言的指標。以下內容分為八個部分,分別是 一 型別指標的定義 二 無型別指標的定義 三 指標的解除引用 四 取位址 指標賦值 五 指標運算 六 動態記憶體分配 七 字元陣列的運算 八 函式指標 對於...

delphi中函式指標的使用

delphi中可以通過函式指標把乙個函式作為引數來傳遞,然後在另外乙個函式中呼叫。1 首先,申明函式指標型別tfunctionparameter type tfunctionparameter function const value integer string 函式指標 2 定義準備被作為引數傳...

Delphi指標認識

大家都認為,c語言之所以強大,以及其自由性,很大部分體現在其靈活的指標運用上。因此,說指標是c語言的靈魂,一點都不為過。同時,這種說法也讓很多人 產生誤解,似乎只有c語言的指標才能算指標。basic不支援指標,在此不論。其實,pascal語言本身也是支援指標的。從最初的pascal發展至今的obje...