首页 > 解决方案 > 如何在 Fortran 子例程中使用可分配数组?

问题描述

让我先说我对 Fortran 很陌生,但对 Python 很熟悉。然而,我的研究项目需要我使用一些预先编写的 Fortran 代码,这些代码目前无法在我的电脑上编译。我试图理解为什么。

我试图编译的实际代码很长,可能不是很有启发性,但我想我已经设法提出了一个我认为问题所在的最小示例。假设我有一个非常简单的模块和子例程,如下所示,

module arraycheck
    implicit none
    real*8, allocatable, dimension(:) :: x
    contains
    subroutine fillx
        real*8, allocatable, dimension(:) :: x
        allocate(x(5))
        x(1) = 1
        x(2) = 2
        x(3) = 3
        x(4) = 4
        x(5) = 5
        print*, x
    end subroutine fillx
end module arraycheck

我希望简单地创建一个数组x,当调用子例程时,它fillx会用整数 1 到 5 填充数组。我的实际源包含概念上与此类似的东西。现在我还有一个main程序如下,

program main
use arraycheck
print*, x
call fillx
print*,x
end

我的想法是,在第一print条语句中,变量x仍然未分配,因此print不返回任何内容,然后在第二print条语句x中已填充,因此它应该返回填充的数组。

然而,在这两个print语句中都没有返回任何内容。现在在我的原始源代码中发生了类似的事情,这导致运行时抛出一个未分配的数组作为实际参数传递到某处的错误,该参数应该已分配。似乎与我在此处的小示例中发生的事情完全相同。

所以我的问题是,我在此处的示例中观察到的行为是预期的吗?如果是,我如何更改代码以使其以我希望的方式工作?如果我知道这一点,我可能会更好地理解为什么实际来源不起作用。

以防万一,我在 ubuntu 上使用 gfortran。

谢谢!

标签: fortrangfortransubroutine

解决方案


x的 s 太不一样了。他们没有任何共同点。一个模块数组和一个子程序本地数组。当您在子例程中分配本地数组时,它不会对模块中的其他数组做任何事情。

此外,您不能打印未分配的数组。这不符合标准(未定义的行为)。任何事情都有可能发生。在诊断问题时,您绝对应该启用所有编译器检查。编译器应该通过这些检查来抱怨您的代码。

删除局部数组声明并避免引用未分配的变量。模块过程可以通过主机关联访问模块变量。

module arraycheck
    implicit none
    real*8, allocatable, dimension(:) :: x

  contains

    subroutine fillx

        allocate(x(5))
        x(1) = 1
        x(2) = 2
        x(3) = 3
        x(4) = 4
        x(5) = 5
        print*, x
    end subroutine fillx
end module arraycheck


program main
  use arraycheck

  call fillx
  print*,x
end

另外,real*8它不是标准的 Fortran,它是一个非标准的扩展。Fortran 90 及更高版本使用 kind 系统。


推荐阅读