Delphi 关于指针Pointers 和@操作符

摘要:
第2行声明X和Y为整型变量。第六行是P赋值X的地址(用@X表示)。第7行检索P所指位置的值(用^P表示)。这里我们使用@运算符来获取变量的地址,该变量返回存储在指针保存的内存地址中的值。我们的示例似乎是将一个变量的值复制到另一个变量中的迂回方法——这可以通过简单的赋值语句来完成。指针用于任何需要动态分配大内存块的数据类型。

Delphi 关于指针Pointers 和@操作符

1、指针Pointers

指针是如何工作的,例如:

1    var
2      X, Y: Integer;   // X和Y是整数变量 
3      P: ^Integer;     // P指向一个整数 
4    begin
5      X := 17;         // 给X赋值
6      P := @X;         //将X的地址分配给P
7      Y := P^;         // 去参考P;将结果分配给Y,Y的结果:17
8    end;
  • 第2行将X和Y声明为Integer类型的变量。
  • 第3行将P声明为指向整数值的指针;这意味着P可以指向X或Y的位置。
  • 第5行为X赋值,
  • 第6行为P赋值X的地址(用@X表示)。
  • 最后,第7行检索P(用^P表示)指向的位置处的值,并将其分配给Y。
  • 执行此代码后,X和Y具有相同的值,即17。

我们在这里使用 @操作符 获取变量的地址,它也对函数和过程进行操作。有关详细信息,请参见语句和表达式中的@operator和produceral类型。

符号^有两个用途,在我们的示例中说明了这两个用途。当它出现在类型标识符之前时:

^typeName

它表示表示指向typeName类型变量的指针的类型。当它出现在指针变量之后时: 

pointer^

它取消对指针的引用;也就是说,它返回存储在指针持有的内存地址上的值。

我们的示例似乎是一种将一个变量的值复制到另一个变量的迂回方式——这是我们可以用一个简单的赋值语句完成的。

但,指针之所以有用有几个原因:

  • 首先,理解指针将有助于您理解Delphi语言,因为指针通常在代码中的幕后操作,而这些代码并不显式出现。
  • 任何需要动态分配大内存块的数据类型都使用指针。例如,长字符串变量和类实例变量都是隐式指针。此外,一些高级编程技术需要使用指针。
  • 最后,指针有时是绕过Delphi严格的数据类型的唯一方法。通过使用通用指针引用变量,将指针强制转换为更特定的类型,然后取消引用,可以将任何变量存储的数据视为属于任何类型。

例如,以下代码将存储在实变量中的数据分配给整数变量:

type
  PInteger = ^Integer;
var
  R: Single;
  I: Integer;
  P: Pointer;
  PI: PInteger;
begin
  ...
  P := @R;
  PI := PInteger(P);
  I := PI^;
end;

当然,实数和整数以不同的格式存储。这个赋值只是将原始二进制数据从R复制到I,而不进行转换。

除了分配@运算的结果外,还可以使用几个标准例程为指针赋值。New和GetMem过程将内存地址分配给现有指针,而Addr和Ptr函数将返回指向指定地址或变量的指针。

解引用指针可以是限定的,并且可以用作限定符,如表达式 P1^.Data^。

保留字nil是一个特殊常量,可以分配给任何指针。将nil指定给指针时,指针不引用任何内容。

2、关于@操作符  

@运算符返回变量或函数、过程或方法的地址;也就是说,@构造一个指向其操作数的指针。

以下规则适用于@:

  • 如果X是一个变量,@X返回X的地址(当X是程序变量时,特殊规则适用;请参阅语句和表达式中的过程类型。)如果默认的{$T-}编译器指令有效,@X的类型是指针。在{$T+}状态下,@X是^T类型,其中T是X的类型(这种区别对于赋值兼容性很重要,请参见第5-36页的“赋值兼容性”)。
  • 如果F是一个例程(函数或过程),@F返回F的入口点。@F的类型始终是指针。
  • 将@应用于类中定义的方法时,方法标识符必须使用类名限定。例如:
  • @TMyClass.DoSomething
  • 指向TMyClass的剂量测定方法。有关类和方法的更多信息,请参见类和对象。

注意:当使用@运算符时,不可能获取接口方法的地址,因为该地址在编译时未知,并且无法在运行时提取。

 

 

创建时间:2021.08.12  更新时间:

免责声明:文章转载自《Delphi 关于指针Pointers 和@操作符》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇homebrew & brew cask使用技巧及Mac软件安装如何使用vb通过outlook收发邮件下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Delphi管理多线程之线程局部存储:threadvar

尽管多线程能够解决许多问题,但是同时它又给我们带来了很多的问题。其中主要的问题就是:对全局变量或句柄这样的全局资源如何访问?另外,当必须确保一个线程中的某些事件要在另一个线程中的其他时间之前(或之后)发生时,该怎么办?这里将讲解通过使用由 Delphi提供的线程局部存储和 A P I为线程提供同步的方法。 这里先讲线程局部存储,下一篇再讲线程同步 线程局部...

shell分享

shell脚本分享 一、介绍shell Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁。Shell 既是一种命令语言,又是一种程序设计语言。 Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。 Shell 脚本(shell script),是一种为 shell 编写的脚本程序。 业...

ABAP 用指针的方式

首先要定义指针 FIELD-SYMBOLS: <fs_out> LIKE gt_tab_out. 然后在循环赋值时使用ASSIGNING关键字对指针初始化。 LOOP AT lt_tab_out ASSIGNING <fs_out> WHERE aufnr NE space.        READ TABLE lt_afko WI...

Mac下的IDEA快捷键

  快捷键 功能 Option + enter 打开提示 Command + / 注释方式是“行注释”;可以注释当前行、取消当前行的注释 注释选中的内容、取消选中行的注释 Option + Command + / 注释方式为“多行注释”;注释选中的内容、取消注释 Option + Command + L 格式化代码 Comman...

前端动态表单的处理方法

背景: 类似于如下的表单的形式,如果我们提前知道了表单的key,那么我们就可以通过正常的处理表单形式,完成相关数据的获取。 但是,如果我们事先不知道表单的属性key值及对应的输入框还是select框, 那我们就得选择其他方式处理。  步骤一:首先,我们约定,后台返回的格式如下: 其中,code字段的具体值为表单的key,type为到底是输入框还是选择框,...

蓝桥杯Java——安装软件Eclipse以及JDK

蓝桥杯Java——安装软件Eclipse以及JDK 安装Eclipse 安装JDK 检查JDK是否安装成功 安装Eclipse 安装后打开失败 安装Eclipse 安装JDK http://www.oracle.com/technetwork/java/javase/downloads/index.html 选择需要的版本 在页面底部找到如...