pascal語言入門教程(免費(fèi)的編程自學(xué)網(wǎng)站)
發(fā)布時(shí)間:2025-08-18 | 來源:互聯(lián)網(wǎng)轉(zhuǎn)載和整理
指針,是C語言中的一個(gè)重要概念及其特點(diǎn),也是掌握C語言比較困難的部分。指針也就是內(nèi)存地址,指針變量是用來存放內(nèi)存地址的變量,不同類型的指針變量所占用的存儲(chǔ)單元長(zhǎng)度是相同的,而存放數(shù)據(jù)的變量因數(shù)據(jù)的類型不同,所占用的存儲(chǔ)空間長(zhǎng)度也不同。有了指針以后,不僅可以對(duì)數(shù)據(jù)本身,也可以對(duì)存儲(chǔ)數(shù)據(jù)的變量地址進(jìn)行操作
引自百度百科
這里面提到了兩個(gè)比較重要的名詞:指針和指針變量,其實(shí)只要理清楚這兩個(gè)東西就會(huì)感覺指針并不難(基礎(chǔ)使用)
C語言之所以強(qiáng)大,以及其自由性,很大部分體現(xiàn)在其靈活的指針運(yùn)用上。因此,說指針是C語言的靈魂,一點(diǎn)都不為過。
這種說法也讓很多人產(chǎn)生誤解,似乎只有C語言的指針才能算指針。其他語言不支持指針,其實(shí),Pascal語言本身也是支持指針的。從最初的Pascal發(fā)展至今的Object Pascal,可以說在指針運(yùn)用上,絲毫不會(huì)遜色于C語言的指針。
類型指針
類型指針的定義。對(duì)于指向特定類型的指針,在C中是這樣定義的:
int?*ptr;char?*pcr;與之等價(jià)的Object Pascal是如何定義的呢?
varptr?:?^Integer;pcr?:?^char;針對(duì)ptr和pcr這種變量我們就可以稱為指針變量,和普通變量相比而言他們的值不一樣而已,類似于下圖這樣
無類型指針
所謂無類型指針類似于老外心目中的上帝
C中有void *類型,也就是可以指向任何類型數(shù)據(jù)的指針。Object Pascal為其定義了一個(gè)專門的類型:Pointer。于是,ptr : Pointer;就與C中的void *ptr;等價(jià)了。
在新版本的Delphi中其實(shí)很少使用指針了,所以個(gè)人建議無類型指針更應(yīng)該少用甚至不用
基本使用
主要是指針的解除引用和取地址,不說了直接代碼演示
var??//?定義普通變量,因?yàn)槭侨肿兞靠梢灾苯淤x初始值??Age:?Integer?=?10;??//?定義同類型的指針變量,可以使用^數(shù)據(jù)類型的形式,他們是等同的??PAge:?PInteger;begin??//?給指針變量賦值,它只能接收這樣的值??PAge?:=?@Age;??//?獲取指針變量PAge的值,即變量Age的內(nèi)存地址??Writeln(IntToHex(Integer(PAge)));??//?直接獲取變量Age的內(nèi)存地址??Writeln(IntToHex(Integer(@Age)));??//?獲取指針變量中存儲(chǔ)的具體值(解除指針引用)??Writeln(PAge^);??readln;end.上面代碼演示的僅僅為一級(jí)指針,指針是可以嵌套的
指針運(yùn)算
在C中,可以對(duì)指針進(jìn)行移動(dòng)的運(yùn)算,如:
char?a[20];char?*ptr=a;ptr++;ptr+=2;當(dāng)執(zhí)行ptr++;時(shí),編譯器會(huì)產(chǎn)生讓ptr前進(jìn)sizeof(char)步長(zhǎng)的代碼,之后,ptr將指向a[1]。ptr+=2;這句使得ptr前進(jìn)兩 個(gè)sizeof(char)大小的步長(zhǎng)。同樣,我們來看一下Object Pascal中如何實(shí)現(xiàn)
var???a?:?array?[1..20]?of?Char;???ptr?:?PChar;?//PChar?可以看作?^Charbegin???ptr?:=?@a;???Inc(ptr);?//?這句等價(jià)于?C?的?ptr++;???Inc(ptr,?2);?//這句等價(jià)于?C?的?ptr+=2;end;可能我接觸Delphi 的時(shí)間比較短,指針運(yùn)算這一塊我?guī)缀鯖]怎么用過,作為一個(gè)知識(shí)點(diǎn)整理出來
字符數(shù)組的運(yùn)算
C語言中,是沒有字符串類型的,因此,字符串都是用字符數(shù)組來實(shí)現(xiàn),于是也有一套str打頭的庫函數(shù)以進(jìn)行字符數(shù)組的運(yùn)算,
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類型,因此可以很方便地對(duì)字符串進(jìn)行各種運(yùn)算。但是,有時(shí)我們的Pascal代碼需要與C的代碼交互(比如:用 Object Pascal的代碼調(diào)用C寫的DLL或者用Object Pascal寫的DLL準(zhǔn)備允許用C寫客戶端的代碼)的話,就不能使用String類型了,而必須使用兩種語言通用的字符數(shù)組。其實(shí),Object Pascal提供了完全相似C的一整套字符數(shù)組的運(yùn)算函數(shù),以上那段代碼的Object Pascal版本是這樣的:
var?str?:?array?[1..15]?of?char;???pstr?:?PChar;?//Pchar?也就是?^Charbegin???StrCopy(@str,?'teststr');?//在C中,數(shù)組的名稱可以直接作為數(shù)組首地址指針來用????//但Pascal不是這樣的,因此?str前要加上取地址的運(yùn)算符???StrCat(@str,?'_testok');???GetMem(pstr,?sizeof(char)?*?15);???StrCopy(pstr,?@str);???Write(pstr);???FreeMem(pstr);end;函數(shù)指針
函數(shù)指針能用于兩種不同的目的:聲明函數(shù)指針類型的變量;或者把函數(shù)指針作為參數(shù)傳遞給另一例程。
Delphi中可以通過函數(shù)指針把一個(gè)函數(shù)作為參數(shù)來傳遞,然后在另外一個(gè)函數(shù)中調(diào)用。首先,申明函數(shù)指針類型TFunctionParameter
type??????????TFunctionParameter?=?function(const?value?:?integer)?:?string;?//函數(shù)指針定義準(zhǔn)備被作為參數(shù)傳遞的函數(shù)
function?One(const?value?:?integer)?:?string;????????????????????????????//函數(shù)-實(shí)例1begin??result?:=?IntToStr(value)?;end;function?Two(const?value?:?integer)?:?string;????????????????????????????//函數(shù)-實(shí)例2begin??result?:=?IntToStr(2?*?value)?;end;定義將要使用動(dòng)態(tài)函數(shù)指針參數(shù)的函數(shù)
function?DynamicFunction(f?:?TFunctionParameter;?const?value?:?integer)?:?string;begin??result?:=?f(value)?;end;上面這個(gè)動(dòng)態(tài)函數(shù)的使用實(shí)例
var??s?:?string;begin??s?:=?DynamicFunction(One,2006)?;??ShowMessage(s)?;?//will?display?"2006"??s?:=?DynamicFunction(Two,2006)?;??ShowMessage(s)?;?//?will?display?"4012"end;雖然這種調(diào)用方法比直接調(diào)用麻煩了,那么我們?yōu)槭裁匆眠@種方式呢?
例子
//********************************************************//?函數(shù)指針(指向一般函數(shù)和過程)//*********************************************************unit?DelegateUnit;interface?????procedure?Func1;?????//定義兩個(gè)函數(shù)型構(gòu)相同但功能不同的函數(shù)????function????FuncAdd(VarA?,?VarB?:?Integer):Integer;????function????FuncSub(VarA?,?VarB?:?Integer):Integer;type????DelegateFunc1?=?procedure;????DelegateFuncCalc?=?function(VarA?,?VarB?:?Integer):Integer;var??I?:?Integer;implementationprocedure?Func1;begin??????Writeln('Func1?was?called!');end;function????FuncAdd(VarA?,?VarB?:?Integer):Integer;begin?????Result?:=?VarA?+?VarB;end;function????FuncSub(VarA?,?VarB?:?Integer):Integer;begin???Result?:=?VarA?-?VarB;end;end.調(diào)用
program?Delegate;{$APPTYPE?CONSOLE}uses??DelegateUnit;?var????ADelegateFunc1?:?DelegateFunc1;????ADelegateFuncCalc?:?DelegateFuncCalc;?begin?????//通過函數(shù)指針調(diào)用過程?????ADelegateFunc1??:=?Func1;?????ADelegateFunc1?;????//通過同種方式調(diào)用不同函數(shù)????ADelegateFuncCalc??:=?FuncAdd;????Writeln(ADelegateFuncCalc(3,5));????ADelegateFuncCalc??:=?FuncSub;????Writeln(ADelegateFuncCalc(3,5));end.
下一篇:河源社保局電話是多少