我需要摆脱Fortran程序使用的一些库,所以我必须在程序中使用的库中创建所有子程序。
其中一个子程序是内存分配,由C语言完成。
我为分配创建了自己的子程序
MODULE ARRAY_ALLOCATION
CONTAINS
SUBROUTINE ARRAY_ALLOCATE (ARR, ARR_SIZE, ARR_IDX, CODE_RET)
! DECLARE AN ALLOCATABLE PARAMETER
INTEGER, ALLOCATABLE, INTENT (INOUT) :: ARR(:)
INTEGER, INTENT (IN) :: ARR_SIZE,ARR_IDX,CODE_RET
INTEGER :: IDX_END
IDX_END = ARR_IDX + ARR_SIZE -1
ALLOCATE (ARR(ARR_IDX:IDX_END))
RETURN
END SUBROUTINE ARRAY_ALLOCATE
SUBROUTINE ARRAY_DEALLOCATE (ARR)
INTEGER, ALLOCATABLE, INTENT (INOUT) :: ARR(:)
DEALLOCATE (ARR)
RETURN
END SUBROUTINE ARRAY_DEALLOCATE
END MODULE
但是我需要保留数组的声明,就像integer alist(1)
一样,没有属性allocatable
。
例如
program test1
USE ARRAY_ALLOCATION
implicit none
integer alist(1)
call ARRAY_ALLOCATE(alist,5,3,1)
CALL Test(ALIST)
CALL ARRAY_DEALLOCATE(alist)
错误
error #7976: An allocatable dummy argument may only be argument associated with an allocatable actual argument
有没有办法在声明后制作我的数组allocatable
?
我正在考虑将它allocatable
(在声明之后)在子程序内部分配内存,这样就不必在我的旧程序中更改声明。
答案 0 :(得分:1)
有没有办法让我的数组在声明后可以分配?我正在考虑将其分配(在声明之后)在子程序内部分配内存,这样就不必在旧程序中更改声明。
没有
错误消息非常明确。您不能将不可分配的数组作为参数传递给期望可分配数组的函数。
以下声明:
integer alist(1)
正在创建一个1维大小的数组。
如果希望为数组分配动态,则必须将它们更改为可分配或使用指针。
编辑
从此处开始:http://web.stanford.edu/class/me200c/tutorial_77/12_arrays2.html
大多数程序员喜欢使用星号表示法强调"实际数组长度"不明。一些旧的Fortran 77程序可能会声明这样的可变长度数组:
real x(1), y(1)
即使数组长度大于1,这也是合法的语法! 但这是糟糕的编程风格,并且强烈反对。
P.S。这种表示法用于INSIDE子程序来定义变长数组参数。
编辑2
以下代码基于您的代码,演示了如何使用allocatable。
MODULE ARRAY_ALLOCATION
CONTAINS
SUBROUTINE ARRAY_ALLOCATE (ARR, ARR_SIZE, ARR_IDX, CODE_RET)
! DECLARE AN ALLOCATABLE PARAMETER
INTEGER, ALLOCATABLE, INTENT (INOUT) :: ARR(:)
INTEGER, INTENT (IN) :: ARR_SIZE,ARR_IDX,CODE_RET
INTEGER :: IDX_END
IDX_END = ARR_IDX + ARR_SIZE -1
ALLOCATE (ARR(ARR_IDX:IDX_END))
ARR = 1
RETURN
END SUBROUTINE ARRAY_ALLOCATE
SUBROUTINE ARRAY_DEALLOCATE (ARR)
INTEGER, ALLOCATABLE, INTENT (INOUT) :: ARR(:)
DEALLOCATE (ARR)
RETURN
END SUBROUTINE ARRAY_DEALLOCATE
subroutine Create (arr)
INTEGER, ALLOCATABLE, INTENT (INOUT) :: ARR(:)
call ARRAY_ALLOCATE(arr,5,3,1)
end subroutine Create
subroutine Destroy (arr)
INTEGER, ALLOCATABLE, INTENT (INOUT) :: ARR(:)
CALL ARRAY_DEALLOCATE(arr)
end subroutine Destroy
END MODULE
program Console1
USE ARRAY_ALLOCATION
implicit none
integer, allocatable :: alist(:)
if (allocated(alist)) then
print *, "is allocated"
else
print *, "is not allocated"
endif
call Create(alist)
if (allocated(alist)) then
print *, "is allocated"
else
print *, "is not allocated"
endif
print *, alist
CALL Destroy(alist)
if (allocated(alist)) then
print *, "is allocated"
else
print *, "is not allocated"
endif
end program Console1
预期结果将是这样的:
is not allocated
is allocated
1 1 1 1 1
is not allocated
编辑3
关于可分配数组,可以在此处找到有关为什么有人想要解除分配的简单解释https://www.phy.ornl.gov/csep/pl/node17.html:
可分配数组是显式声明为ALLOCATABLE的数组。可分配数组可以是过程的本地数据,也可以放在模块中,并且对应用程序的所有过程都是有效的。使用ALLOCATE语句显式分配可分配数组,并使用DEALLOCATE语句显式释放,或者如果它是未指定SAVE的本地数组,则在退出过程时自动释放。 (如果已指定SAVE,则本地可分配数组可以从过程的一次执行持续到下一次 - 它们必须使用DEALLOCATE语句显式释放。)全局可分配数组一直存在,直到它被显式释放,这可能发生在过程中不同于分配它的那个。
可以看出,有些情况下必须手动完成释放可分配数组。
答案 1 :(得分:0)
您可能不想删除库,而是让代码在其中工作。
通常它是这样的: 在图书馆......
MODULE A_Style !(_*_)
IMPLICIT NONE
PUBLIC: Aye
CONTAINS
SUBROUTINE Aye(A)
REAL, DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: A
!...
IF(ALLOCATED(A)) THEN
WRITE(*,*)' I see A as A(',LBOUND(A,1),':',UBOUND(A,1),')'
ELSE
WRITE(*,*)' I see A as "UNALLOCATED"'
ENDIF
!...
RETURN
END SUBROUTINE Aye
SUBROUTINE MakeAye(A, SizeA)
REAL, DIMENSION(:), ALLOCATABLE, INTENT(INOUT) :: A
!...
IF(ALLOCATED(A)A) DEALLOCATE(A)
ALLOCATE(A(SizeA))
!...
RETURN
END SUBROUTINE MakeAye
END MODULE A_Style
使用图书馆:
PROGRAM TestA
USE A_Style !(_*_)
IMPLICIT NONE
REAL, DIMENSION(:), ALLOCATABLE :: A
INTEGER :: Size_A = 100
...
CALL Aye(A)
ALLOCATE(A(Size_A))
CALL Aye(A)
...
IF(ALLOCATED(A)) DEALLOCATE(A)
END PROGRAM TestA
有时,有趣的是,子程序需要在模块中才能看到BOUNDS。然后,INTENT(OUT)将不会出现,因此需要使用(INOUT)或(IN)。