Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran 子例程之间的调用_Fortran - Fatal编程技术网

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(:)

我是Fortran编程新手,我试图理解子程序之间的调用。所以我写了一个简单的程序来测试它

这是我的密码

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