Fortran 子程序中的数组分配

Posted

技术标签:

【中文标题】Fortran 子程序中的数组分配【英文标题】:Array allocation in Fortran subroutine 【发布时间】:2017-07-19 13:04:07 【问题描述】:

我的问题是关于 Fortran 中的数组分配。

我有一个子程序,比如 readParams,我想从文件中读取一些动态大小的数组。这些也用于子程序之外。 处理这个问题的最佳方法是什么?

在 F95 中,似乎不可能在子程序中进行分配并将填充了值的数组传回主程序。 但是如果我在主程序中分配它并在子程序中使用“intent(inout)”,它也会在那里被释放。

(我这里用的是 F90/95,但是由于代码不大,我也可以将其修改为较新的版本...我对 Fortran 比较陌生,所以我不确定是否改进了数组处理是值得的时间投资^^

编辑感谢您的提示。不过,我并不想在子例程中解除分配我的数组。

问题是:我有一个数组,我需要在我的 ma​​in 程序中分配 somewhere。只有在我从子例程 readArgs 中的输入读取它之后,才能知道数组大小。因此,我使数组“可分配”。 一旦分配,该状态就永远不会再改变。 该数组由子例程 readParams 中的值填充。 我是在 ma​​in 还是在 readParams 中分配最好?如何分配?

...我现在将我的子程序放在一个模块中并从那里使用它们。 目前我在 ma​​in 中进行分配,将数组传递给我的子例程,并在子例程的数组声明中删除了“可分配”语句。 它似乎有效,但我仍然不明白这是否是要走的路。

【问题讨论】:

另见其他一些问题,它们是相关的,但不重复。他们使用可分配参数处理一些特定问题***.com/questions/13058743/…***.com/questions/19537974/…***.com/questions/22169365/… 从 Fortran 95 到 Fortran 2003 的修改并不意味着重写整个代码。一点也不!!!这只是意味着在您需要的特定地方使用现代功能。 一切都在链接中,真的。在其他示例中也是如此。忽略释放。 1.阅读链接中的问题。 2. 使readParams 的数组参数可分配。 3. 分配readParams中的数组。真的看***.com/a/13810698/721644。您也可以只在主程序中分配数组。如果您对此有疑问,请显示您的代码和错误消息并解释这些问题。 无论分配在reaArgs还是readParams,都是你的选择。如果您认为该链接不适用于您的情况,那么 1. 显示您的代码,2. 显示您在尝试分配数组时收到的任何错误消息。 你写似乎不可能。为什么看起来不可能?您遇到了哪些具体错误?您尝试了哪个代码? 【参考方案1】:

在我看来,这个问题与Can a input argument of a Fortran subroutine be deallocated and allocated in the body of the subroutine? 完全相同,如果它 不是,那么它应该被关闭因为你没有显示任何代码所以我们怎么能告诉你你的代码(有效)是否正确???

但我个人对许多人持这种观点,所以如果您的代码看起来与此相似,那可能是正确的:

您可以在子程序中读取大小并在主程序中分配:

module subs
contains
  subroutine readArgs(n)
    integer, intent(out) :: n
    !read n here
  end subroutine

  subroutine readParams(a)
    real :: a(:)

    do i = 1, size(a)
      !read values of a
      a(i) =
    end do
  end subroutine
end module

program main

  use subs

  integer :: n

  readArgs(n)

  allocate(a(n))

  readParams(n)
end program

或者你可以在子程序中分配它。您必须满足Can a input argument of a Fortran subroutine be deallocated and allocated in the body of the subroutine?中的所有要求

module subs
contains
  subroutine readArgs(n)
    integer, intent(out) :: n
    !read n here
  end subroutine

  subroutine readParams(n, a)
    real, allocatable :: a(:)

    allocate(a(n))

    do i = 1, size(a)
      !read values of a
      a(i) =
    end do
  end subroutine
end module

program main

  use subs

  integer :: n

  readArgs(n)

  readParams(n)
end program

不管你做什么,这两种方法都很好。

【讨论】:

【参考方案2】:

如果有人仍然感兴趣,我正在使用 Cuda 编译器 pgf90 和以下工作:

module subs  
implicit none  
    contains  
    subroutine load_array( b )  
        real, allocatable :: b(:)  
        allocate( b(10) )  
        b( 7 ) = 4  
    end subroutine load_array  
end module subs  

Program main  
    use subs  
    implicit none  
    real, allocatable :: a(:)  
    Call load_array( a )  
    print *, a(7)  
    deallocate( a )  
end program main  

【讨论】:

以上是关于Fortran 子程序中的数组分配的主要内容,如果未能解决你的问题,请参考以下文章

Fortran - 可分配派生类型的可分配数组

如何使用 gdb 为 Fortran 程序打印数组大小(绑定)

如何将可分配数组传递给 Fortran 中的子例程

GDB 可以用于在 Fortran 90 中打印派生类型的可分配数组的值吗? [复制]

fortran程序如何将两个数组中的元素,放入一个数组?

Fortran数组范围检查的运行时检查未触发