简体   繁体   English

在 FORTRAN-77 中传递二维数组的子数组

[英]Passing subarray of 2-dimensional array in FORTRAN-77

I have 2-dimensional array我有二维数组

real triangle(0:2, 0:1)

where "triangle" is an array of vectors (1-dim arrays) also i have subroutine其中“三角形”是一个向量数组(一维数组),我也有子程序

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

is there any way to pass one of the vectors from "triangle" variable to this subroutine?有没有办法将“三角形”变量中的向量之一传递给这个子程序? Fortran-90 can do this: triangle(0, :) which gives first array of triangle, but i'm allowed to use only FORTRAN-77, so this won't do, any suggestions? Fortran-90 可以做到这一点: triangle(0, :)给出第一个三角形数组,但我只允许使用 FORTRAN-77,所以这不行,有什么建议吗?

@Javier Martin wrote "not with the current layout of your array", but missed the opportunity to suggest an alternative. @Javier Martin 写道“不使用您的阵列的当前布局”,但错过了提出替代方案的机会。

If instead you declared the variable as follows:如果您改为如下声明变量:

real triangle(0:1, 0:2)

reversing the order of the bounds, you could then pass triangle(0,0) , triangle(0,1) or triangle(0,2) to the subroutine and get exactly the behavior you want, due to a Fortran feature called "sequence association".颠倒边界的顺序,然后您可以将triangle(0,0)triangle(0,1)triangle(0,2)传递给子程序并获得您想要的准确行为,这是由于名为“序列”的 Fortran 功能协会”。 When you pass a single array element to a dummy argument that is an array, you are implicitly passing that and following elements, in array element order.当您将单个数组元素传递给作为数组的虚拟参数时,您将按数组元素顺序隐式传递该元素和后续元素。 This is about the only allowed violation of the normal Fortran shape-matching rules, and was part of FORTRAN 77.这是对正常 Fortran 形状匹配规则唯一允许的违反,并且是 FORTRAN 77 的一部分。

No , not with the current layout of your array, because of two reasons:,不是与您的阵列的当前布局,因为两个原因:

  • Fortran uses an array element order in which the leftmost dimension is contiguous. Fortran 使用数组元素顺序,其中最左边的维度是连续的。 That is, in an array of size (n,m,l) the distance between elements (the stride ) is (1,n,m) , measured in units of array elements (that is, not bytes).也就是说,在大小为(n,m,l)的数组中(n,m,l)元素之间的距离(步幅)是(1,n,m) ,以数组元素为单位(即,不是字节)。
  • F77 does not include assumed-shape arrays a(:) which are generally implemented by passing a small descriptor structure that communicates details like the stride or the number of elements. F77 不包括假定形状数组a(:) ,它们通常通过传递一个小的描述符结构来实现,该结构传达诸如步幅或元素数量之类的细节。 Instead, you can only use assumed-length arrays a(*) which are normally a pointer to the first element, kind of like C arrays.相反,您只能使用假定长度的数组a(*) ,它通常是指向第一个元素的指针,有点像 C 数组。 You have to pass the length as a separate argument, and array elements have to be contiguous您必须将长度作为单独的参数传递,并且数组元素必须是连续的

This is the reason why you can "pass a subarray" to an F77 subroutine, as long as that subarray is eg a matrix column: elements therein are contiguous.这就是为什么您可以将子数组“传递给 F77 子程序”的原因,只要该子数组是例如矩阵列:其中的元素是连续的。

A possible solution (one that many current Fortran compilers implement) is that when you try to pass a non-contiguous subarray to a function that is not known to accept them, they make a copy of the array, and even write it back in memory if required.一种可能的解决方案(许多当前的 Fortran 编译器实现的解决方案)是,当您尝试将非连续子数组传递给未知接受它们的函数时,它们会复制该数组,甚至将其写回到内存中如果需要的话。 This would be equivalent to:这相当于:

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

However, as others are saying, you should try not to call F77 functions directly, but either adapt them to or at least wrap them in more recent Fortran interfaces.但是,正如其他人所说,您应该尽量不要直接调用 F77 函数,而是要使它们适应或至少将它们包装在更新的 Fortran 接口中。 Then you can have code like the above in the wrapper, and call that wrapper "normally" from modern Fortran routines.然后,您可以在包装器中使用上述代码,并从现代 Fortran 例程“正常”调用该包装器。 Then you may eventually get around to rewriting the actual implementation in modern Fortran without affecting client code.然后,您最终可能会在不影响客户端代码的情况下改写现代 Fortran 中的实际实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM