如何在Fortran中将子例程名称作为参数传递? [英] How to pass subroutine names as arguments in Fortran?

查看:228
本文介绍了如何在Fortran中将子例程名称作为参数传递?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 

调用操作(mySubX(argA,argB))


$ b $子程序动作(whichSub(argA,argB))
...
调用子程序whichSub(argA,argB)
...
结束子程序动作

目标是让调用子程序whichSub(argA,argB)充当调用子程序mySubX(argA,argB)
我的首选是避免避免传递参数,然后使用SELECT CASE。

解决方案

  call action(mySubX)

提供的动作看起来像

 子程序动作(子)
!要么 - 不推荐,它是旧的FORTRAN77风格
外部的子
!或 - 推荐的
接口
子程序子(aA,aB)
整数,意图(...):: aA,aB
结束子程序
结束界面
!不是都!!

call sub(argA,argB)

provided action 知道应该把 argA,argB 放在那里以表示 aA,aB



否则,如果您想传递参数

  call action(mySubX,argA,argB)

子程序操作(sub,argA,argB)
!要么 - 不推荐,它是旧的FORTRAN77样式
外部子
!或 - 建议
接口
子程序子(aA,aB)
整数,意图(...):: aA,aB
结束子程序
结束接口

整数,意图(...):: argA,argB

呼叫子(argA,argB)

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






因此,按照评论中的要求,如果您处于具有正确接口的模块和过程可以从模块访问(可能在同一个模块中),您可以使用过程语句来获取接口块的标签:



<$ p模块subs_mod
包含
子程序example_sub(aA,aB)
整数,意图(...):: aA,aB
!真正的示例代码
结束子程序
结束模块

模块action_mod
包含

子程序操作(子)
使用subs_mod
过程(example_sub):: sub

调用子(argA,argB)
结束子程序
结束模块

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

  module action_mod 

抽象接口
子例程sub_interface(aA,aB)
整数,意图(...):: aA,aB
结束子程序
结束接口

包含

子程序动作(子)
程序(sub_interface)::子

call sub(argA,argB)
结束子程序
结束模块


What is the syntax for passing subroutine names as arguments? Schematically:

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

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

The goal is to have call subroutine whichSub ( argA, argB ) act as call subroutine mySubX ( argA, argB ). My preference is to avoid avoid passing a switch parameter and then use SELECT CASE.

解决方案

It is

call action(mySubX)

provided action looks as

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)

provided action knows what to put there as argA, argB to represent aA, aB.

Otherwise, if you want to pass also the arguments

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)

I don't think it is good to use function pointers here, they are good when you have to change the value of the pointer (the subroutine it points to) sometimes. Normal procedure arguments worked in FORTRAN77 and continue to work even now.


So as requested in the comment, if you are in a module and procedure with the right interface is accessible from the module (perhaps in the same module), you can use the procedure statement to get rod of the interface block:

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

but more likely, instead of a real subroutine you will create an abstract interface which you would reference with the procedure statement so in the end everything will be similar as before:

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

这篇关于如何在Fortran中将子例程名称作为参数传递?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