如何在Fortran中传递子例程名称作为参数



传递子例程名称作为参数的语法是什么?示意图:

  .
  .
call action ( mySubX ( argA, argB ) )
  .
  .
subroutine action ( whichSub ( argA, argB ) )
  ...
call subroutine whichSub ( argA, argB )
  ...
end subroutine action

目标是让call subroutine whichSub ( argA, argB )充当call subroutine mySubX ( argA, argB )。我的偏好是避免传递一个开关参数,然后使用SELECT CASE。

call action(mySubX)

提供的操作看起来像

subroutine action(sub)
  !either - not recommmended, it is old FORTRAN77 style
  external sub
  !or - recommended
  interface
    subroutine sub(aA, aB)
      integer,intent(...) :: aA, aB
    end subroutine
  end interface
  ! NOT BOTH!!
  call sub(argA, argB)

如果action知道argA, argB在那里代表aA, aB

否则,如果你想传递参数

call action(mySubX, argA, argB)
subroutine action(sub, argA, argB)
  !either - not recommmended, it is old FORTRAN77 style
  external sub
  !or - recommended
  interface
    subroutine sub(aA, aB)
      integer,intent(...) :: aA, aB
    end subroutine
  end interface
  integer, intent(...) :: argA, argB
  call sub(argA, argB)

我不认为在这里使用函数指针是好的,当你不得不改变指针的值(它指向的子程序)时,它们是好的。正常的过程参数可以在FORTRAN77中工作,并且即使现在也可以继续工作。


因此,正如评论中所要求的,如果您在模块中,并且可以从模块(可能在同一模块中)访问具有正确接口的过程,则可以使用过程语句获取接口块的rod:

module subs_mod
contains
  subroutine example_sub(aA, aB)
    integer,intent(...) :: aA, aB
    !the real example code
  end subroutine
end module
module action_mod
contains
  subroutine action(sub)
    use subs_mod
    procedure(example_sub) :: sub
    call sub(argA, argB)
  end subroutine
end module

,但更有可能的是,你将创建一个抽象的接口,你将与过程语句引用,而不是一个真正的子例程,所以最后一切都将像以前一样:

module action_mod
  abstract interface
    subroutine sub_interface(aA, aB)
      integer,intent(...) :: aA, aB
    end subroutine
  end interface
contains
  subroutine action(sub)
    procedure(sub_interface) :: sub
    call sub(argA, argB)
  end subroutine
end module

我认为使用module来避免interface是一个很好的现代Fortran实践,因为它提供了一个更干净的接口。

这是理想的实现:

模块部分:

module foo
contains
subroutine callsub(sub,arg1,arg2)
!This subroutine is used to call other subroutines
external::sub !Use external to tell compiler this is indeed a subroutine
call sub(arg1,arg2)
end subroutine
subroutine sub(arg1,arg2)
!The subroutine to be called.
!do something
end sub
end module

下面是主程序:

program main
use foo !Use module automatically avoids using interface.
implicit none
!Declare about args
call callsub(sub,arg1,arg2)
end program

下面是我的演示,以展示如何实现这一点。

最新更新