從最初的
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...