2014-08-30 138 views
2

我想知道什麼是編寫下面的代碼的正確方法?在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://stackoverflow.com/q/9374691/3157076。 – francescalus 2014-08-31 00:59:57

+0

看來你試圖複製C,最好是在Fortran中思考。仔細閱讀Bálint的回答,雖然伊恩也是對的。 – 2014-08-31 09:15:31

回答

2

如果一個過程有一個僞參數是一個指針,那麼在任何調用範圍內都需要一個顯式接口。

(有需要顯式接口許多事情,指針假,只有一個。)

您可以通過將接口塊爲您的子程序主程序裏面自己提供顯式接口。另一種遠遠更好的選擇是將子程序放入模塊中,然後在主程序中使用該模塊。第三種方法是使子程序成爲調用範圍的內部過程。

從Fortran 2003開始,如果您打算將指針指向不同的東西,則應該只使用指針。如果你只是使用指針來表示真正的行爲就像一個值,那麼你應該使用allocatables。

2

這取決於你的意思是「正確」的方式。作爲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