如何分配数组传递到FORTRAN子程序(How to pass allocatable arrays

2019-06-18 15:02发布

下面的代码返回分段错误,因为分配数组我试图通过没有被正确识别(尺寸返回1,当它应该是3)。 在这个页面(http://www.eng-tips.com/viewthread.cfm?qid=170599)类似的例子似乎表明,它应该在F95做工精细; 我的代码文件具有.F90扩展,但我试图将其更改为F95,而我使用gfortran编译。

我的猜测是,这个问题应该是在我传递的分配数组的子程序的方式; 我究竟做错了什么?

!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
 PROGRAM test
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
 IMPLICIT NONE
 DOUBLE PRECISION,ALLOCATABLE :: Array(:,:)
 INTEGER                      :: iii,jjj

 ALLOCATE(Array(3,3))
 DO iii=1,3
 DO jjj=1,3
    Array(iii,jjj)=iii+jjj
    PRINT*,Array(iii,jjj)
 ENDDO
 ENDDO
 CALL Subtest(Array)

 END PROGRAM
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
 SUBROUTINE Subtest(Array)
 DOUBLE PRECISION,ALLOCATABLE,INTENT(IN) :: Array(:,:)
 INTEGER                                 :: iii,jjj

 PRINT*,SIZE(Array,1),SIZE(Array,2)
 DO iii=1,SIZE(Array,1)
 DO jjj=1,SIZE(Array,2)
    PRINT*,Array(iii,jjj)
 ENDDO
 ENDDO

 END SUBROUTINE
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!

Answer 1:

如果过程有一个伪参数是分配的,则显式接口是必需的任何呼叫范围。

(有需要显式接口许多东西,可分配的虚拟只是一个。)

您可以通过将接口块为您的子程序主程序里面自己提供显式接口。 另一种与远很远,更好的选择是把子程序模块内,然后用在主程序中该模块 - 然后自动创建的显式接口。 还有就是这对您提供的链接在ENG提示网站的例子 - 看到XWB职。

请注意,它才有意义的伪参数有可分配属性,如果你打算做有关其分配状态的东西 - 查询其状态,重新分配它,释放它,等等。



Answer 2:

另请注意,您的可分配伪参数array声明与intent(in) ,这意味着它的分配状态将是相关联的实际参数(它可能不会在手术过程中被改变)。 传递给你的子程序的实际参数可以是未分配的,因此非法引用,即使有明确的接口。 编译器将不知道这一点,像查询的行为, size在这种情况下是不明确的。

因此,你首先要检查的分配状态arrayallocated(array)引用其内容之前。 我会进一步建议实行循环与全阵列上lboundubound ,因为一般你不能肯定array的界限:

subroutine subtest(array)
  double precision, allocatable, intent(in) :: array(:,:)
  integer                                   :: iii, jjj

  if(allocated(array)) then
    print*, size(array, 1), size(array, 2)
    do iii = lbound(array, 1), ubound(array, 1)
      do jjj = lbound(array, 2), ubound(array, 2)
        print*, array(iii,jjj)
      enddo
    enddo
  endif  
end subroutine


Answer 3:

这是使用分配的伪参数与一个模块一个简单的例子。

module arrayMod   
  real,dimension(:,:),allocatable :: theArray    
end module arrayMod

program test
   use arrayMod
   implicit none

   interface
      subroutine arraySub
      end subroutine arraySub
   end interface

   write(*,*) allocated(theArray)
   call arraySub
   write(*,*) allocated(theArray) 
end program test

subroutine arraySub
   use arrayMod

   write(*,*) 'Inside arraySub()'
   allocate(theArray(3,2))
end subroutine arraySub


文章来源: How to pass allocatable arrays to subroutines in Fortran