如何在子程序中声明一个大小修改的数组?
How to declare an array with size modification in a subroutine?
我做了一个子例程 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
我仍然不清楚如何声明一个数组,其大小将在子程序中修改...如果有人能解释它是如何工作的,谢谢!
编辑
为了更清楚地简化我的问题,我怎样才能修改我的数组 A
的大小并在主程序结束子例程之间传递它? :
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
当我尝试这样做时,它给我一个 "SIGSEV, segmentation fault occured"
或 运行 永远没有任何消息....
首先,编译器肯定有一些错误信息。请在我们的问题中显示您的错误消息。
在 调用的 子例程中,您声明了伪参数 allocatable
。没错。
在 调用 子例程中,您没有声明数组 allocatable
。那是不正确的。如果将任何变量传递给可分配的虚拟参数,则该变量本身必须是可分配的。
因此 Path
和 St
都必须在 FINDPATH
内分配 。
您可能可以从 Start
中删除 allocatable
属性,然后 St
也不必是 allocatable
。
所以(未测试):
!**********************************************************************
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
的存在使我怀疑您的子程序不在模块中。它们必须在模块中,否则必须通过其他方式建立显式接口,因为可分配参数需要显式接口。
第二个版本(也未测试):
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 的地方。
我做了一个子例程 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
我仍然不清楚如何声明一个数组,其大小将在子程序中修改...如果有人能解释它是如何工作的,谢谢!
编辑
为了更清楚地简化我的问题,我怎样才能修改我的数组 A
的大小并在主程序结束子例程之间传递它? :
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
当我尝试这样做时,它给我一个 "SIGSEV, segmentation fault occured"
或 运行 永远没有任何消息....
首先,编译器肯定有一些错误信息。请在我们的问题中显示您的错误消息。
在 调用的 子例程中,您声明了伪参数 allocatable
。没错。
在 调用 子例程中,您没有声明数组 allocatable
。那是不正确的。如果将任何变量传递给可分配的虚拟参数,则该变量本身必须是可分配的。
因此 Path
和 St
都必须在 FINDPATH
内分配 。
您可能可以从 Start
中删除 allocatable
属性,然后 St
也不必是 allocatable
。
所以(未测试):
!**********************************************************************
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
的存在使我怀疑您的子程序不在模块中。它们必须在模块中,否则必须通过其他方式建立显式接口,因为可分配参数需要显式接口。
第二个版本(也未测试):
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 的地方。