如何将数组传递给一个过程,该过程作为参数传递给使用 Fortran 的另一个过程 [英] How to pass array to a procedure which is passed as an argument to another procedure using Fortran
问题描述
我正在尝试将另一个 subroutine_b 的名称和一个数组传递给通用 subroutine_a.这个 subroutine_a 应该将数组传递给 subroutine_b 并取回其计算值.
I am trying to pass the name of another subroutine_b and an array to a generic subroutine_a. This subroutine_a is supposed to pass the array to subroutine_b and get back its computed value.
以下是我写的代码:
module pass_subroutine_mod1
implicit none
private
public :: ave_value, fx
contains
subroutine ave_value( func, x, y, ave )
! Calculate average of y which is passed on from another function `func`.
!
external :: func
double precision, intent(in), dimension(:) :: x
double precision, intent(inout), dimension(:) :: y
double precision, intent(inout) :: ave
integer :: n
N = size( x )
call func( x, y )
ave = sum( y ) / dble( N )
return
end subroutine ave_value
subroutine fx( x, y )
double precision, dimension(:), intent(in) :: x
double precision, dimension(:), intent(inout) :: y
y = x ** 3
return
end subroutine fx
end module pass_subroutine_mod1
program main
use :: pass_subroutine_mod1
implicit none
integer :: i, N = 101
double precision :: ave
double precision, allocatable, dimension(:) :: x, y
allocate( x(N), y(N), source=0.0d0 )
do i = 1, N
x(i) = dble( i - 1 )
end do
call ave_value( fx, x, y, ave )
write( *, '(A, ES15.6E3)' ) "Average value of y (from fx) = ", ave
deallocate( x, y )
end program main
这里ave_value()
是subroutine_a,fx()
是subroutine_b.
Here ave_value()
is the subroutine_a and fx()
is subroutine_b.
当我编译并运行上面的代码时,它会抛出以下错误:
When I compile and run the above code, it throws the following error:
At line 28 of file pass_subroutine.f90
Fortran runtime error: Array bound mismatch for dimension 1 of array 'y' (1/1125899906842625)
Line 28
是子程序fx( x, y )
中的y = x ** 3
行.因此,数组 x
和 y
似乎没有正确传递给 fx()
因为当我尝试打印 x
fx()
中的 code>,它无法这样做.
Line 28
is the line y = x ** 3
in subroutine fx( x, y )
.
It thus seems that the arrays x
and y
are not properly passed to fx()
because when I try to print x
from within fx()
, it is unable to do so.
如果我使用标量(并相应地更新代码)而不是数组 x
和 y
,则代码能够正常运行并输出所需的结果.
If, instead of arrays x
and y
, I use scalars (and update the code accordingly) the code is able to run properly and output the desired result.
此外,经过 this thread,如果我通过添加接口块来修改 ave_value
,代码会再次正常运行.以下是 ave_value
的修改:
Additionally, after going through this thread, if I modify the ave_value
by adding an interface block, the code runs properly again. Following is the modification with ave_value
:
subroutine ave_value( func, x, y, ave )
! Calculate average of y which is passed on from another function `func`.
!
external :: func
double precision, intent(in), dimension(:) :: x
double precision, intent(inout), dimension(:) :: y
double precision, intent(inout) :: ave
integer :: n
interface
subroutine func( ip, op )
double precision, dimension(:), intent(in) :: ip
double precision, dimension(:), intent(inout) :: op
end subroutine func
end interface
N = size( x )
call func( x, y )
ave = sum( y ) / dble( N )
return
end subroutine ave_value
因此,我的问题是:
a) 上述修改是否正确?
a) Is the above modification correct?
b) 如果是,那么为什么在处理数组时需要接口块而不是在处理标量时需要接口块?
b) If yes, then why do I need an interface block when working with arrays and not when working with scalars?
推荐答案
需要显式接口的是假定形状的数组虚拟参数 dimension(:)
.这是因为编译器必须为这些做一些不同的事情,通常是传递一个描述符.调用方的内容并不重要,重要的是被调用过程的虚拟参数.
It's the assumed-shape array dummy arguments dimension(:)
that require an explicit interface. This is because the compiler has to do something different for these, typically passing a descriptor. It doesn't matter what's on the calling side, it's the dummy arguments of the called procedure that matter.
有关更多信息,请参阅我的旧博文 Doctor Fortran 变得明确 - 再次!
For more information see my old blog post Doctor Fortran Gets Explicit - Again!
您可能需要查看语言特性 abstract interface
以及 procedure
,以使代码看起来更简洁.
You may want to look at the language feature abstract interface
, along with procedure
, to make the code look a bit cleaner.
这篇关于如何将数组传递给一个过程,该过程作为参数传递给使用 Fortran 的另一个过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!