递归Fortran函数返回数组?

时间:2015-08-01 00:05:46

标签: arrays function recursion fortran fibonacci

我对Fortran相对较新(使用90),并且无法找到任何回答这个问题的文献,所以我想我会在 SO 上问:我正在尝试写一个将返回数组的递归函数。

我的最终目标是在Fortran中编写自己的FFT而不通过C fftw并使用“C to Fortran”包;我知道有一些方法可以在不使用递归函数的情况下执行此操作,但我仍然想知道递归函数是否能够返回数组。

作为练习,我尝试编写一个接受自然数的程序,递归计算Fibonacci序列并返回索引到参数整数的Fibonacci数列表。使用相同的算法,我在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

每次都有不同的输出,并且像我一样猜测存在内存分配的问题,或类似的东西,但就像我说的我在网上找不到任何返回数组的递归函数的文献。也许它无法完成?

P.S。当调用Fibbo(1),Fibbo(2),休息时,它将输出正确的列表 - 即,1,[1 1] -

编辑: P.P.S.如果重要的话,我正在优胜美地与gfortran一起编译

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

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

这仍然会给出错误> 2。

1 个答案:

答案 0 :(得分:3)

问题在于这一行:

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

您分配给数组n的元素x的位置。问题是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