如何在子例程中声明具有大小修改的数组?

时间:2017-06-05 13:27:06

标签: fortran 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"或者只是在没有任何消息的情况下永远奔跑....

1 个答案:

答案 0 :(得分:2)

首先,编译器肯定会出现一些错误消息。请在我们的问题中显示您的错误消息。

调用子例程中,声明伪参数allocatable。这是对的。

调用子例程中,您没有声明数组allocatable。这是不正确的。如果将任何变量传递给可分配的伪参数,则该变量本身必须是可分配的。

因此PathSt 必须在FINDPATH内分配

您可以从allocatable删除Start属性,然后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类的地方,否则没有理由说前者可能会更好。