在fortran中传递指针参数

问题描述:

我想知道什么是编写下面的代码的正确方法?在fortran中传递指针参数

PROGRAM foo 

    INTEGER :: x 
    REAL(KIND=8), TARGET, DIMENSION(0: 10) :: array 
    REAL(KIND=8), POINTER, DIMENSION(:) :: ptr 

    ptr => array 

    CALL bar(ptr) 

END PROGRAM foo 

SUBROUTINE bar (ptr) 

    REAL(KIND=8), POINTER, DIMENSION(:) :: ptr                                                     
    INTEGER x 
    DO x =0, 10 
    ptr(x) = 2 // seg faults 
    ENDDO 

END SUBROUTINE bar 

它的工作原理,如果我在bar声明ptrREAL(KIND=8), DIMENSION(0:10)。但总的来说,我可能不知道传入数组的大小,那么有没有办法将ptr声明为某个数组的指针?我正在编译gfortran

+1

这是一个情况下的'foo'中'bar'需要_explicit interface_。例如,参见http://*.com/q/9374691/3157076。 – francescalus 2014-08-31 00:59:57

+0

看来你试图复制C,最好是在Fortran中思考。仔细阅读Bálint的回答,虽然伊恩也是对的。 – 2014-08-31 09:15:31

如果一个过程有一个伪参数是一个指针,那么在任何调用范围内都需要一个显式接口。

(有需要显式接口许多事情,指针假,只有一个。)

您可以通过将接口块为您的子程序主程序里面自己提供显式接口。另一种远远更好的选择是将子程序放入模块中,然后在主程序中使用该模块。第三种方法是使子程序成为调用范围的内部过程。

从Fortran 2003开始,如果您打算将指针指向不同的东西,则应该只使用指针。如果你只是使用指针来表示真正的行为就像一个值,那么你应该使用allocatables。

这取决于你的意思是“正确”的方式。作为IanH已经pointed out,你需要一个明确的接口(最好通过在模块中包装东西完成),如果可能的话,使用可分配的而不是指针。

我还想补充一点,如果你不想在你的子程序中改变你的数组的分配状态,但只想操纵它的元素,那么在你的子程序中使用一个简单的假定形状数组。下面你会找到一个工作的例子。一些事情需要注意:

  • 不要使用real(kind=8),因为不是所有的编译器使用的字节数作为一种为实数。如果你想要双精度精度,请明确要求如下。

  • 如果你只是想填补一个恒定值的数组,这样做的简单的方法:array(:) = 2.0_dp

而且这里的例子:

module accuracy 
    implicit none 

    integer, parameter :: dp = kind(1.0d0) 

end module accuracy 


module barmodule 
    use accuracy 
    implicit none 

contains 

    subroutine bar(array) 
    real(dp), intent(inout) :: array(:) 

    integer :: ii 

    do ii = 1, size(array) 
     array(ii) = ii 
    end do 

    end subroutine bar 

end module barmodule 


program foo 
    use accuracy 
    use barmodule 
    implicit none 

    real(dp), dimension(0:10) :: array 
    call bar(array) 

end program foo 
+2

如果您希望数组为零索引,您可以在子例程中声明它为'array(0:)'。它允许假定形状,但指定起始索引。这可以被概括,直到将起始索引作为参数传递。 – 2014-08-31 08:41:01

+0

你是对的!谢谢!这是我已经打了很多次的东西......我已经从帖子中删除了appropraite部分。 – 2014-08-31 09:08:09