目的是使用allocatable而不使用延迟大小,反之亦然

时间:2014-05-14 01:34:28

标签: arrays memory-management fortran fortran90

我正在学习fortran(90),有过c和python的经验。我正在阅读有关数组的信息(有趣的是,看到很多python数组行为基于fortran);我想知道,有没有理由分配一个allocatable数组没有延迟大小?是否可以在不使用allocatable的情况下推迟尺寸 - 如果是这样,怎么做?

e.g。

REAL, DIMENSION(:) :: arr1
REAL, ALLOCATABLE, DIMENSION(20) :: arr2

1 个答案:

答案 0 :(得分:3)

数组术语在Fortran中可能有点令人生畏。要实现的第一件事是实际参数,一个过程必须为其分配一些内存的变量,以及一个伪参数,调用过程传递的实际参数的占位符之间的区别。如果变量在过程的参数列表中,则它是伪参数。

因此,对于实际参数,有两种数组:

  • 显式形状,例如<type> :: A(3,6)
  • 延迟形状,例如<type>, <allocatable|pointer> :: A(:,:,:)

延迟形状必须具有allocatablepointer属性。

当谈到伪参数时,还有两种数组:

  • 假设大小,例如<type> :: A(4,5,*), B(1:2,4:*), C(m,n)
  • 假设形状,例如<type> :: A(:,4:)

实际和虚假的论点没有任何关联,所以不要混淆它们。还要注意,存在一些称为自动数组的东西,它们看起来与伪大小变量大小(C(m,n))的假定大小数组完全相同,但不会出现在参数列表中,因此它们不是伪参数。

对于假定大小的数组,最后一个维度的上限应该是未指定的(*),除了可以指定下限+上限,包括传递给过程的变量。可以将其视为一个数组,您可以为其重新指定整个布局,而不考虑实际参数。这允许您执行以下操作:

program toby
integer, parameter :: n = 10
real :: a(n**3)
call my_sub(a,n)
end program

subroutine my_sub(a,n)
integer, intent(in) :: n
real, intent(inout) :: a(n,n,*)
...
end subroutine

另一个伪参数,假定形状,只允许您指定下限,因为它从实际参数中获取其大小信息。这意味着您也无法重新定义维度,并且您需要一个明确的界面(例如通过模块)。这使得它更加严格,也没有必要传递数组的大小信息。

program toby
integer, parameter :: n = 10
real :: a(n,n,n)
call my_sub(a)

contains

subroutine my_sub(a)
real, intent(inout) :: a(:,:,:)
integer :: n
n = size(a,1)
...
end subroutine
end program

你可以更详细地阅读它here我发现它是一个理想的参考。

最后但并非最不重要的是,既然你提到了python,就不要急于在Fortran中应用类似python的数组切片,因为它会导致临时数组的使用,这可能会减慢程序的速度。您可以使用-fcheck=array-temps与gfortran进行警告。此外,尽管建议整个阵列上的基本操作用于提高效率(例如using arrays efficiently中的A=A+1),但不要误解为&#34;编写非常简洁的代码有利于提高效率&#34 ;。后者当然不是(必然)真实。