Fortran 子例程之间的调用
我是Fortran编程新手,我试图理解子程序之间的调用。所以我写了一个简单的程序来测试它 这是我的密码Fortran 子例程之间的调用,fortran,Fortran,我是Fortran编程新手,我试图理解子程序之间的调用。所以我写了一个简单的程序来测试它 这是我的密码 program dummy real, allocatable, dimension(:) :: zz,yy call test2(zz,yy) print *, zz, yy contains subroutine test1(ar1,ar2,arsum) real, dimension(:)
program dummy
real, allocatable, dimension(:) :: zz,yy
call test2(zz,yy)
print *, zz, yy
contains
subroutine test1(ar1,ar2,arsum)
real, dimension(:) :: ar1,ar2
real, allocatable, dimension(:) :: arsum
allocate(arsum(size(ar1)+size(ar2)))
arsum(1:size(ar1)) = ar1
arsum(size(ar1)+1:size(ar1)+size(ar2)) = ar2
end subroutine test1
subroutine test2(sg1,sg2)
real, dimension(3) :: g1,g3
real, dimension(4) :: g2,g4
real, allocatable,dimension(:) :: sg1,sg2,dum
g1 = 1.0
g2 = 2.0
g3 = 3.0
g4 = 4.0
call test1(g1,g3,dum)
sg1 = 2*dum
call test1(g2,g4,dum)
sg2 = 3*dum
end subroutine test2
end program dummy
然而,这给我带来了以下错误
forrtl: severe (151): allocatable array is already allocated
Image PC Routine Line Source
dummy.exe 0000000000409B1C Unknown Unknown Unknown
dummy.exe 0000000000402E70 MAIN__ 26 dummy.f90
dummy.exe 0000000000402A2E Unknown Unknown Unknown
libc-2.23.so 00002B3E716C7830 __libc_start_main Unknown Unknown
dummy.exe 0000000000402929 Unknown Unknown Unknown
test1
子例程只是连接任意两个给定数组Test2
子例程定义要连接的数组,并对输出执行一些代数运算,并将它们存储在新数组中。程序dummy
只打印新数组
我做错了什么 让我们看看这个程序的流程。这里涉及到一些术语,但所使用的内容有望通过其他文档进行探索 主程序使用两个参数调用子例程
test2
。对于这里的问题,这些论点毫无意义。相反,请查看本地(子例程)变量dum
dum
是一个可分配数组。它在执行未分配的test2
时开始使用。它首先是调用test1
的(实际)参数,然后是另一个调用test1
的(实际)参数。那么,出了什么问题
在这里,论点的意图至关重要。真的很关键。在继续回答这个问题之前,你应该仔细阅读其他地方的意图
所以,我们现在已经熟悉了争论的意图
在进入子例程test1
时,伪参数arsum
与实际参数dum
具有相同的分配状态。在执行test1
期间,有一条allocate
语句
allocate
语句只能尝试分配尚未分配的对象。这在第一次调用时很好:输入时未分配dum
/arsum
。在执行子例程期间,分配了arsum
,这会影响test2
的dum
的分配状态
在对test1
arsum
的第二次调用中,由于实际参数dum
已分配,因此现在已分配。因此,allocate
语句失败,并给出错误消息
这就是问题所在;如何修复?我们需要确保未分配arsum
。有两种明显的方式:
- 测试
的分配状态并做出相应的响应(可能使用arsum
)李>deallocate
- 在调用
之间取消分配test1
dum
dum
仅在返回某些操作的值时有用。回想一下意图:这就是intent(out)
的含义
如果我们重写子程序test1
as
subroutine test1(ar1,ar2,arsum)
real, dimension(:) :: ar1,ar2
real, allocatable, dimension(:), intent(out) :: arsum
allocate(arsum(size(ar1)+size(ar2)))
arsum(1:size(ar1)) = ar1
arsum(size(ar1)+1:size(ar1)+size(ar2)) = ar2
end subroutine test1
然后,由于intent(out)
,属性arsum
/dum
如果在输入时分配,则会自动取消分配
最后(并且未示出),人们甚至可以考虑使用函数来返回<代码> ARSUM 或甚至使用自动数组而不是可分配数组。或者,甚至Fortran 2003自动分配和数组构造函数:
subroutine test1(ar1,ar2,arsum)
real, dimension(:) :: ar1,ar2
real, allocatable, dimension(:) :: arsum ! Or with `intent(out)`
arsum = [ar1,ar2]
end subroutine test1