递归 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
我对 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