如何在子程序中声明一个大小修改的数组?

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。那是不正确的。如果将任何变量传递给可分配的虚拟参数,则该变量本身必须是可分配的。

因此 PathSt 都必须在 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 的地方。