我想了解我要向您展示的背后的逻辑 如果我有'module.f90':
module def_dimens
integer :: dimens=4
end module def_dimens
'subr.f90':
subroutine sub(X)
integer :: X
integer :: S(1:X*5)
S=1
print*,S
end subroutine sub
和'main.f90':
program test
use def_dimens
call sub(dimens)
end program test
通过编译gfortran module.f90 subr.f90 main.f90
并运行结果,没有任何问题。
但是'main2.f90'由
给出program test
use def_dimens
integer :: A(1:dimens*5)
A=1
print*,A
end program test
并编译gfortran module.f90 main2.f90
我有错误,所以我必须使用可分配的数组:
program test
use def_dimens
integer,allocatable :: A(:)
allocate(A(1:dimens*5))
A=1
print*,A
end program test
或者我必须在模块中指定'dimens'作为参数(但这对我没用, 因为在比这更复杂的情况下,我需要一个变量,其值通过在使用之前调用另一个子程序来修复。)
所以我的问题是:为什么会有这样的差异?为什么gfortran会抱怨它 必须通过使用变量来修改其大小来在主程序中声明一个数组,而在子例程中执行该操作没有任何问题吗?
答案 0 :(得分:2)
您不能拥有静态定义的数组,其中包含编译器认为 variable 的变量。错误代码(打印过它)非常清楚:
错误:(1)处的模块或主程序数组
a
必须具有恒定的形状
编译器不知道dimens
假设是不变的。您可以将dimens
声明为parameter
:
module def_dimens
integer, parameter :: dimens=4
end module
答案 1 :(得分:2)
要添加到Kyle的答案,如果在子例程中声明一个数组,该数组不是伪参数,或者它没有save
属性,则它是automatic array
。每次子程序开始运行时都会自动分配。它是根据表达式中变量的值为其形状分配的。调用之间不保留数组中的值。