DELPHI 指针使用用的一篇好文 收藏
DELPHI 指針使用用的一篇好文 收藏
??? Delphi里自己管理內存的兩對函數 new(),dispose()和getmem(),freemem()???
???
??? 大家都認為,C語言之所以強大,以及其自由性,很大部分體現在其靈活的指針運用上。因此,說指針是C語言的靈魂,一點都不為過。同時,這種說法也讓很多人產生誤解,似乎只有C語言的指針才能算指針。Basic不支持指針,在此不論。其實,Pascal語言本身也是支持指針的。從最初的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;??
??????????????????? 只是,Pascal中,只允許對有類型的指針進行這樣的運算,對于無類型指針是不行的。??
???
??????????? 六、動態內存分配。C中,使用malloc()庫函數分配內存,free()函數釋放內存。如這樣的代碼:??
??????????????????? int???? *ptr,???? *ptr2;??
??????????????????? int???? i;??
??????????????????? ptr???? =???? (int*)???? malloc(sizeof(int)???? *???? 20);??
??????????????????? ptr2???? =???? ptr;??
??????????????????? for???? (i=0;???? i<20;???? i++){??
??????????????????????????? *ptr???? =???? i;??
??????????????????????????? ptr++;??
??????????????????? }??
??????????????????? 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()??
??????????????????? {??
??????????????????????????? HMODULE???? hModule???? =???? LoadLibrary("test.dll");??
??????????? PVFN???? pvfn???? =???? NULL;??
??????????????????????????? pvfn???? =???? (PVFN)???? GetProcAddress(hModule,???? "Function1");??
??????????????????????????? pvfn(2);??
??????????????????????????? FreeLibrary(hModule);??
??????????????????? }??
??????????????????? 就我個人感覺來說,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;??
?
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/aroc_lo/archive/2010/04/07/5456930.aspx
總結
以上是生活随笔為你收集整理的DELPHI 指针使用用的一篇好文 收藏的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【项目管理】项目管理计划
- 下一篇: 作者:马晓磊(1985-),男,北京航空