2017-06-05 2 views
0

Ich habe ein Unterprogramm MatPath ein Array anhängen, aber ich verstehe nicht, wie ich diese Anordnung in der Unterprogramm erklären sollte, wo ich MatPath nennen:Wie deklariere ich ein Array mit Größenmodifikation in einem Unterprogramm?

!********************************************************************** 
SUBROUTINE MatPath(Path, Start) 
INTEGER(2),PARAMETER::Ximax = 5, Yimax = 5, Zimax = 1 
INTEGER(4)::W,B 
REAL(8), DIMENSION(:,:), ALLOCATABLE::Path 
REAL(8), DIMENSION(:,:), ALLOCATABLE::Temp_Array 
REAL(8), DIMENSION(:), ALLOCATABLE::Start 
W=SIZE(Path,DIM=2) 
ALLOCATE(Temp_Array(3,W)) 
DEALLOCATE(Path) 
ALLOCATE(Path(3,W+1)) 
Path(:,1:W)=Temp_Array(:,1:W) 
Path(:,W+1)=Start(:) 
DEALLOCATE(Temp_Array) 

RETURN 
END SUBROUTINE MatPath 
!************************************************ 
SUBROUTINE FINDPATH(Array, St) 
IMPLICIT NONE 
INTEGER(4), DIMENSION(3,3)::Array 
REAL(8), DIMENSION(3)::St 
REAL(8), DIMENSION(3, :)::Path !PROBLEM HERE 

CALL MatPath(Path, St) 

END SUBROUTINE FINDPATH 

Es ist immer noch unklar, wie ich ein Array deklarieren kann, die die Größe würde in einem Unterprogramm ändern ... Wenn jemand erklären kann, wie es funktioniert, Danke!

EDIT

klarer hier eine Vereinfachung meines Problems sein, wie kann ich Modifikation der Größe meiner Array erhalten A und es zwischen dem Hauptprogramm übergeben das Unterprogramm beenden? :

program teste10 

REAL(8),DIMENSION(:,:),ALLOCATABLE::A 

ALLOCATE(A(2,2)) 
A=1 
WRITE(*,*), "Initial A : ", A 

CALL TESTE1(A) 

WRITE(*,*) "new A : ", A 

DEALLOCATE(A) 
STOP 
end program teste10 
!********************************************** 
SUBROUTINE TESTE1(A) 

REAL(8),DIMENSION(:,:),INTENT(INOUT), ALLOCATABLE::A 
REAL(8), DIMENSION(:,:), ALLOCATABLE::Temp 
INTEGER(4)::X, Y 

X=SIZE(A, DIM=1) 
Y=SIZE(A, DIM=2) 
ALLOCATE(Temp(X,Y)) 
DEALLOCATE(A) 
ALLOCATE(A(X+2,Y+3)) 
A(1:X, 1:Y)=Temp(1:X,1:Y) 
A(X+1:X+2, Y+1:Y+3)=0 
DEALLOCATE(Temp) 

RETURN 
END SUBROUTINE TESTE1 

Wenn ich versuche, mir zu tun, dass es ein "SIGSEV, segmentation fault occured" geben oder einfach nur für immer ohne jede Nachricht laufen ....

Antwort

2

Erstens gibt sicherlich einige Fehlermeldung vom Compiler war. Bitte zeigen Sie Ihre Fehlermeldungen in unseren Fragen.

In der Unterroutine namens deklarieren Sie die Dummy-Argumente allocatable. Das ist richtig.

Im Aufruf Subroutine, haben Sie nicht die Arrays allocatable deklariert. Das ist nicht richtig. Wenn Sie eine Variable in ein zuweisbares Dummy-Argument übergeben, muss die Variable selbst zuweisbar sein.

So beide Path und Sthaben zuweisbaren innen FINDPATH sein.

Sie können wahrscheinlich das allocatable Attribut von Start entfernen und dann muss St nicht allocatable sein.

So (nicht getestet):

