2017-06-05 28 views
0

私は、アレイを追加するサブルーチンMatPathをしましたが、私は私がMatPathを呼び出すサブルーチンでこの配列を宣言すべきか理解していない:サブルーチンでサイズを変更して配列を宣言するにはどうすればよいですか?

!********************************************************************** 
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 

私は配列を宣言することができますどのようにそれはまだ不明だサイズサブルーチンで修正されるだろう...誰かがそれがどのように動作するかを説明することができれば、ありがとう!

EDIT

私は私の配列Aのサイズの変更を取得し、メインプログラムのサブルーチンを終了する間にそれを渡すことができますどのようにここに私の問題の簡素化、より明確にするためには? :私はそれが私に"SIGSEV, segmentation fault occured"を与えるか、単に任意のメッセージなしで永久に実行することを行うようにしようとすると

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 

....

答えて

2

まず、コンパイラからのいくつかのエラーメッセージが確かにありました。質問にエラーメッセージを表示してください。

では、サブルーチンと呼ばれ、ダミー引数allocatableを宣言します。それは正しいです。

サブルーチンを呼び出すと、配列allocatableは宣言されていません。それは正しくありません。割り当て可能な仮引き数に変数を渡すと、その変数自体が割り振り可能でなければなりません。

だから、両方PathStFINDPATH割り当て可能でなければなりません。

からallocatable属性を削除し、次にStallocatableにする必要はありません。

ので(テストしていません):

!********************************************************************** 
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 

また、呼び出し元のサブルーチン内IMPLICIT NONEの存在は、あなたのサブルーチンは、モジュールに含まれていないという疑いに私をリードしています。それらはにする必要があります。割り当て可能な引数には明示的なインタフェースが必要なため、明示的なインタフェースを他の手段で設定する必要があります。


(もテストされていない)は、第2のバージョン:

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 

ここ醜さとinteger(4)real(8)の非移植についての私のいつもの暴言を挿入します。

あなたが

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

だけではなく

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

あなたがどこかに引数として渡していない限り、前者が良いかもしれない理由は単純にありませんしたい場合がありますなぜ私は想像することはできません

種類2が必要です。

+0

ありがとう、私はモジュールについての部分を理解していないのですか?私のコード全体は同じページにあり、私は他のサブルーチン、つまりメインプログラムを呼び出しています....私もやっているテストで私の投稿を編集します – Dadep

+1

あなたは**モジュールを使用する必要があります** 。サブルーチンはモジュール内になければなりません。あるいは、サブルーチンを 'CONTAINS'と' END PROGRAM'の間で動かすこともできますが、これは短いプログラムの場合にのみ有効です。サブルーチンが同じソースファイルにあるかどうかは関係ありません。 –

+0

配列がINTENT(OUT)の場合はどうなりますか?それは自動的にサブルーチンに割り当てられますか? – Holmz

関連する問題