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

我最近了解了在向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 function

end interface

在我看来,这可能不是最佳选择。


我已经研究了子例程,但是我不太确定这是正确的解决方案。我正在做的事情是相对简单的,我需要将参数传递给子例程,但是我所看到的所有子例程都是a)复杂的(即,对于函数而言过于复杂),并且b)不接受参数。它们的行为就像是在不将变量传递给变量的情况下操纵变量一样。


我还没有真正地研究模块,但是从我看来,这不是正确的选择。


什么时候应该使用哪个,如何最好地使用它?


慕雪6442864
浏览 771回答 3
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该模块和程序可以(实际上应该)在单独的文件中,但是必须在实际程序之前编译该模块。

肥皂起泡泡

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

慕工程0101907

alexurba和MSB的答案是正确的,并且像往常一样有用;让我在一点上充实一些细节-如果要使用模块(的确是这样),那么接口到底有什么用呢?对于模块中的函数和子例程,该模块中的所有内容都use可以自动看到那些接口;接口是在编译模块时生成的(除其他外,这些信息将进入编译模块时生成的.mod文件中)。因此,您无需自己编写。同样,当您使用CONTAINed子程序时(与MSB一致,我发现它更加令人困惑,然后有所帮助- 与外部子程序相比,它们被更好地认为是闭包或嵌套子程序),主程序已经可以显式“查看”接口不需要您为此写出来。接口块适用于您无法执行的操作-编译器无法为您生成显式接口时,或者您想要的内容与给定的内容不同时。一个示例是在Fortran 2003中使用C-Fortran互操作性。在这种情况下,Fortran代码正在链接到某些C库(例如),并且无法为您生成与C例程的正确的fortran接口-您必须通过编写自己的接口块,自己完成操作。另一个例子是,当您已经知道子例程的接口,但是当您想创建一个新的接口来“隐藏”后面的子例程时,例如,当您有一个对整数进行操作的例程(例如,对整数进行操作) ,并且您希望能够在任何一个上调用相同的例程名称,并让编译器根据参数对其进行排序。这种构造称为通用例程,自Fortran 90开始就存在。在这种情况下,您将显式创建此新通用例程的接口,并在该接口块内列出与“真实”例程的接口。
打开App,查看更多内容
随时随地看视频慕课网APP