Fortran 范围和处理具有多个输入的子例程

Fortran 范围和处理具有多个输入的子例程,fortran,subroutine,Fortran,Subroutine,我的一些fortran子程序有大量的输入传递给它们,有时甚至是30或40。原因有两个,第一,这些子例程有许多明显直接相关的子例程,它们需要一些变量作为输入;第二,为了避免定义全局变量,解决方法似乎是每次都将每个变量显式地传递给子例程 这对我来说似乎是不可接受的,但我真的没有一个解决方案,我也不是100%确定这首先是一个问题,也许这是用这种语言做事情的正确方式 我的问题是:这是个问题吗?如果是的话,有没有更好的方法来管理这种语言中的作用域,而不必引入对象?我可以理解为什么设计者想要避免全局变量。我

我的一些fortran子程序有大量的输入传递给它们,有时甚至是30或40。原因有两个,第一,这些子例程有许多明显直接相关的子例程,它们需要一些变量作为输入;第二,为了避免定义全局变量,解决方法似乎是每次都将每个变量显式地传递给子例程

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


我的问题是:这是个问题吗?如果是的话,有没有更好的方法来管理这种语言中的作用域,而不必引入对象?

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

我们可以有把握地说,这个数量的论点(比如说30个)太多了。所有的代码风格指南都可能同意这一点。使用许多参数库(如LAPACK require)通常会有点不愉快,这还不到30

Fortran 90和更新版本有几种减少参数数量的方法

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

type particle
  integer :: species
  real    :: mass
  real    :: x, y, z
  real    :: vx, vy, vz
  ...
end type
其次,通过使用假定形状数组,可以避免传递数组维度。这使得现代LAPACK接口的参数数量大大减少,例如(Netlib和MKL接口)

vs

此更改需要程序的明确接口,因此在实践中,程序必须移动到模块中


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

我担心这是基于观点的。特别是说这是否是一个问题是基于意见的。我建议您阅读一般编程问题和答案,就像Fortran没有那么特别一样。现代Fortran有许多功能可以帮助您减少参数的数量,特别是派生类型-结构。请注意,其中一个也是基于意见的。另一个@Ignacio只要你远离动态多态性,我不认为由于使用简单的复合类型(只聚合变量)而导致的性能损失会有多大(虽然我没有测试过)。你不需要OOP,你只需要使用结构派生的类型。这不是OOP,甚至在20世纪70年代(以及更早的一些其他语言中)就在Pascal或C中广泛使用OOP。对于过去的一些CPU,由于参数列表过长(与常用或模块变量相比),可能会出现可测量的性能下降;有不止一种可能的机制。过程间编译器优化是处理这一问题的常用方法。替换派生类型不会影响这一点。
subroutine sub(A, NX, NY, NZ)
  integer :: NZ, NY, NZ
  real :: A(NX, NY, NZ)
subroutine sub(A)
  real :: A(:,:,:)