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

dan*_*opa 5 fortran subroutine

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

  .
  .
call action ( mySubX ( argA, argB ) )
  .
  .

subroutine action ( whichSub ( argA, argB ) )
  ...
call subroutine whichSub ( argA, argB )
  ...
end subroutine action
Run Code Online (Sandbox Code Playgroud)

目标是call subroutine whichSub ( argA, argB )采取行动call subroutine mySubX ( argA, argB ).我的偏好是避免传递switch参数然后使用SELECT CASE.

Vla*_*r F 14

它是

call action(mySubX)
Run Code Online (Sandbox Code Playgroud)

提供的行动看起来像

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)
Run Code Online (Sandbox Code Playgroud)

提供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)
Run Code Online (Sandbox Code Playgroud)

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


因此,根据注释中的要求,如果您在模块中并且可以从模块(可能在同一模块中)访问具有正确接口的过程,则可以使用procedure语句获取接口块的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
Run Code Online (Sandbox Code Playgroud)

但更有可能的是,您将创建一个抽象接口,而不是真正的子例程,您将使用过程语句引用它,因此最终所有内容都与以前类似:

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
Run Code Online (Sandbox Code Playgroud)