通过fortran中的子程序传递未知大小的数组(在子程序中分配的数组)

时间:2012-12-21 17:35:21

标签: arrays fortran allocation subroutine

我有一个程序,在第一个子程序(CALCONE)中创建一个数组,然后我想将它传递到下一个子程序(CALCTWO),然后将其输出到主程序中的文件。我不知道在哪里放置INTENT(IN),INTENT(OUT)语句,因为数组需要分配IN子程序CALCONE(因为在我的程序中,长度是在CALCONE中确定的) - 我已经离开了我的尝试以避免混乱。有人可以帮助把他们放在正确的地方。一旦我有了模板,我就会明白它是如何运作的。感谢。

我简化了程序,变量代表了其他无法移动的东西。我只需要一种在子程序之间移动数组的方法,然后在主程序结束时将其写出来。

 program TEST
 implicit none

 integer a,b,c,d,reclen

 a = 1
 b = 2
 c = 3
 d = 4

 call CALCONE(a,b,c,d,array)

 call CALCTWO(e,f,g,h,array)

 inquire(iolength=reclen)array 
 open(unit=8,file='array_output.dat', &
   form="unformatted",access="stream")
 write(unit=8)array       
 close(unit=8)

 END PROGRAM TEST

 SUBROUTINE CALCONE(adummy,bdummy,cdummy,ddummy,arraydummy)
 IMPLICIT NONE

 integer i,j,k
 integer e,f,g,h,N
 !ALLOCATE ARRAY HERE OR IN MAIN PROGRAM?
 real*8,   allocatable  :: arraydummy(:,:)

 e = a + 1
 f = b + 1
 g = c + 1
 h = d + 1

 ! N can only be is calculated here

 allocate(arraydummy(1:N,1:3))

 !POPULATE 'arraydummy'
 !PASS ARRAY BACK OUT TO NEXT SUBROUTINE FOR FURTHER PROCESSING IN CALCTWO
 END SUBROUTINE CALCTWO

 SUBROUTINE CALCTWO(edummy,fdummy,gdummy,hdummy,arraydummy)
 IMPLICIT NONE

 integer e,f,g,h
 !DEFINE HERE ALSO? i.e.
 !real*8,   allocatable  :: arraydummy(:,:)

 e = a + 1
 f = b + 1
 g = c + 1
 h = d + 1

 arraydummy = arraydummy*e*f*g*h

 END SUBROUTINE CALCTWO

1 个答案:

答案 0 :(得分:6)

你不必在主程序中分配数组,但你必须在那里声明它,你必须将它作为参数传递(你这样做)。请注意,主程序中未定义符号array

确保为sub提供明确的接口。因为您使用高级功能(可分配的伪参数)是必要的。最好将它们放在一个模块中。

必须在两者中将数组定义为伪参数。我在第一个中将它声明为intent(out),因为它是在开头分配的。这不是绝对必要的。

另一个选择是在模块中声明数组并让它由模块程序共享。

免责声明:我没有尝试编译它。

 module subs
   integer,parameter :: rp = kind(1d0)


   contains




   SUBROUTINE CALCONE(adummy,bdummy,cdummy,ddummy,arraydummy)
   IMPLICIT NONE

   integer i,j,k
   integer e,f,g,h,N
   !ALLOCATE ARRAY HERE OR IN MAIN PROGRAM?
   real(rp),   allocatable, intent(out) :: arraydummy(:,:)

   e = a + 1
   f = b + 1
   g = c + 1
   h = d + 1

   !N can only be is calculated here

    allocate(arraydummy(1:N,1:3))

   !POPULATE 'arraydummy'
   !PASS ARRAY BACK OUT TO NEXT SUBROUTINE FOR FURTHER PROCESSING IN CALCTWO
   END SUBROUTINE CALCTWO

   SUBROUTINE CALCTWO(edummy,fdummy,gdummy,hdummy,arraydummy)
   IMPLICIT NONE

   integer e,f,g,h
   !DEFINE HERE ALSO? i.e.
   real(rp),   allocatable, intent(inout)  :: arraydummy(:,:)

   e = a + 1
   f = b + 1
   g = c + 1
   h = d + 1

   arraydummy = arraydummy*e*f*g*h

   END SUBROUTINE CALCTWO


 end module subs

 program TEST

 use subs

 implicit none

 integer a,b,c,d,reclen

 real(rp),allocatable :: array

 a = 1
 b = 2
 c = 3
 d = 4

 call CALCONE(a,b,c,d,array)

 call CALCTWO(e,f,g,h,array)

 inquire(iolength=reclen)array 
 open(unit=8,file='array_output.dat', &
   form="unformatted",access="stream")
 write(unit=8)array       
 close(unit=8)

 END PROGRAM TEST