0

我想我可以在这里轻松地使用一些帮助,因为我在搞乱一些 fortran 2003 但似乎无法真正理解如何做事。事实是,我需要编写一个 fortran 代码,在模块内声明一个新数据类型,该数据类型的成员之一是指向真实函数的指针。就像是

module new_mod
  type my_type
    real*8 :: a, b
    (here something that declares a real*8 function), pointer :: ptr
  end type my_type
end module_new

module funcs
  real*8 function function1(x)
    real*8 :: x
    function1 = x*x
  end function function1
  real*8 function function2(x)
    real*8 :: x
    function2 = x*x
  end function function2
end module funcs

然后在主程序中我想要类似的东西

program my_prog
  use module_new
  use module_funcs
  implicit none
  real*8 :: y, z
  type(my_type) :: atom
  ...
  atom%ptr => function1
  y = atom%ptr(x)
  ...
  atom%ptr => function2
  z = atom%ptr(x)
end program my_prog

尽管

所以主要思想是 module_new 包含一个类型,该类型具有指向实际函数的指针。新类型的对象中的这个指针必须能够指向主程序中的不同函数。我已经看到可以用抽象接口等做类似的事情,但老实说,我在这里一团糟。如果有人可以提供帮助,我将不胜感激。干杯...

4

1 回答 1

3

好吧,这并不是您发送给 stackoverflow 的真正问题类型,但实际上您的代码只需要“轻微改进”(通过适当的轻微定义)即可工作:

module accuracy
  implicit none

  integer, parameter :: dp = kind(1.0d0)

end module accuracy


module typedef
  use accuracy
  implicit none

  type :: mytype
    real(dp) :: aa, bb
    procedure(myinterface), pointer, nopass :: myfunc
  end type mytype

  abstract interface
    function myinterface(xx)
      import :: dp
      real(dp), intent(in) :: xx
      real(dp) :: myinterface
    end function myinterface
  end interface

end module typedef

module funcs
  use accuracy
  implicit none

contains

  function func1(xx)
    real(dp), intent(in) :: xx
    real(dp) :: func1

    func1 = xx

  end function func1

  function func2(xx)
    real(dp), intent(in) :: xx
    real(dp) :: func2

    func2 = 2.0_dp * xx

  end function func2

end module funcs


program test
  use accuracy
  use typedef
  use funcs
  implicit none

  real(dp) :: xx
  type(mytype) :: atom

  xx = 12.0_dp
  atom%myfunc => func1
  print *, atom%myfunc(xx)
  atom%myfunc => func2
  print *, atom%myfunc(xx)

end program test

有几点值得一提:

  • 您应该使用一个全局参数来确保您的准确性(请参阅模块accuracy)并忘记real*8.

  • 您的派生类型中的过程指针需要一个接口,该接口在以下abstract interface块中提供(请参阅一本好的 F2003 书中的“抽象接口”)。

  • 您需要nopass派生类型中的过程指针选项,否则 Fortran 将假定传递给函数/子例程的第一个参数是派生类型本身(请参阅一本好的 F2003 书中的“类型绑定过程”)。

  • 最后,虽然相当明显:如果您认真考虑在生产代码中使用 Fortran 2003 功能,那么您绝对应该阅读一本有关 Fortran 2003 功能的书。

于 2013-05-13T18:54:35.297 回答