2014-03-28 48 views
1

我試圖編寫一個過程,它存儲用戶數組的地址以供進一步處理。問題被封裝在這個測試程序中:不同類型的指針Fortran

program test_ptr 
    real(4), target, allocatable :: i4(:,:) 
    real(8), target, allocatable :: i8(:,:) 
    real(4), pointer :: p(:,:) 

    allocate(i4(2,2)) 
    allocate(i8(2,2)) 

    p => i4 ! ok 
    p => i8 ! compile error 
end 

編譯器建議爲不同的類型製作不同的指針。 但我不想爲真實(4)和真實(8)創建單獨的指針。我試圖製作通用和緊湊的解決方案,併爲不同類型的數據提供一個指針。可能嗎?

回答

2

如果你真的想存儲地址,我會小心多態。指向多態變量的指針通常指向與實際數據具有不同地址的描述符。考慮使用iso_c_binding模塊中定義的type(c_ptr)和函數c_loc()來獲取地址。它不一定只用於與C接口,有幾個地方可以在純Fortran中使用。

+0

謝謝,但我不明白它是如何工作的。如果'p = c_ptr(r4)',那我怎麼能得到它下面的數據(就像C中的'* p')? – vovo

+1

然後使用設置Fortran'指針'的'c_f_pointer()'子例程來指向數據。您必須知道該類型,因爲它不存儲在'c_ptr'中。 –

5

對於p可以使用(無限制)多態性做到這一點。

program test_ptr 
    implicit none 

    real(kind(0.)), target :: r4(2,2) 
    real(kind(0d0)), target :: r8(2,2) 

    class(*), pointer :: p(:,:) 

    ! some assignments, etc. 

    if (...some crazy condition...) then 
    p => r4 
    else 
    p => r8 
    end if 

    select type (p) 
    type is (real(kind(0.))) 
     print *, p 
    type is (real(kind(0d0))) 
     print *, p 
    end select 

end program 

要特別注意select type以後使用p時。

+0

請參閱Vladimir F的[answer](http://stackoverflow.com/a/22723837/3157076)如果_address_(在問題中)是重要部分,比_pointer_更重要。 – francescalus

+0

謝謝,這是一個好主意,但是我的編譯器說:'(1)不支持'無限多態''。 – vovo

+0

@vovo這聽起來像一個gfortran錯誤消息。 4.8.2(也許更早,但我沒有檢查什麼時候)確實支持這個構造。 – francescalus