我可以在Fortran 90中使用以下代码创建函数指针

real, external :: f


然后使用f作为另一个函数/子例程的参数。但是,如果我想要一个函数指针数组怎么办?在C中我会做

double (*f[])(int);


创建一个函数数组,该函数返回double并接受一个整数参数。我尝试了最明显的

real, external, dimension(3) :: f


但是gfortran不允许我混合使用EXTERNAL和DIMENSION。有什么办法可以做我想要的吗? (本文的上下文是一个用于求解微分方程组的程序,因此我可以在子程序中输入百万个参数而无需输入方程式。)

最佳答案

声明“ real,external :: f”并没有真正使“ f”成为完整的指针,因为您无法更改其指向的过程,它确实允许您将单个函数传递给另一个例程。您还需要“指针”属性。 Metcalf,Reid和Cohen在“ Fortran 95/2003解释的”第267页上有示例-谷歌搜索“ fortran过程指针”将显示此页面。一个简单的例子是“真实的,外部的,指针:: f_ptr”。或者:“过程(f),指针:: f_ptr”。这是Fortran 2003的功能-http://gcc.gnu.org/wiki/Fortran2003http://gcc.gnu.org/wiki/ProcedurePointers列出了gfortran中的部分支持,最好是4.5。我不确定是否直接允许使用“维度”,但是您可以将过程分配给指针,这样可以提供很大的灵活性。您还可以将指针放入派生类型中,该派生类型可以制成数组。

编辑:这是与gfortran 4.5一起使用的代码示例:
编辑2:在下面的每个评论中注释掉该行。

module ExampleFuncs

  implicit none

contains

function f1 (x)
  real :: f1
  real, intent (in) :: x

  f1 = 2.0 * x

  return
end function f1


function f2 (x)
   real :: f2
   real, intent (in) :: x

   f2 = 3.0 * x**2

   return
end function f2


function fancy (func, x)

   real :: fancy
   real, intent (in) :: x

   interface AFunc
      function func (y)
         real :: func
         real, intent (in) ::y
      end function func
   end interface AFunc

   fancy = func (x) + 3.3 * x

end function fancy

end module  ExampleFuncs

program test_proc_ptr

  use ExampleFuncs

  implicit none

  ! REMOVE: pointer :: func
  interface
     function func (z)
        real :: func
        real, intent (in) :: z
     end function func
  end interface

  procedure (func), pointer :: f_ptr => null ()

  type Contains_f_ptr
     procedure (func), pointer, nopass :: my_f_ptr
  end type Contains_f_ptr

  type (Contains_f_ptr), dimension (2) :: NewType


  f_ptr => f1
  write (*, *) f_ptr (2.0)
  write (*, *) fancy (f_ptr, 2.0)

  f_ptr => f2
  write (*, *) f_ptr (2.0)
  write (*, *) fancy (f_ptr, 2.0)

  NewType(1) % my_f_ptr => f1
  NewType(2) % my_f_ptr => f2

  write (*, *) NewType(1) % my_f_ptr (3.0), NewType(2) % my_f_ptr (3.0)

  stop

end program test_proc_ptr

08-06 04:43