Fortran 简明教程

Fortran - Pointers

在大多数编程语言中,指针变量存储对象的内存地址。然而,在 Fortran 中,指针是一个数据对象,不仅可以存储内存地址,还具有更多功能。它还包含一个特定对象的一些其他信息,比如类型、级别、扩展名和内存地址。

通过分配或指针分配,可以将指针与目标关联。

Declaring a Pointer Variable

使用 pointer 属性声明指针变量。

以下示例展示了指针变量的声明 −

integer, pointer :: p1 ! pointer to integer
real, pointer, dimension (:) :: pra ! pointer to 1-dim real array
real, pointer, dimension (:,:) :: pra2 ! pointer to 2-dim real array

指针可以指向 −

  1. 一段动态分配的内存。

  2. 与指针同类的数据对象,具有 target 特性。

Allocating Space for a Pointer

allocate 语句允许为指针对象分配空间。例如 −

program pointerExample
implicit none

   integer, pointer :: p1
   allocate(p1)

   p1 = 1
   Print *, p1

   p1 = p1 + 4
   Print *, p1

end program pointerExample

编译并执行上述代码后,将产生以下结果 −

1
5

当不再需要时,应使用 deallocate 语句清空已分配的存储空间,并避免累积未使用且不可用的内存空间。

Targets and Association

目标是另一个普通变量,为其预留了空间。必须使用 target 特性声明目标变量。

使用关联运算符 (⇒) 将指针变量与目标变量关联起来。

让我们重写前一个示例来说明这个概念 −

program pointerExample
implicit none

   integer, pointer :: p1
   integer, target :: t1

   p1=>t1
   p1 = 1

   Print *, p1
   Print *, t1

   p1 = p1 + 4

   Print *, p1
   Print *, t1

   t1 = 8

   Print *, p1
   Print *, t1

end program pointerExample

编译并执行上述代码后,将产生以下结果 −

1
1
5
5
8
8

空指针可以是 −

  1. Undefined

  2. Associated

  3. Disassociated

在上面的程序中,我们使用 ⇒ 运算符将指针 p1 与目标 t1 关联起来了。关联的函数测试指针的关联状态。

nullify 语句将指针与目标分离。

即使有多个指针指向同一目标,也不清空目标。不过,清空指针也暗示着无效化。

Example 1

以下示例演示了这些概念 −

program pointerExample
implicit none

   integer, pointer :: p1
   integer, target :: t1
   integer, target :: t2

   p1=>t1
   p1 = 1

   Print *, p1
   Print *, t1

   p1 = p1 + 4
   Print *, p1
   Print *, t1

   t1 = 8
   Print *, p1
   Print *, t1

   nullify(p1)
   Print *, t1

   p1=>t2
   Print *, associated(p1)
   Print*, associated(p1, t1)
   Print*, associated(p1, t2)

   !what is the value of p1 at present
   Print *, p1
   Print *, t2

   p1 = 10
   Print *, p1
   Print *, t2

end program pointerExample

编译并执行上述代码后,将产生以下结果 −

1
1
5
5
8
8
8
T
F
T
0
0
10
10

请注意,每次运行代码时,内存地址都将不同。

Example 2

program pointerExample
implicit none

   integer, pointer :: a, b
   integer, target :: t
   integer :: n

   t = 1
   a => t
   t = 2
   b => t
   n = a + b

   Print *, a, b, t, n

end program pointerExample

编译并执行上述代码后,将产生以下结果 −

2  2  2  4