【发布时间】:2019-07-16 17:34:54
【问题描述】:
假设我想编写一个函数,该函数将一个维度的数组 x 作为输入,并基于它返回另一个相同维度的数组 y(以说明它我正在使用一个将其乘以 2) 的函数。我对该代码有两个选择:
function times2(x) result(y)
real, intent(in) :: x(:)
real, allocatable :: y(:)
allocate(y(size(x))
y = 2*x
end function
或
function times2(x,n) result(y)
real, intent(in) :: x(n)
integer, intent(in) :: n
real :: y(n)
y = 2*x
end function
我个人更喜欢第一个,因为 更容易 用于调用者,但我不确定哪个在内存方面更好,假设数组 x 可能很大,我不知道不知道是延迟数组好还是自动数组好。 在任何情况下,在现代 Fortran 中哪种方法是最好的方法?
【问题讨论】:
-
我认识的大多数人会使用子程序,而不是函数。修改参数的函数是邪恶的——它们会引起混乱,而且我的理解是,在更复杂的表达式中使用它们时,它们的作用并不总是得到很好的定义。因此,如果您必须使用函数,请使用第一种方式,但我想大多数人会说子程序是要走的路。
-
为什么对呼叫者来说应该“更容易”?
-
在底层,函数结果通常是通过创建一个带有隐藏参数的子例程来实现的。然而,如果您在复杂表达式中使用该函数,您最终可能会在堆栈上得到一个临时的。但是,只要您对数组使用复杂的表达式,就会发生这种情况。
-
我想我会为 cross(u, v) 之类的函数使用自动返回数组(对于返回另一个向量的两个向量的叉积),而对 matmul 之类的函数使用可分配的返回数组(A, B) 如果 A 或 B 可能非常大(因此它们可能不适合堆栈)。
-
但是您可以重写第二个以使
y(size(x))仍然具有x(:)(我承认这是我认为您所做的:我可能会根据最小的差异跳过实际代码在自动和延迟之间。)
标签: arrays function fortran heap-memory stack-memory