2014-03-05 35 views
1

我是Fortran新手。我用Fortran 90編寫一個程序來得到一個數組的非零元素,並使用指針函數把它們放入一個新的數組如下:在編譯期間我fortran指針分配期間的90期望邊界規範

program prog 
    implicit none 
    integer, target :: a(5) 
    integer :: i 
    integer, pointer :: nz(:) 


    a(1) = 1 
    a(2) = 0 
    a(3) = 0 
    a(4) = 2 
    a(5) = 3 

    nz => non_zeros(a) 
    do i=1, size(nz) 
     write(*,*) nz(i) 
    end do 

contains 
function non_zeros(a) 
    integer, target :: a(:) 
    integer, pointer:: non_zeros(:) 
    integer :: n, i, j 

    n = count(a .ne. 0) 
    allocate(non_zeros(n)) 

    j = 0 
    do i=1, m 
     if (a(i) .ne. 0) then 
      j = j + 1 
      non_zeros(j) => a(i) 
     end if 
    end do 
end function non_zeros 

end program prog 

得到了錯誤:

non_zeros(j) => a(i) 
1 
Error: Expected bounds specification for 'non_zeros' at (1) 

你能告訴我我做錯了什麼?先謝謝你!

更新我的問題:根據高性能馬克的解釋,我定義了一個派生類型:

program prog 
    implicit none 
    integer, target :: a(5) 
    type dt 
     integer, pointer :: x 
    end type 
    type(dt), allocatable :: nz(:) 


    a(1) = 1 
    a(2) = 0 
    a(3) = 0 
    a(4) = 2 
    a(5) = 3 

    nz = non_zeros(a) 

    contains 

    function non_zeros(a) 
     integer, target :: a(:) 
     type(dt), allocatable :: non_zeros(:) 
     integer :: n, i, j 

     n = count(a .ne. 0) 
     allocate(non_zeros(n)) 

     j = 0 
     do i=1, m 
      if (a(i) .ne. 0) then 
       j = j + 1 
       non_zeros(j)%x => a(i) 
      end if 
     end do 

    end function non_zeros 
end program prog 

現在程序的工作,並給出了預期的效果。但是,在這種情況下,我沒有使用指針函數,因爲我的函數返回一個可分配的指針數組,而不是指向數組的指針。有什麼方法可以在這裏使用指針功能嗎?謝謝

+0

我很懷疑您正嘗試在Fortran中編寫C語言(或類似的語言)。具有指針元素*的派生類型的*數組是常見的用於生成類似於指針數組的類似Fortran的技巧,但獲取包含「a」的非零元素的數組不是必需的。你寫的東西看起來很人性化,至少這個Fortran程序員是不自然的。 –

+0

@HighPerformanceMark正如我所說,我是Fortran的新手,我曾經在Python上工作。這就是爲什麼該程序看起來不自然。您可以請作爲Fortran的專家提示我如何更改我的代碼,以便它將成爲自然的Fortran程序!非常感謝 –

+0

我回答了您的問題*我正在編寫Fortran 90中的程序,以獲取數組中的非零元素,並在我的第一個響應(下)中將它們放入一個新數組*中。我看到沒有必要爲此使用指針。 –

回答

4

要獲得a非零元素融入到一個新的數組,你可以簡單地聲明

integer, dimension(:), allocatable :: non_zeros 

,然後填充與聲明

non_zeros = pack(a,a/=0) 

,並避免與指針周圍擺弄完全。這依賴於2003年標準中引入的一個特性,但是它被所有(我認爲)市場上現有的Fortran編譯器所實現。

您寫的代碼在我看來好像你想要nz是一個指針數組,nz中的每個元素都指向一個非零元素a。如果我是對的,你誤解了一個陳述如

integer, pointer :: nz(:) 

聲明。它沒有聲明一個指向整數的指針數組,它聲明瞭一個指向整數數組的指針。當你寫

non_zeros(j) => a(i) 

你正在做的嘗試設置的non_zeros的元素指向的a元素的錯誤。

錯誤消息誤導這裏,因爲編譯器解釋non_zeros(j)的語法,不正確界規格範圍重新映射,但錯誤是語義時,編譯器不理解你的Fortran語言的誤解。

+0

非常感謝您提供的好幫助解決方案。我會遵循它來寫我的「真實」的程序。我還閱讀了有關指針和可分配數組之間區別的主題,其中有經驗的人建議使用allocatable而不是指針(在可分配數組執行作業的情況下)。但在這裏,我想用指針練習,並嘗試更多地理解它。所以我期待看到你的第二個建議 –

+0

謝謝你的解釋。我嘗試創建一個派生類型,如下所示:type dt integer,pointer :: x endtype',然後將結果聲明爲type(dt),allocatable :: nz(:)'現在程序工作並給出所需的結果。然而,在這種情況下,我沒有使用'pointer function',因爲我的函數返回一個可分配的指針數組,而不是指向數組的指針。有沒有什麼方法可以在這裏使用'指針功能'? –

+0

試圖找出評論中的代碼太過分了。要麼編輯您的問題,要麼發佈新的問題,要麼等待比我擁有的視力更好的人回答您的評論問題。 –