And*_*rew 5 fortran argument-passing subroutine fortran90
我是 Fortran 新手。我正在尝试编写一个子程序,它将从主程序中接收四个参数,然后向主程序输出一个包含最初传入的四个参数的数组。有什么好的/聪明的方法可以做到这一点?
例如,在我下面的测试程序,我创建四个实际变量(a,b,c,并d在主程序)。然后我将这些实际变量传递给一个名为mysub. 我希望mysub能够接收a, b, c, 和d,使用它们来填充一个名为 的 2×2 数组o,然后发送o到主程序以在那里显示(和可能的修改)。所以,我尝试了以下方法:
SUBROUTINE mysub(w,x,y,z)
IMPLICIT NONE
REAL, INTENT(IN) :: w, x, y, z
REAL, DIMENSION(:,:), ALLOCATABLE, INTENT(OUT) :: o
ALLOCATE(o(2,2))
o(1,1)=w
o(1,2)=x
o(2,1)=y
o(2,2)=z
END SUBROUTINE mysub
END MODULE testsubs
PROGRAM test
USE testsubs
IMPLICIT NONE
REAL :: a=1.1, b=2.2, c=3.3, d=4.4
CALL mysub(a, b, c, d)
PRINT *, o(1,1), o(1,2)
PRINT *, o(2,1), o(2,2)
END PROGRAM test
Run Code Online (Sandbox Code Playgroud)
但是,我收到以下错误:
test.f90:10.53:
REAL, DIMENSION(:,:), ALLOCATABLE, INTENT(OUT) :: o
1
Error: Symbol at (1) is not a DUMMY variable
Run Code Online (Sandbox Code Playgroud)
我将此解释为,编译器不知道o的是,由于o不是在子程序头参数列表:SUBROUTINE mysub(w,x,y,z)。所以我可能需要包含o在该标题中。因此,我接下来尝试以下操作(我使用 表示更改或添加!...):
SUBROUTINE mysub(w,x,y,z,o) !...
IMPLICIT NONE
REAL, INTENT(IN) :: w, x, y, z
REAL, DIMENSION(:,:), ALLOCATABLE, INTENT(OUT) :: o
ALLOCATE(o(2,2))
o(1,1)=w
o(1,2)=x
o(2,1)=y
o(2,2)=z
END SUBROUTINE mysub
END MODULE testsubs
PROGRAM test
USE testsubs
IMPLICIT NONE
REAL :: a=1.1, b=2.2, c=3.3, d=4.4
REAL, DIMENSION(:,:), ALLOCATABLE :: o !...
CALL mysub(a, b, c, d, o) !...
PRINT *, o(1,1), o(1,2)
PRINT *, o(2,1), o(2,2)
DEALLOCATE(o) !...
END PROGRAM test
Run Code Online (Sandbox Code Playgroud)
这似乎工作正常,我得到了正确的输出:
1.1000000 2.2000000
3.3000000 4.4000001
Run Code Online (Sandbox Code Playgroud)
但是,我的问题是,这是做到这一点的好方法吗?在这个工作示例中,我在子例程和主程序中o 都声明了数组。这似乎可能造成混乱,因为我认为,这意味着我必须要小心,无论是在子程序或主程序分配(而不是两个,我认为,为了避免错误消息)。有没有更聪明的方法来做到这一点——将一个数组从子程序发送到主程序?感谢您的时间。o
您的解决方案将“o”作为意图(输出)参数就可以了。如果没有“o”作为参数,子程序中的变量“o”和主程序中的变量“o”之间就没有联系,因此主程序中没有声明或分配该变量。另一种解决方案(除了 @ja72 提供的解决方案之外)是更改您的方法:使“o”成为子例程的 Intent(inout) 参数并在主程序中分配它。可能的优点:分配和释放在代码中更接近并且配对。可能的缺点:根据程序逻辑和设计,子例程可能最了解数组维度。
PS 如果你在主程序中分配数组,并且在子程序中实际上没有使用数组的可分配属性(即,你没有分配或释放它),那么你不必使用可分配的属性来声明它子例程中的属性——一个有用的简化。在这种情况下,“意图(出局)”可能是合适的。但是,如果您在主程序中分配数组并希望将该状态传递给子例程,则参数状态不能是“intent(out)”。“intent (out)”在进入过程时自动释放参数。