^符号有两个用途,在我们的例子中都用到了。当它出现在一个类型标志符前面时:
^typeName
它表示一个指向typeName 类型的变量的指针;当它出现在一个指针变量的后面时:
pointer^
它表示对指针解除引用,换句话说,它返回在指针所指向的地址处保存的值。
除了使用@运算符,你也可以使用几个标准例程给一个指针赋值。New 和GetMem 过程把一个内存地址
赋给指针,而Addr 和Ptr 函数则返回一个指向特定变量或地址的指针。
保留字nil 是一个特殊常量,可赋给任何指针(类型)。当nil 被赋给一个指针时,指针不表示任何东西。
使用下面的语法,你能声明一个任意类型的指针,
type pointerTypeName = ^type
当定义一个记录类型(或其它数据类型)时,习惯上也就定义了一个此类型的指针,这使得处理更容易,
我们不需要拷贝一大块内存。
在Pointer 类型变量的后面使用^运算符会引发编译错误。要访问一个Pointer 类型引用的变量,首先把它
转换为其它指针类型,然后再解除引用。
基本(fundamental)类型PAnsiChar 和PWideChar 分别表示AnsiChar 和WideChar 值的指针,一般(generic)
类型PChar 表示一个指向Char 的指针(在当前实现中,它表示AnsiChar)。这些字符指针用来操纵零结
尾字符串
System 和SysUtils 单元定义了许多常用的标准指针类型:
Pointer type Points to variables of type
PAnsiString,PString AnsiString
PByteArray TByteArray (declared in SysUtils).
Used to typecast dynamically allocated memory for array access.
PCurrency,PDouble,
PExtended,PSingle Currency,Double,Extended,Single
PInteger Integer POleVariant OleVariant
PShortString ShortString. Useful when porting legacy code that uses the old PString type.
PTextBuf TTextBuf (declared in SysUtils).
TTextBuf is the internal buffer type in a TTextRec file record.)
PVarRec TVarRec (declared in System)
PVariant Variant
PWideString WideString
PWordArray TWordArray (declared in SysUtils).
Used to typecast dynamically allocated memory for arrays of 2-byte values.
过程类型允许你把过程和函数作为“值”看待,它可以赋给变量或传给其它过程和函数。比如,假设你
定义了一个叫做Calc 的函数,它有两个整型参数并返回一个整数值:
function Calc(X,Y: Integer): Integer;
你可以把Calc 函数赋给变量F:
var F: function(X,Y: Integer): Integer;
F := Calc;
我们只取过程或函数头(heading)并把procedure 或function 后面的标志符去掉,剩下的就是过程类型
的名称。
可以在声明变量时直接使用这样的名称(就像上面的例子一样),也可以声明新类型:
type
TIntegerFunction = function: Integer;
TProcedure = procedure;
TStrProc = procedure(const S: string);
TMathFunc = function(X: Double): Double;
var
F: TIntegerFunction; {F 是一个无参数、返回整数值的函数}
Proc: TProcedure; { Proc 是一个无参数过程}
SP: TStrProc; { SP 是一个使用string 类型参数的过程}
M: TMathFunc; { M 是一个使用Double 类型参数、返回Double 值的函数}
procedure FuncProc(P: TIntegerFunction); { FuncProc 是一个过程,它的参数是一个无参数、返回整数值的函数}
上面的所有变量都是过程指针,也就是指向过程或函数地址的指针。若想引用一个实例对象的方法(参
考Classes and objects),你需要在过程类型的名称后面加上of object。比如
type
TMethod = procedure of object;
TNotifyEvent = procedure(Sender: TObject) of object;
这些类型表示方法指针。方法指针实际上是一对指针:第一个存储方法的地址,第二个存储方法所属的
对象的引用。给出下面的声明
type
TNotifyEvent = procedure(Sender: TObject) of object;
TMainForm = class(TForm)
procedure ButtonClick(Sender: TObject);
...
end;
var
MainForm: TMainForm;
onClick: TNotifyEvent
我们就可以进行下面的赋值:
onClick := MainForm.ButtonClick;
两个过程类型是兼容的,如果它们具有
􀁺 相同的调用约定,
􀁺 相同类型的返回值(或没有返回值),并且具有
􀁺 相同数目的参数,并且相应位置上的类型也相同(参数名无关紧要)
过程指针和方法指针是不兼容的。nil 可以赋给任何过程类型。
嵌套的过程和函数(在其它例程中声明的例程)不能被用作过程类型值,内置的过程和函数也不可以。
若想使用内置的过程作为过程类型值,比如Length,你可以给它加一个包装:
function FLength(S: string): Integer;
begin
Result := Length(S);
end;
。要比较F 和MyFunction 的过程值,使用
if @F = @MyFunction then ...;
@F 把F 转换为无类型指针变量,它包含的是地址,@MyFunction 返回的是MyFunction 的地址。
要取得过程变量的内存地址(而不是它包含的地址),使用@@。比如,@@F 返回F 的地址。
@运算符也可以用来把一个无类型指针值赋给过程变量,比如
var StrComp: function(Str1, Str2: PChar): Integer;
...
@StrComp := GetProcAddress(KernelHandle, ’lstrcmpi’);
调用GetProcAddress 函数,并使StrComp 指向结果。
要测试一个过程变量是否被赋值,使用标准函数Assigned:
if Assigned(onClick) then onClick(X);
分享到:
相关推荐
在VARIANT的vt成员的 值如果包含VT_ARRAY|...,那么它所封装的就是一个SafeArray,它的parray成员即是指向SafeArray的指针。 SafeArray中元素的类型可以是VARIANT能封装的任何类型,包括VARIANT类型本身。 Delphi中...
6. **内存管理和性能优化**:理解Delphi中的内存管理机制,如引用计数和智能指针,以及如何进行性能优化,是提升程序效率的关键。 7. **网络编程**:Delphi提供了许多网络通信组件,如 Indy,使得开发者能够轻松地...
Delphi TreeView 使用笔记 Delphi 的 TreeView 控件是树形结构的视图控件,用于展示层次结构的数据。TreeView 由节点构成,通过对 TreeView.items 属性进行操作。Items 是一个 TTreeNodes 对象,这是一个 ...
### Delphi 学习笔记知识点总结 #### 一、Delphi 概览 Delphi 是由 Borland 公司开发的一款强大的集成开发环境(Integrated Development Environment, IDE),它主要用于快速开发 Windows 平台下的应用程序。...
Delphi TreeView笔记 Delphi 中的 TreeView 控件是一种常用的树形结构控件,常用于显示树形结构的数据。下面是 Delphi TreeView 的各种知识点。 TreeView 的基本结构 TreeView 由节点构成,节点是 TreeView 的...
本学习笔记将从创建第一个DirectShow程序开始,帮助你深入理解这一技术的核心概念和实现步骤。 DirectShow主要由两部分组成:Filter Graph(过滤器图)和Filters(过滤器)。Filter Graph是整个系统的核心,它负责...
这个"学习笔记:32/64位列举系统进程名称和ID"的主题聚焦于使用Delphi 2010编程环境来实现这一功能,同时兼容32位(x86)和64位(x64)操作系统,如Windows XP、Windows 7以及Windows 8。下面我们将详细探讨这一主题...
编程语言从第一代的机器语言(由0和1组成)发展到第二代的汇编语言,再到第三代的高级语言,如C、C++、Java、Delphi和Basic。这些高级语言提供了更接近自然语言的语法,提高了编程效率。 ### Java语言的发展史 ...
这通过调用`DirectSoundEnumerate`函数来实现,这个函数接收两个参数:一个是回调函数`DSEnumCallBack`的指针,另一个是自定义的上下文指针`lpContext`。 回调函数`DsEnumProc`具有特定的原型,它会被系统中的每个...
幻灯片母版通常包含多个占位符,用于放置标题、内容、页脚等信息,而备注母版则主要用于添加演讲者笔记,其占位符布局可能与幻灯片母版不同。题中提到的选项A和D描述了幻灯片母版和备注母版的占位符数量,都是正确的...