3

我想了解我将向您展示的内容背后的逻辑。
如果我有一个“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 必须在主程序中通过使用变量来固定其大小来声明一个数组,而在子程序中这样做没有任何问题?

4

2 回答 2

2

您不能拥有一个静态定义的数组,其中包含编译器认为是variable的变量。错误代码(您是否打印过)非常清楚:

错误:(1)处的模块或主程序数组a必须具有恒定的形状

编译器不知道它dimens应该常量。您可以通过声明dimens为来解决此问题parameter

module def_dimens
   integer, parameter :: dimens=4
end module
于 2013-08-22T15:10:53.873 回答
2

为了补充凯尔的答案,如果您在子例程中声明一个数组,该数组不是虚拟参数或没有save属性,则它是一个automatic array . 每次子程序开始运行时自动分配。它是根据其形状表达式中变量的值分配的。调用之间不保留数组中的值。

于 2013-08-22T15:23:13.513 回答