为了账号安全,请及时绑定邮箱和手机立即绑定

正确使用Fortran中的模块,子例程和函数

正确使用Fortran中的模块,子例程和函数

慕雪6442864 2019-12-27 15:40:52
我最近了解了在向Fortran程序中添加函数时的接口块。一切都工作得井井有条,但是现在我想在接口块中添加第二个函数。这是我的界面块:interface    function correctNeighLabel (A,i,j,k)    integer :: correctNeighLabel    integer, intent(in) :: i,j,k    integer,dimension(:,:,:),intent(inout) :: A    end function    function correctNeighArray (B,d,e,f)        character :: correctNeighArray    integer, intent(in) :: d,e,f    character, dimension(:,:,:),intent(inout) :: B    end functionend interface在我看来,这可能不是最佳选择。我已经研究了子例程,但是我不太确定这是正确的解决方案。我正在做的事情是相对简单的,我需要将参数传递给子例程,但是我所看到的所有子例程都是a)复杂的(即,对于函数而言过于复杂),并且b)不接受参数。它们的行为就像是在不将变量传递给变量的情况下操纵变量一样。我还没有真正地研究模块,但是从我看来,这不是正确的选择。什么时候应该使用哪个,如何最好地使用它?
查看完整描述

3 回答

?
偶然的你

TA贡献1841条经验 获得超3个赞

模块永远是正确的选择;-)


如果您有一个非常简单的F90程序,则可以在“包含”块中包含函数和子例程:


 program simple

   implicit none

   integer :: x, y

   x = ...

   y = myfunc(x)

 contains

   function myfunc(x) result(y)

     implicit none

     integer, intent(in)  :: x

     integer              :: y

     ...

   end function myfunc

 end program

然后,函数/子例程的接口将在程序中已知,并且不需要在接口块中定义。


对于更复杂的程序,应将所有函数/子例程保留在模块中,并在需要时加载它们。因此,您也不需要定义接口:


 module mymod

   implicit none

   private

   public :: myfunc

 contains

   function myfunc(x) result(y)

     implicit none

     integer, intent(in)  :: x

     integer              :: y

     ...

   end function myfunc

 end module mymod


 program advanced

   use mymod, only: myfunc

   implicit none

   integer :: x, y

   x = ...

   y = myfunc(x)

 end program advanced

该模块和程序可以(实际上应该)在单独的文件中,但是必须在实际程序之前编译该模块。


查看完整回答
反对 回复 2019-12-27
?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

第二,扩大已经说过的话。最好将您的过程(子例程和函数)放入模块中并“使用”它们,因为您可以轻松地对它们进行接口的自动一致性检查。其他方式也有缺点。如果使用接口块定义接口,则需要维护三件事,而不是两件事:接口,过程本身和调用。如果进行更改,则必须修改所有三个以保持一致。如果使用模块,则只需更改两个。使用接口块的原因是,如果您无权访问源代码(例如,预编译的库)或源代码是另一种语言(例如,您正在通过ISO C绑定使用C代码)。

“包含”方法的缺点在于,所包含的过程继承了父程序的所有局部变量……这不是非常模块化的,如果您忘记了这种“功能”,可能会造成很大的混乱。


查看完整回答
反对 回复 2019-12-27
?
慕工程0101907

TA贡献1887条经验 获得超5个赞

alexurba和MSB的答案是正确的,并且像往常一样有用;让我在一点上充实一些细节-如果要使用模块(的确是这样),那么接口到底有什么用呢?

对于模块中的函数和子例程,该模块中的所有内容都use可以自动看到那些接口;接口是在编译模块时生成的(除其他外,这些信息将进入编译模块时生成的.mod文件中)。因此,您无需自己编写。同样,当您使用CONTAINed子程序时(与MSB一致,我发现它更加令人困惑,然后有所帮助- 与外部子程序相比,它们被更好地认为是闭包或嵌套子程序),主程序已经可以显式“查看”接口不需要您为此写出来。

接口块适用于您无法执行的操作-编译器无法为您生成显式接口时,或者您想要的内容与给定的内容不同时。一个示例是在Fortran 2003中使用C-Fortran互操作性。在这种情况下,Fortran代码正在链接到某些C库(例如),并且无法为您生成与C例程的正确的fortran接口-您必须通过编写自己的接口块,自己完成操作。

另一个例子是,当您已经知道子例程的接口,但是当您想创建一个新的接口来“隐藏”后面的子例程时,例如,当您有一个对整数进行操作的例程(例如,对整数进行操作) ,并且您希望能够在任何一个上调用相同的例程名称,并让编译器根据参数对其进行排序。这种构造称为通用例程,自Fortran 90开始就存在。在这种情况下,您将显式创建此新通用例程的接口,并在该接口块内列出与“真实”例程的接口。


查看完整回答
反对 回复 2019-12-27
  • 3 回答
  • 0 关注
  • 762 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信