2013-03-13 97 views
1

我正在处理一个项目(这是明天到期的:/),并且当我试图在自己写的函数上使用单纯形算法时遇到问题。它没有工作,经过5个小时的搜索和实验后,我发现了以下内容:FORTRAN:分段错误,当将数组参数传递给子例程

当我将函数传递给子例程时,此函数不能有任何数组参数。这是真的?因为在我应该使用它的代码中显然应该工作。

我正在使用ifort编译器。请参阅下面最少例如,我basicaly从http://malayamaarutham.blogspot.de/2006/02/passing-function-names-as-arguments-in.html

! Author : Kamaraju S Kusumanchi 
    ! Email : [email protected] 
    ! Last edited : Sun Feb 5 2006 
    ! 
    ! Sample program demonstrating the use of external attribute.  This program 
    ! shows how to pass function names as arguments in Fortran 90  programs. 
    ! 
    ! Compilation and execution steps 
    ! $gfortran passing_functions.f90 -o passing_functions 
    ! $./passing_functions 
    ! beta = 5.500000 
    ! beta = 1.500000 
    ! 
    ! I would appreciate any comments, feedback, criticism,  mistakes, errors etc., 
    ! (however minor they are) 
    ! 
    module dummy 
    implicit none 
    contains 
    !------------------------------------------------------------------------------ 
    function func1(a) 
    implicit none 
    real :: a 
    real :: func1 

    func1 = a+5 
    end function func1 
    !------------------------------------------------------------------------------ 
    function func2(b) 
    implicit none 
    real :: b(:) 
    real :: func2 

    func2 = b(1) 
    end function func2 
    !------------------------------------------------------------------------------ 
    function func3(dyn_func, c) 
    implicit none 
    real :: c 
    real, external :: dyn_func 
    real :: func3 

    func3 = dyn_func(c) 
    end function func3 
    !------------------------------------------------------------------------------ 
    function func4(dyn_func, c) 
    implicit none 
    real :: c(*) 
    real, external :: dyn_func 
    real :: func4 

    func4 = dyn_func(c) 
    end function func4 
    end module dummy 
    !------------------------------------------------------------------------------ 

    program passing_functions 
    use dummy 
    implicit none 

    real :: alpha=0.5, beta 
    real :: gamma(2) = (/10,20/) 

    beta = func3(func1, alpha) 
    write(*,*) 'beta = ', beta 
    beta = func4(func2, gamma) 
    write(*,*) 'beta = ', beta 
    end program passing_functions 

这花是输出:

zeus$ passing.out 
beta = 5.500000  
forrtl: severe (174): SIGSEGV, segmentation fault occurred 
Image    PC    Routine   Line  Source    
passing.out  0000000000402D44 Unknown    Unknown Unknown 
passing.out  0000000000402C7C Unknown    Unknown Unknown 
libc.so.6   00002AFF7915D23D Unknown    Unknown Unknown 
passing.out  0000000000402B79 Unknown    Unknown Unknown 
zeus$ 
+0

这SOLN可以解决这个问题。 http://stackoverflow.com/questions/2521072/function-pointer-arrays-in-fortran。我认为问题是func4 doensnt知道dyn_func采取什么参数。 – yosukesabai 2013-03-14 00:09:56

回答

5

对方回答可以用来解决您的问题,但也有不使用简单的方法指针。

在现代Fortran中几乎没有理由使用external。在我看到的有关Stackoverflow的Fortran问题中,它几乎总是让人们误入歧途。除非你确定,否则不要使用external

你想要做的是用interface块声明(即描述)函数func3func4中的函数参数。这里是如何做到这一点的func4 ...你应该能够找出func3

function func4(dyn_func, c) 
    implicit none 
    real, dimension (:) :: c 
    interface 
     function dyn_func (x) 
      real :: dyn_func 
      real, dimension (:) :: x 
     end function dyn_func 
    end interface 
    real :: func4 

    func4 = dyn_func(c) 
    end function func4 
+0

...以及需要接口块的具体原因是因为被传递的函数(func2)具有假定的形状参数。然后OP将需要处理这样一个事实,即你无法将假定大小的实际参数传递给假设的形状虚拟物体...... – IanH 2013-03-14 01:01:53

+0

非常正确,IanH。在我添加的示例代码中,我也改进了这一点,但没有提到它... – 2013-03-14 01:04:11

+0

哦,哇,这很多!它适用于简单的东西,现在我将尝试将其应用到其余部分。老实说,我必须承认我之前读过其他答案,但我仍然不明白这里有一个词:) 我将查找这些接口是,但现在我只是很高兴它的工作,thatnks再次:) – 2013-03-14 01:24:10