2011-01-05 7 views
6

In Fortran kann ich Arrays aus einer Subroutine mit drei Ansätzen zurückgeben. Die erste ist über einen intent(out) Parameter. Die zweite ist über eine Funktion mit dem Array result. Die dritte ist eine Funktion, die als result einen Zeiger auf Array hat, der in der Funktion zugeordnet ist.Array-Strategievergleich zurückgeben

Was sind die Vor- und Nachteile jedes Ansatzes?

Antwort

5

Meine Praxis ist es, eine Funktion zurückzukehren, wenn die Funktion nur eine Variable ändert und keine andere Ausgabe macht. Wenn mehrere Variablen geändert werden oder die Prozedur andere Aktionen ausführt, würde ich die Ausgabevariablen in die Argumentliste einfügen. Dies ist eine Stilwahl. Es ist möglich, Speicherverluste mit Zeigern zu erzeugen, insbesondere mit Zeigern, die als Funktionsargumente zurückgegeben werden, so dass ich diese Option vermeiden würde, wenn es keinen zwingenden Grund in dem speziellen Fall gibt.

UPDATE: Es gibt kein Problem mit der Absicht (out) Array-Argument ... müssen keine Annahmen über die Größe des Arrays hergestellt werden, wie das folgende Beispiel zeigt:

module example_one 

implicit none 

contains 

subroutine two_arrays (in_arr, out_arr) 

    integer, dimension (:), intent (in) :: in_arr 
    integer, dimension (:), allocatable, intent (out) :: out_arr 

    integer :: i, len 

    len = size (in_arr) 

    allocate (out_arr (1:len)) 

    do i=1, len 
     out_arr (i) = 3 * in_arr (i) 
    end do 

return 

end subroutine two_arrays 

end module example_one 


program test 

use example_one 

implicit none 

integer, dimension (1:5) :: in_arr = [ 1, 2, 4, 5, 10 ] 
integer, dimension (:), allocatable :: out_arr 

write (*, *) allocated (out_arr) 
call two_arrays (in_arr, out_arr) 

write (*, *) size (out_arr) 
write (*, *) out_arr 

write (*, *) allocated (out_arr) 
deallocate (out_arr) 
write (*, *) allocated (out_arr) 

stop 

end program test 
+0

Gibt es Probleme wie Stapelabstürze, wenn Sie mit den verschiedenen Strategien zurückkehren? Angenommen, Sie geben ein Array von 1 Million Real zurück. Überlaufen Sie den Stapel und wird er vom Funktionskontext in den Aufruferkontext kopiert? –

0
  1. `Intent (out) `kann ein Problem sein, wie Sie Annahmen über die Größe des Arrays machen müssen in weitergegeben werden.
  2. ein Array ist auch ein Problem, da der Empfangscode Rückkehr müssen Annahmen über die Größe des Arrays macht zurückgegeben werden
  3. Zeiger auf Arrays haben Probleme mit der Größe und dem Problem o f Annahmen treffen, ob der Zeiger zugeordnet ist oder nicht.
  4. die Alternative ist, ein Modul, und in diesem Modul einen Typen hat, zu schaffen, die sowohl einen zuweisbaren Array enthält, und eine ganze Zahl, die Größe des Arrays Detaillierung:
module mymodule 
    type myvector 
     double precision,allocatable::values(:) 
     integer::length 
    end type 
end module 

Dann kann Ihre Funktion sein:

function myvecreturner(someparam) 
    use mymodule 
    type(myvector)::myvecreturner 
    integer::someparam 

    allocate(myvecreturner%values(someparam)) 
    myvecreturner%length = someparam 
end function 

Und Sie können diese myvector Typen glücklich herumreichen. Denken Sie daran, die Zuordnung zu trennen, wenn Sie fertig sind ...

+1

Nun, technisch, Sie tragen bereits die Größe eines Arrays, ohne die Notwendigkeit für einen Typ. Anfragen mit 'size' erzielen den gleichen Effekt. –

+0

Es gibt auch Lösungen für # 2. Funktionen können zuweisbare Arrays zurückgeben. Siehe http://stackoverflow.com/questions/464772/function-returning-array-with-no-defined-explicit-shape –