如何在Fortran中明确使用继承变量?

时间:2017-09-12 13:32:51

标签: variables module fortran

我对模型/变量使用的最佳实践有疑问:

假设我有一个包含一些变量/参数定义的模块和一些使用这些变量的子程序。

我不需要在子例程中明确使用这些变量,因为它们是从父模块继承的 - 但这样做会更好吗?

示例:

module test
implicit none

integer, parameter :: a = 1
real               :: x

contains

subroutine idk(y,z)
  real, intent(in)  :: y
  real, intent(out) :: z

  if(a .eq. 1) then
    z = x*y + 5.
  else 
    z = x*y - 5.
  end if
end subroutine idk

end module test

上面的示例应该可以正常工作,但添加

会更好
use test, only: a,x

到子程序idk的声明部分?

在我的推理中,这里有两个要点:

1)Pro:明确地添加这一行让我可以很容易地看到子程序中实际需要哪些变量。 在许多情况下,模块包含相当多的变量,但每个子程序只需要几个变量。因此,为了更好地理解,增加这一行是有益的。

BUT

2)Contra:在很多情况下,需要上面声明的许多变量/参数(有时编号超过100个参数)。在子例程的开头明确地使用它们只会不必要地混淆代码,降低了代码的可读性。

如果只需要包含几个变量,则第1点很重要,而第2点仅在需要包含许多变量时才重要。但是我认为为少数变量做一件事而对许多变量做另一件事是愚蠢的 - 一旦你选择了一个约定,你应该坚持下去恕我直言......

有关于此的最佳做法吗?

增加: 或者,可以将子例程声明为

subroutine idk(b,w,y,z)

然后将其称为idk(a,x,y,z)

一方面,如果我后来决定将idk与其他变量一起使用,这会给我更大的灵活性。

另一方面,如果我稍后更改某些内容,也会增加出错的风险(例如,我发现我不需要参数a作为条件,而是参数c。我只是在子程序中切换a - > c。但在最后一种情况下,我需要将每次调用更改为idk(c,...)。如果有很多这些调用,这很容易出错)

我非常感谢您的投入!谢谢!

1 个答案:

答案 0 :(得分:1)

绝对没有理由use当前正在定义的模块。这是非法的。如果之前编译过模块并且编译器可以找到.mod文件但是文件,则可能会编译,但除此之外它是错误的。

您应该会遇到错误,例如

    ifort -c assoc.f90
assoc.f90(10): error #6928: The module-name on a USE statement in a program unit cannot be the name of any encompassing scoping unit.   [TEST]
  use test
------^

模块子例程通过主机关联从主机模块获取变量,use语句用于使用关联。这是两件不同的事情,不应该混在一起。

如果要避免全局变量,请将它们作为参数传递。这是一般性建议。什么是最好的取决于每个案例和程序员,一般无法回答。