Skip to content

从指针到引用


引用并不完全提供与指针相同的功能,但使用引用可以简化编码。

前言:

引用和指针密切相关。

实际上,变量及其不同的引用持有相同的地址,因为它们允许访问相同的对象。

引用封装了对象地址的操作,并作为已解引用的指针使用。

区别在于不必执行解引用操作。

引用比指针更容易处理,因此使代码更安全。

指针回顾

地址是一个值。用户可以将此值存储在变量中。指针正是包含其他对象地址的变量,例如另一个变量的地址。

指针的值可以改变。这通常不意味着被指向的变量在内存中移动,而是指针指向了其他东西。

为了明确指针指向什么,指针有类型。这种类型通常从被指向对象的类型构建。这允许编译器验证通过指针在内存中进行的操作是否有效。

指针最常见的用途是作为过程的参数传递。它们能够以简单的方式操作可能很重要的数据(不必向过程提供非常大的数据块,可以例如提供指向它的指针)。

另一种用途是在内存中进行动态分配时,使用返回已分配内存地址的 '[C]Allocate' 和 'New' 关键字。这个地址必须存储在某处并知道如何使用它。

最后,指针也可以用于操作表,但在 FB 中其重要性较低,因为用户有能力声明静态和动态数组,并使用专用的 '()' (数组索引)运算符访问其元素。

还可以创建指向过程的指针,并使用这些指针参数化算法,该算法的行为将取决于所指向的过程。

非常重要的是,确保用户正在操作的所有指针都已初始化(即它们包含有效对象的地址,而不是随机内容)。实际上,通过未初始化的指针访问变量,相当于在内存中完全随机的位置进行读取,或更严重地进行写入(根据创建时指针的初始值)。

通常,指针在创建时立即初始化,或者如果要在以后使用,则用空值初始化。这将允许对指针有效性进行未来测试,或至少检测错误。实际上,使用具有空值的指针访问变量通常会产生程序保护错误,但如果使用 '-exx' 选项编译程序,将在运行时始终产生错误消息。

使用解引用运算符 '*' 和 '[]',可以从指针访问变量。

'Any Ptr' 指针是一种特殊类型的指针。它们可以指向任何类型的变量。不能在 'Any Ptr' 指针上使用 '*' 和 '[]' 解引用运算符。必须先将其转换为给定类型的指针。

类似地,类型化指针也可以转换为任何其他类型的指针(如有必要,首先通过 'Any Ptr' 指针转换)。

对于对象指针('po'),使用单个 '->' 运算符比组合 "*" 和 "." 来访问对象成员更方便(使用 'po->member' 而不是 '(*po).member')。

指针也可以声明为与被指向对象的地址类型不同但兼容的类型(作为简单示例,'Zstring Ptr' 和 'Ubyte Ptr' 是两种在两个方向上兼容的指针类型)。以更高级的方式,在继承结构中,派生类型对象可以用从其共同基类类型之一构建的指针引用(当在此类指针上调用虚拟且已重写的方法时,允许激活多态性)。

指针有自己的算术。此类型的递增/递减是特殊的。通过将指针类型的大小乘以要加/减的值来完成。这使得可以将指针向前或向后移动所指示的元素数量。

指针之间唯一允许的操作是减法,前提是指针类型相同。只有当指针指向相同的同构元素结构(指针类型的元素)时,此操作才有意义,因为结果对应于元素数量的差值。

引用的概念

在更高级的语言中,倾向于通过引用和编译器管理的动态数组来取代指针的使用。引用通过移除用户对内存的显式访问来实现某些指针功能。这避免了许多问题,但作为回报,一些用途和优化不再可能。

除了访问内存中表示的数据的两种经典方式:使用其名称(如果它是变量或常量)或解引用包含其地址的指针,还有第三种方法,即引用的使用,在某些情况下这是绝对必要的,并且提供了除了使用指针之外的替代方案。

引用是将新名称与已存在对象关联的方式。

它不是创建新对象的手段,即使创建引用变量的语法看起来奇怪地类似于初始化变量的定义。

这种新名称的分配不会剥夺相关对象的原始名称(如果它有的话)。新名称只是成为旧名称的同义词,这意味着它们都指向同一个对象。

通过引用而不是通过值传递/返回变量,避免了对传输对象进行复制。当相关对象非常大时,复制操作在运行时和内存方面都很昂贵。

像指针一样,引用有自己的类型,必须与被引用对象的类型相同,或者至少兼容。只有在后一种情况下(类型兼容但不相同),引用(像指针一样)不能执行与原始对象相同的所有操作。

使用对象的引用可以获得与使用"对象指针"(速度和内存节省)相关的优势,同时避免了使用对象指针所隐含的书写繁琐(使用 '@' 运算符以及 '*' 或 '[]' 运算符)。

注意:

  • FB 中目前尚不支持引用数组。

  • FB 中目前尚不支持 UDT 的非静态引用字段。

  • FB 中不支持对过程的引用(只支持对过程指针的引用)。

使用引用

请参阅本"引用"部分的下一页:

另请参阅

  • AllocateCallocateNew (Expression)
  • Operator @ (Address of)Operator * (Value of)Operator [] (Pointer index)
  • Operator . (Member access)Operator -> (Pointer to member access)
  • 指针概述
  • 指针算术
  • 使用引用

返回 目录

基于 FreeBASIC 官方文档翻译 如有侵权请联系我们删除
FreeBASIC 是开源项目,与微软公司无隶属关系