!********************************************************************** 
SUBROUTINE MatPath(Path, Start) 
    INTEGER :: W 
    REAL(something_better), DIMENSION(:,:), ALLOCATABLE :: Path 
    REAL(something_better), DIMENSION(:,:), ALLOCATABLE :: Temp_Array 
    REAL(something_better), DIMENSION(:),    :: Start 

    W=SIZE(Path,DIM=2) 
    ALLOCATE(Temp_Array(3,W)) 
    DEALLOCATE(Path) 
    ALLOCATE(Path(3,W+1)) 
    Path(:,1:W)=Temp_Array(:,1:W) 
    Path(:,W+1)=Start(:) 
    DEALLOCATE(Temp_Array) 
END SUBROUTINE MatPath 
!************************************************ 


SUBROUTINE FINDPATH(Array, St) 
    INTEGER, DIMENSION(3,3) :: Array 
    REAL(something_better), DIMENSION(3) :: St 
    REAL(something_better), DIMENSION(3, :), allocatable :: Path 

    CALL MatPath(Path, St) 

    !here do something with Path and Array? 
    !it is not clear what does Path and what does Array 
END SUBROUTINE FINDPATH 

Darüber hinaus ist die Anwesenheit von IMPLICIT NONE in der anrufenden Unterprogramm mich vermuten ließ, dass Ihre Subroutinen sind nicht in einem Modul. Sie müssen in einem Modul sein oder die explizite Schnittstelle muss auf andere Weise eingerichtet werden, da zuweisbare Argumente eine explizite Schnittstelle erfordern.


Die zweite Version (auch nicht getestet):

module Subroutines 
    implicit none 
    integer, parameter :: dp = kind(1.d0) 

contains 

    SUBROUTINE TESTE1(A) 
     REAL(dp), DIMENSION(:,:), INTENT(INOUT), ALLOCATABLE :: A 
     REAL(dp), DIMENSION(:,:), ALLOCATABLE :: Temp 
     INTEGER :: X, Y 

     X=SIZE(A, DIM=1) 
     Y=SIZE(A, DIM=2) 
     ALLOCATE(Temp(X,Y)) 
     DEALLOCATE(A) 
     ALLOCATE(A(X+2,Y+3)) 
     A(1:X, 1:Y) = Temp(1:X,1:Y) 
     A(X+1:X+2, Y+1:Y+3) = 0 
     DEALLOCATE(Temp) 
    END SUBROUTINE TESTE1 

end module 


program teste10 
    use Subroutines 

    implicit none 

    REAL(dp), DIMENSION(:,:), ALLOCATABLE :: A 

    ALLOCATE(A(2,2)) 
    A=1 
    WRITE(*,*), "Initial A : ", A 

    CALL TESTE1(A) 

    WRITE(*,*) "new A : ", A 

    DEALLOCATE(A) 
end program teste10 

Hier meine übliche schimpfen über Hässlichkeit und Nicht-Übertragbarkeit von integer(4) und real(8) einzufügen.

Ich kann mir nicht vorstellen, warum Sie

INTEGER(2),PARAMETER::Ximax = 5, Yimax = 5, Zimax = 1 

statt nur von möchten vielleicht

INTEGER, PARAMETER :: Ximax = 5, Yimax = 5, Zimax = 1 

Es gibt einfach keinen Grund, warum die ehemaligen besser sein könnte, wenn Sie es als ein Argument irgendwo passieren, wo Art 2 ist erforderlich.

+0

Vielen Dank, ich verstehe nicht den Teil über Module? Mein ganzer Code ist in der gleichen Seite und ich rufe eine Subroutine in einem anderen oder im Hauptprogramm auf .... Ich bearbeite auch meinen Pfosten mit dem Test, den ich tue – Dadep

+1

Sie ** MÜSSEN ** Module benutzen . Die Unterprogramme müssen in einem Modul sein. Oder Sie können die Subroutinen zwischen 'CONTAINS' und' END PROGRAM' verschieben, aber das ist nur für kurze Programme gut. Es spielt keine Rolle, ob die Unterprogramme in der gleichen Quelldatei sind oder nicht. –

+0

Was passiert, wenn das Array INTENT (OUT) ist? Wird es automatisch im Unterprogramm zugewiesen? – Holmz

Verwandte Themen