以下代码返回分段错误,因为我尝试传递的可分配数组未被正确识别(大小返回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
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
答案 0 :(得分:30)
如果过程具有可分配的伪参数,则在任何调用范围中都需要显式接口。
(有很多东西需要显式接口,可分配的虚拟只有一个。)
您可以通过在主程序中放置子程序的接口块来自己提供该显式接口。另一个远远更好的选择是将子程序放在一个模块中,然后在主程序中使用该模块 - 然后自动创建显式接口。您在eng-tips网站上提供了一个链接的示例 - 请参阅xwb的帖子。
请注意,如果您要执行与其分配状态相关的操作,则只有具有allocatable属性的伪参数才有意义 - 查询其状态,重新分配,解除分配等等。
答案 1 :(得分:6)
请注意,您的可分配伪参数array
是使用intent(in)
声明的,这意味着它的分配状态将是相关实际参数的分配状态(并且在过程中可能不会更改)。传递给子例程的实际参数可能是未分配的,因此即使使用显式接口也无法引用。编译器不会知道这一点,在这种情况下,size
之类的查询行为是未定义的。
因此,首先必须在引用其内容之前检查array
与allocated(array)
的分配状态。我还建议使用lbound
和ubound
在整个数组上实现循环,因为通常你无法确定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
答案 2 :(得分:1)
This is a simple example that uses allocatable dummy arguments with a module.
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