为什么我们不能通过变量定义数组大小?

时间:2019-01-09 13:14:41

标签: fortran fortran90

我发现数组大小可以由参数定义,而不能由变量定义。下面举例说明我在说什么。

第一个示例-不起作用:

integer :: narr=100
integer, dimension(narr) :: Total

第二个示例-工作:

integer, parameter :: narr=100
integer, dimension(narr) :: Total

在第一个示例中,我期望dimension可以使用变量narr,因为narr是最先定义的。但是我意识到这可能不正确,因为变量的创建可能不遵循我的代码行的顺序。也许这只是具有Python背景的人会这么想的。

在第二个示例中,一切正常。

我推测差异与创建变量和常量的时间有关。有人可以解释其中的奥秘吗?

1 个答案:

答案 0 :(得分:3)

在您的示例中,由于integer, dimension(narr) :: Total没有allocatablepointer属性,因此根据上下文,它可以是静态数组也可以是自动数组(我要离开而不是假定的形状数组,因为问题专门关于定义数组)。无论哪种情况,其大小都必须是编译时间常数或伪参数。在第一个示例中,narr都不是,这使其无效Fortran。为了使用narr作为非常数变量来指定大小,您需要通过包含Totalallocatable属性来将pointer声明为动态数组。视情况而定,这可能会降低性能,但是它在定义数组绑定的方式和位置方面提供了更大的灵活性。

以下是在Fortran中定义静态和动态数组的一些常用方法:

  ! Static
  call test_fixed_size()
  call test_size_parameter()

  ! Dynamic
  call test_allocatable()
  call test_pointer()
  call test_automatic(10)

contains
  subroutine test_fixed_size()
    integer :: array(10)
    array = 1
  end subroutine test_fixed_size

  subroutine test_size_parameter()
    integer, parameter :: size = 10
    integer :: array(size)
    array = 1
  end subroutine test_size_parameter

  subroutine test_allocatable()
    integer, allocatable :: array(:)
    integer :: narr = 100
    allocate(array(narr))
    array = 1
  end subroutine test_allocatable

  subroutine test_pointer()
    integer, pointer :: array(:) => null()
    integer :: narr = 100
    allocate(array(narr))
    array = 1
    deallocate(array)
  end subroutine test_pointer

  subroutine test_automatic(size)
    integer, intent(in) :: size
    integer :: array(size)
    array = 1
  end subroutine test_automatic
end program

(我在这里遗漏了更多现代功能,例如分配时自动分配。)