【问题标题】:Can I use allocatable array as an intent(out) matrix in Fortran?我可以在 Fortran 中使用可分配数组作为意图(输出)矩阵吗?
【发布时间】:2018-01-27 03:56:22
【问题描述】:

考虑下面的子程序

subroutine myProc(m,n,flag,X)
Integer, intent(in) :: m,n
logical, intent(in) :: flag
real(8), intent(out), allocatable :: X(:,:)

if (flag) then
  allocate(X(m,n))
  ! some more code here
else 
  allocate(X(m-1,n))
  ! some more code here
end if
end subroutine myProc
!!!!!!!!!!!!!!!!!!!

另外,如何在程序中调用此过程?假设我写了

!... some code before
call myProc(5,6,.TRUE.,X)

我需要将 X 定义为 (4,6) 实数数组还是将可分配数组传递给子例程?

在 Fortran 95 中是否可以做到所有这些?

【问题讨论】:

  • 欢迎。对于所有 Fortran 问题,请使用标签 fortran。矩阵和数组是有区别的。数组是某种类型的元素的结构化/索引集合。矩阵是来自线性代数的数学结构,它描述了向量空间基之间的变换。另请注意,real(8) 很丑陋,不可移植,并不总是意味着 8 字节或双精度。
  • 感谢您向我解释什么是矩阵。另外,请您指出 real(8) 是不可移植的。关于我的实际问题,您的建议和丹的建议都有效。谢谢。

标签: arrays fortran fortran95


【解决方案1】:

在 Fortran 2003 及更高版本中将可分配的虚拟参数传递给子例程是非常好的。 IIRC TS(技术规范)首先允许 Fortran 95。今天所有的编译器都支持它。

在传递给可分配的虚拟参数时,不必分配实际参数。在这里,如果它恰好被分配,它实际上会被自动释放,因为dummy是intent(out)allocatable, intent(out)参数在进入子程序时会自动释放。

您的代码应该可以正常工作,但有一个重要方面,子例程必须具有显式接口。所以它必须放在一个模块中。或者它必须是内部的(在contains 之后)或者必须使用interface 块(丑陋)。

你可以照你说的那样称呼它

call myProc(5,6,.TRUE.,X)

并且X 不必分配。

【讨论】:

    【解决方案2】:

    你可以把 X 放在一个模块中,在调用程序中声明它,然后在子程序中分配它。任何使用此类模块的程序、函数或子例程都引用相同的内存空间,因此这些变量甚至不会作为参数传递。它看起来像这样:

    module Global
       real(8), allocatable :: X(:,:)
    end module Global
    
    program main
       use Global
       !... some code before
       call myProc(5,6,.TRUE.)
    end program main
    
    subroutine myProc(m,n,flag)
       use Global
       Integer, intent(in) :: m,n
       logical, intent(in) :: flag
    
       if (flag) then
         allocate(X(m,n))
         ! some more code here
       else 
         allocate(X(m-1,n))
         ! some more code here
       end if
    end subroutine myProc
    !!!!!!!!!!!!!!!!!!!
    

    【讨论】:

    • 鉴于 OP 要求 Fortran 95,在 Fortran 95 中不可能实现这一事实在技术上是正确的,但忽略了要点。解释不正确。前两句完全错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 2015-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多