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,我试图将另一个子例程_b的名称和数组传递给通用子例程_a。该子例程_a应将数组传递给子例程_b并返回其计算值 以下是我编写的代码: module pass_subroutine_mod1 implicit none private public :: ave_value, fx contains subroutine ave_value( func, x, y, ave ) ! Calculate average of y

我试图将另一个子例程_b的名称和数组传递给通用子例程_a。该子例程_a应将数组传递给子例程_b并返回其计算值

以下是我编写的代码:

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\u value()
是子程序a,
fx()
是子程序b

当我编译并运行上述代码时,它抛出以下错误:

At line 28 of file pass_subroutine.f90
Fortran runtime error: Array bound mismatch for dimension 1 of array 'y' (1/1125899906842625)
第28行是子例程
fx(x,y)
中的
y=x**3
行。 因此,数组
x
y
似乎没有正确地传递到
fx()
,因为当我试图从
fx()
内打印
x
时,它无法这样做

如果使用标量(并相应地更新代码)而不是数组
x
y
,则代码能够正常运行并输出所需的结果

此外,在完成之后,如果通过添加接口块修改
ave_值
,代码将再次正常运行。以下是使用
平均值
进行的修改:

        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) 上述修改是否正确


b) 如果是,那么为什么在处理数组时需要接口块而在处理标量时不需要接口块?

需要显式接口的是假定的形状数组伪参数
维度(:)
。这是因为编译器必须对它们执行不同的操作,通常传递一个描述符。调用端的内容并不重要,重要的是被调用过程的伪参数

有关更多信息,请参阅我以前的博客文章


您可能需要查看语言功能
抽象接口
,以及
过程
,以使代码看起来更干净。

当您有一个伪过程参数时,正如
ave_value
中的
func
一样,没有“假定接口”。虽然数组伪参数
x
y
是假定的形状(它们的形状来自调用过程时的实际参数),但过程没有类似的情况

相反,过程
func
具有声明它的接口。在这种情况下,您拥有声明

external :: func
因此
func
是一个具有隐式接口的外部过程。正如我们所知,隐式接口在我们想要引用它时是不合适的,并且它假定了形状数组参数
ip
op

您需要以某种方式显式地为伪参数提供正确的接口。如您所见,一种方法是使用接口块为外部过程提供显式接口。或者,您可以使用过程声明语句,如

procedure(iface) func

其中,
iface
是一个合适的接口。有几种方法可以使该界面可用,但我在这里不赘述。

Darn-我知道区别,但一直说错话。编辑-谢谢。谢谢你的回答。我认为将过程放在模块中会自动为它提供一个明确的接口。我这样想的另一个原因是,如果我将
call func(x,y)
行替换为
call fx(x,y)
,而不是通过名称
func
调用
fx
,则代码可以在没有接口块的情况下工作。当
fx
位于不同的模块中时,它显然不起作用,这两种情况之间有什么区别?即使您调用的过程位于可见的模块中,当您将过程作为参数传递时,也没有什么可以将“外部函数”与该过程联系起来。这就是func必须有一个显式接口的原因。谢谢。当我将假定的shape数组参数更改为假定的大小时,代码将正确运行,而不使用接口块。此外,我尝试将
fx
子例程编写为C代码,并从fortran模块调用它。即使这样,我也不需要接口块。因此,问题似乎在于在外部过程中使用假定的形状数组(您和Steve都提到过,但我稍微改变了措辞)!再次感谢。是的,这就是为什么你需要一个显式接口的关键所在——但是如果用C编写的
fx
有一个C-可互操作的接口,那么它也需要这个显式接口。我的答案不是为什么需要显式接口,而是为什么该接口不能用于伪过程参数。