如何在 Fortran 中将子程序名称作为参数传递?
How to pass subroutine names as arguments in 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 中工作并且现在继续工作。
所以按照评论中的要求,如果你在一个模块中并且可以从模块访问具有正确接口的过程(可能在同一个模块中),你可以使用过程语句来获取接口块的杆:
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
我认为使用模块来避免 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
这里 my demonstration 展示了如何实现这一点。
将子例程名称作为参数传递的语法是什么?示意图:
.
.
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 中工作并且现在继续工作。
所以按照评论中的要求,如果你在一个模块中并且可以从模块访问具有正确接口的过程(可能在同一个模块中),你可以使用过程语句来获取接口块的杆:
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
我认为使用模块来避免 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
这里 my demonstration 展示了如何实现这一点。