范围和处理具有许多输入的子程序

Scope and dealing with subroutines with many inputs

我的一些 Fortran 子例程有大量的输入传递给它们,有时甚至是 30 或 40 个。这样做的原因有两个,首先,这些子例程有许多明显直接相关的子例程,它们需要其中一些变量作为输入,其次,避免定义全局变量,对此的解决方案似乎是每次都将每个变量显式传递给子程序。

这对我来说似乎是无法接受的,但我并没有真正的解决方案,而且我不是 100% 确定它首先是一个问题,也许这是正确的做事方式这种语言。

我的问题是:这是一个问题吗?如果是,是否有更好的方法来管理这种语言的范围,而不必引入对象?

我明白为什么设计者要避免全局变量了。我必须使用采用相反方法的代码,几乎没有参数,并且各种模块中的所有内容都处于全局状态,这很糟糕,无论他们在 [=14= 中使用了多少 only 子句] 语句。

我们可以肯定地说,这个数量的参数(比如 30 个)太大了。所有的代码风格指南都可能同意这一点。使用像 LAPACK 这样的许多参数库需要的参数通常有点不愉快,而且远不及 30 个。

Fortran 90 和更新版本可以通过多种方式减少参数数量。

首先,您可以将逻辑相关的变量耦合到派生类型中

type particle
  integer :: species
  real    :: mass
  real    :: x, y, z
  real    :: vx, vy, vz
  ...
end type

其次,通过使用假定的形状数组,您可以避免传递数组维度。这允许现代 LAPACK 接口具有明显更少的参数,例如(Netlib 和 MKL 接口)。

subroutine sub(A, NX, NY, NZ)
  integer :: NZ, NY, NZ
  real :: A(NX, NY, NZ)

对比

subroutine sub(A)
  real :: A(:,:,:)

此更改需要过程的显式接口,因此在实践中必须将过程移入模块。

这两项更改都是相当重要的更改,需要对大型遗留代码进行大量重构工作。