【问题标题】:Passing subarray of 2-dimensional array in FORTRAN-77在 FORTRAN-77 中传递二维数组的子数组
【发布时间】:2020-02-16 12:47:11
【问题描述】:

我有二维数组

real triangle(0:2, 0:1)

其中“三角形”是一个向量数组(一维数组) 我也有子程序

subroutine vecSub(lhs, rhs, result)
real lhs(0:1), rhs(0:1), result(0:1)
    result(0) = lhs(0) - rhs(0)
    result(1) = lhs(1) - rhs(1)
    return
end

有没有办法将“三角形”变量中的一个向量传递给这个子程序? Fortran-90 可以做到这一点:triangle(0, :) 它给出了第一个三角形数组,但我只能使用 FORTRAN-77,所以这不行,有什么建议吗?

【问题讨论】:

  • 不,您不能在 Fortran 77 中传递数组的一部分。有一种方法可以做类似的事情,但是要传递“向量”,请使用 Fortran 2003 或更高版本,这就是你应该在所有新代码中做。 Fortran 77 已经死了,它仍然在抽搐,因为人们仍然在教它,从而损害了他们的学生。请帮助它最终摆脱困境。
  • 只是想知道,你提到你只能使用 Fortran77,你是在暗示你必须严格遵循它的标准,还是人们将 Fortran77 与固定格式源连接而 Fortran90 与免费连接是一种常见的误解- 形式来源。真的已经没有很多编译器可以针对 ANSI Fortran77 进行编译了。
  • 没办法,单个学生不可能为俄罗斯的整个教育系统做点什么:D 我们应该使用 fortran 77 并且不能使用任何更高版本的标准
  • 我们应该只使用标准77,正如老师所说(多次,如果你好奇的话),我们应该使用的IDE是WATCOM
  • 由于您需要重写整个子例程(F77 编译器不会理解任何一行),您是否接受有关 50 年前如何编写这样的东西以适应这个愿望?

标签: arrays fortran fortran77


【解决方案1】:

@Javier Martin 写道“不使用阵列的当前布局”,但错过了提出替代方案的机会。

如果您将变量声明如下:

real triangle(0:1, 0:2)

反转边界的顺序,然后您可以将triangle(0,0)triangle(0,1)triangle(0,2) 传递给子例程,并获得您想要的行为,这要归功于名为“序列关联”的 Fortran 功能。当您将单个数组元素传递给作为数组的虚拟参数时,您将按数组元素顺序隐式传递该数组和后面的元素。这是唯一允许违反正常 Fortran 形状匹配规则的行为,并且是 FORTRAN 77 的一部分。

【讨论】:

  • 谢谢,没想到。我们的老师说没有指针和引用,但是这种行为很像在 C(C++) 中传递数组(不是常量数组)。这样就可以了,再次感谢
  • 这有一些例外 - 如果数组是假定形状或指针(Fortran 90 的两种功能),它就不起作用。我在2009 blog post 中讨论过这个问题。
【解决方案2】:

,与阵列的当前布局无关,原因有二:

  • Fortran 使用数组元素顺序,其中最左边的维度是连续的。也就是说,在大小为(n,m,l) 的数组中,元素之间的距离(步幅)为(1,n,m),以数组元素为单位(即,不是字节)测量。
  • F77 不包括假定形状数组a(:),它们通常通过传递一个小型描述符结构来实现,该结构传达诸如步幅或元素数量等细节。相反,您只能使用假定长度数组a(*),它们通常是指向第一个元素的指针,有点像 C 数组。您必须将长度作为单独的参数传递,并且数组元素必须是连续的

这就是为什么您可以“将子数组”“传递给 F77 子例程”的原因,只要该子数组是例如矩阵列:其中的元素是连续的。

一种可能的解决方案(许多当前的 Fortran 编译器实现的解决方案)是,当您尝试将不连续的子数组传递给未知接受它们的函数时,它们会复制该数组,甚至将其写入如果需要,返回内存。这相当于:

! Actual array
integer m(3,5)
integer dummy(5)
dummy = m(2,:)
call myF77sub(dummy, 5)
m(2,:) = dummy

但是,正如其他人所说,您应该尽量不要直接调用 F77 函数,而应使它们适应或至少将它们包装在更新的 Fortran 接口中。然后,您可以在包装器中包含上述代码,并从现代 Fortran 例程中“正常”调用该包装器。然后,您最终可能会在不影响客户端代码的情况下改写现代 Fortran 中的实际实现。

【讨论】:

  • '相反,您只能使用假定长度数组a(*)' - 或者实际上是问题中的明确形状数组。
  • 感谢您的解释,关于我已经阅读过的内存中的元素顺序。关于不调用函数..我的任务是将这部分代码编写为函数(而且,正如我之前提到的,我不能使用像“m(2,:)”这样的语法,因为它来自 F90 标准,我只允许使用 F77。顺便说一句,我试图重组整个代码,现在我只包含 3 个不同的数组(它们是向量),我知道这是一个错误的决定,不灵活,但它会通过完成任务
  • @francescalus 好吧,是的,但是如果我必须从字面上考虑 OP 的子程序,那绝对不是 F77。所以我认为这只是一个 F90 的例子。
猜你喜欢
  • 2016-12-15
  • 2015-08-08
  • 1970-01-01
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-19
  • 2011-04-20
相关资源
最近更新 更多