递归 Fortran 函数 return 数组?

Recursive Fortran function return array?

我对 Fortran 比较陌生(使用 90),还没有找到任何文献来回答这个问题,所以我想我会在 SO 上提问:我正在尝试编写一个递归函数,它将 return 一个数组。

我的最终目标是在不通过 C fftw 和使用 "C to Fortran" 包的情况下用 Fortran 编写自己的 FFT;我知道有很多方法可以在不使用递归函数的情况下执行此操作,但我仍然想知道递归函数是否能够 return 数组。

作为练习,我尝试编写一个程序,该程序接受一个自然数,递归地计算斐波那契数列和 return 一个索引到参数整数的斐波那契数列。使用相同的算法,我在 Matlab 中编写了这个函数并且可以运行,但是在 Fortran 90 中编写时出现语义错误:

recursive function Fibbo(l)
    integer, INTENT(IN) :: l
    integer, dimension(l)  :: x

    integer, dimension(l) :: Fibbo

    if ( l == 1 ) then
        x = 1
    else if ( l == 2 ) then
        x(1) = 1
        x(2) = 1
    else
        x(1:l-1) = Fibbo(l-1)
        x(n) = x(l-1) + x(l-2)
    end if

Fibbo = x  
end function

它会编译得很好,除了输出没有问题:(当尝试调用 ell = 3 时)

Enter an integer:
3
 -1610612736
  1342177280
           0

每次都有不同的输出,并且像这样的输出我猜内存分配有问题,或者类似的问题,但就像我说的,我找不到任何在线解决递归函数的文献returning 数组。也许做不到?

P.S。当调用 Fibbo(1)、Fibbo(2)、rest.

时,它将输出正确的列表——即 1, [1 1]

编辑: P.P.S。如果重要的话,我正在用 gfortran 编译,在 Yosemite

编辑: 感谢您指出错误,但是尝试重铸输出并没有解决它:

recursive function Fibbo(l) result(x)
    integer, INTENT(IN) :: l
    integer, dimension(l)  :: x

    if ( l == 1 ) then
        x = 1
    else if ( l == 2 ) then
        x(1) = 1
        x(2) = 1
    else
        x(1:l-1) = Fibbo(l-1)
        x(n) = x(l-1) + x(l-2)
    end if

end function

对于 ell > 2,这仍然给出错误。

问题出在这一行:

x(n) = x(l-1) + x(l-2)

分配给数组 x 的元素 n 的位置。问题在于 n 是一个未初始化的整数类型隐式变量(因为您没有声明任何名为 n 的变量)。您还没有为 n 赋值,并且正在访问它,这使它成为一个不合格的程序。

如评论中所述,使用 'implicit none' 被认为是最佳做法,当您无意中使用未声明的变量时会导致编译器错误。例如gfortran 5.2 会抱怨:

        x(n) = x(l-1) + x(l-2)
          1
Error: Symbol ‘n’ at (1) has no IMPLICIT type

如果您将 n 修改为 l 并确保您的函数具有显式接口(例如,将其放入模块中),您的代码就可以正常工作。

出于演示目的,这是我对您的代码所做的:

module fib
  implicit none
contains
  recursive function Fibbo(l) result(x)
    implicit none
    integer, INTENT(IN) :: l
    integer, dimension(l)  :: x
    if ( l == 1 ) then
       x = 1
    else if ( l == 2 ) then
       x(1) = 1
       x(2) = 1
    else
       x(1:l-1) = Fibbo(l-1)
       x(l) = x(l-1) + x(l-2)
    end if
  end function Fibbo
end module fib

program test
  use fib
  implicit none
  print *, Fibbo(10)
end program test

这将输出

1       1       2       3       5       8      13      21      34      55