带有模块和子程序的fortran程序的结构

时间:2016-04-13 12:16:08

标签: module scope fortran subroutine

这是主程序的一部分

PROGRAM program1
USE method
USE variables
IMPLICIT NONE
:
CALL method_init(A,a1end,C)
:
END PROGRAM program1

对模块method_init中包含的method的调用,“初始化”一个方法,因为它构建数组a1endC形成数组{{1} (其他对模块中包含的其他过程的调用应遵循)。 数组Aa1end是方法的一部分,因此它们都在C模块中声明;数组method不是方法的一部分(可以用另一种方法“解决”),因此它在模块A中声明。

数组variablesC可以由a1end模块中未包含的子程序使用,因此必须在 {{1}之前声明它们声明。 因此,method模块中包含的子程序可以使用这些变量而不使用它们作为输入/输出变量,但这会使子程序的作用不明确(调用只是CONTAINS,所以“这个子程序如何运作?它使用哪些数组?哪些数据会修改?...“),所以我更喜欢将调用作为method

这意味着模块CALL method_init就像这样

CALL method_init(A,a1end,C)

我想知道这是否是一种正确的编程方式。这只是一种品味问题吗?

编辑简而言之,问题是: 编程是否正确使用模块中定义的变量作为模块本身包含的过程的输入/输出参数?或者最好编写没有参数的子程序?或者一切都只是品味问题?

由@Vladimir F联系的问题/答案让我觉得是的,这是一个品味问题。然而,这些问题都没有触及我感兴趣的特定点(即模块中的过程并使用模块中定义的变量作为输入/输出参数)。

1 个答案:

答案 0 :(得分:2)

我的答案是你做出了正确的选择,因为我总是建议用其所有参数编写程序并避免使用全局变量(如Ca1end在你的例子中。)

然而,Fortran中的许多人都习惯使用全局变量,并且不会打扰传递这些参数,有时候出于错误的原因(例如"它写得更快")。 但是,如果将后者想象为包含其自己的特定且唯一的参数集的框,那么在模块中使用全局变量仍然是完全正确的。也许那时你想要将它们指定为Fortran parameter(带有关联的关键字)。

当你质疑传递参数或使用全局变量作为函数/子程序时,一个简单的选择是你的函数是否必须与其他地方的其他不同参数一起调用/重用在您的代码中,或在您的开发过程中的某个时间。 当您将模块视为时,尤其如此,您可以根据自己的需要将模块拔出并交给配偶,然后您可能希望method_init更灵活,因此阐明论点。

注意:在您的示例中,我建议您将子例程参数命名为与模块的变量不同,以避免代码中的任何混淆,并且能够使用它们而不会发生任何冲突:

MODULE method
    IMPLICIT NONE
    REAL, DIMENSION(:,:), ALLOCATABLE :: C
    REAL, DIMENSION(:,:), ALLOCATABLE :: a1end 

CONTAINS

    SUBROUTINE method_init(A,my_a1end,my_C)
    IMPLICIT NONE ! Already specified above
    REAL, DIMENSION(:,:), ALLOCATABLE, INTENT(IN) :: A
    REAL, DIMENSION(:,:), ALLOCATABLE, INTENT(OUT) :: my_C
    REAL, DIMENSION(:,:), ALLOCATABLE, INTENT(OUT) :: my_a1end
    ALLOCATE(my_C(  ),my_a1end(   ))
    ! Here you can work with module's C and a1end
    ! Given that they have been effectively allocated
    ! You can also test whether C and my_C are the same object or not (pointerwise speaking)
    END SUBROUTINE method_init
END MODULE method