指针:
一个指针变量指示了内存的位置,在本章介绍 Pchar 类型时,就有使用指针的例子, Pascal 通用
指针类型的名称是 Pointer 。 Pointer 有时又被称为无类型指针,因为它只指向内存地址,但编译器并
不管指针所指向的数据,这一点与 Pascal 严谨的风格似乎不相称,所以建议你在大部分情况下用有类型
的指针。注意指针是一种高级技术,对于编写程序来说不是必须的,当你对它运用熟练以后,它会成为你
写程序的好工具。
有类型指针在你的应用程序的 Type 部分用 ^ (或 Pointer)运算符声明。对于有类型指针来说,编译
器能准确地跟踪指针所指内容的数据类型,这样用指针变量,编译器就能跟踪正在进行的工作。以下是声
明指针的例子。
Type
PInt = ^Integer; // PInt现在是指向 Integer 的指针
Foo = record // 一个记录类型
GobbledyGook: string;
Snarf : Real;
end;
PFoo = ^Foo; // PFoo是一个指向 Foo 类型的指针
var
P: Pointer; // 一个无类型的指针
P2: PFoo; // PFoo的实例
注意C语言的程序员可能注意到了, Object Pascal 的 ^ 运算符与C语言中 * 运算符相似,
Pascal 的 Pointer 类型对应与 C 的 void * 类型。要记住一个指针变量仅仅是存储一个内存的地址,
为指针所指向的内容分配空间是程序员要干的工作,用在前面介绍过的并列在表2 - 6中的内存分配例
程来分配内存。注意如果一个指针没有指向任何数据,它的值是 nil ,它就被称为是零(nil)指针或
空(null) 指针。要访问一个指针所指向的内容,在指针变量名字的后面跟上^运算符。这种方法称为对
指针取内容 //@为取址运算符
什么时候用 New():
用 New() 函数能为一个指针分配指定长度的内存空间。在为某结构分配内存时,因为编译器知道要
分配的内存的大小,所以调用 New() 就能分配到所需的字节,而且它比 GetMem() 或AllocMem()更安全,
更易于使用。但不能用 New() 为 Pointer 或 Pchar 变量分配内存,因为编译器不知道需要分配多大的
内存。另外要记住用 Dispose() 函数来释放用 New() 分配的内存。当编译器不知道要分配多少内存时,
就要用到 GetMem() 和 AllocMem() ,在对 Pchar 和Pointer 类型分配内存时,编译器不可能提前告诉
你要分配多少,因为它们有长度可变特性。要注意,不要试图操作分配空间以外的数据,因为这是导致
"Access Violation" 错误最常见的原因。用 FreeMem() 来释放由 GetMem() 和 AllocMem() 分配的内存。
顺便说一下,AllocMem() 要比GetMem()安全,因为 AllocMem() 总是把分配给它的内存初始化为零。
C程序员在学习 Object Pascal 时感到头痛的是, Object Pascal 对指针类型的检查非常严格,
例如,下面的代码中变量a和变量b并不兼容:
var
a:^Integer;
b:^Integer;
相反在C语言中是兼容的:
int *a;
int *b;
为了让其在PASCAL中兼容,要如下生名:
type
Ptrinteger = ^Integer;
var
a,b:PtrInteger; //现在a和b相兼容了
出处: delphi 5开发人员指南 第2章
*****************************************************************
补充:
ReallocMem 函数说明 }
使用 ReallocMem 重新分配内存后,如果新空间变大,
原有的数据会被复制过来,如果新空间变小,空间中的
内容是原来靠前一部分的内容。
重新分配数据后,空间变大,会占用跟多内存,变小,
原有多余出的空间并不会得到释放,也就是被泄露的空
间,如果新空间的大小变为 0 ,那么分配的空间被释放。
此时可以用 Assigned 函数来进行检测。
针对同一个指针变量 P, 如果使用了FreeMem 函数对其
进行释放操作后,再使用ReallocMem分配空间时会报错。
应该使用AllocMem再次对其进行空间分配。
自定义类型指针使用说明
type
PIntArray = ^TIntArray;
TIntArray = array[0..1] of Integer;
var
P: PIntArray;
此时P是一个指针类型变量,正确的强转操作如下:
PIntArray(P) 或 TIntArray(P^)
对其中数据元素正确的操作方法如下:
PIntArray(P)^[i] 或 TIntArray(P^)[i]
说明:强转操作与其操作数的类型应该一致。
PIntArray的操作数应该是指针P
TIntArray的操作数应该是指针内容P^
注意:由于定义数组的类型的索引范围是0..1
所以强转后的操作范围也是0..1,就是说
最大操作数是PIntArray(P)^[1]。当输入2
是编译不过去,当然可以使用变量代替,但是
不保证其安全性。