我正在尝试按如下方式初始化数组:
program test
n = 3
call it(n)
contains
subroutine it(n)
integer n,j
integer, dimension(3*(n-1)) :: a=(/(j,j=4,3*n,1)/)
write(*,*) a
end subroutine it
end program test
当我使用gfortran -o test.exe test.f
进行编译时,收到以下错误:
test.f:9.43:
integer, dimension(3*(n-1)) :: a=(/(j,j=4,3*n,1)/)
1
Error: Invalid character in name at (1)
有什么问题?据我了解,这是符合标准的代码。
答案 0 :(得分:5)
编译器错误可能令人困惑,但示例代码不符合标准。
类型声明语句中的初始值设定项必须是常量表达式。此外,自动数据对象可能没有SAVE属性。
初始化(没有限定形容词)只在Fortran中发生一次,在程序开始执行之前。因此,初始化程序中使用的表达式必须能够在程序开始执行之前进行评估(此类表达式中允许的内容(以及术语的各个方面)依赖于您编写的Fortran标准)。
示例代码中的初始化程序取决于n的值,这是一个伪参数。在程序开始执行之前,不能引用伪参数的值 - 它本身不是常量。
类似地,a
局部变量的属性(其形状)取决于伪参数的值。这使变量a
成为自动数据对象。不允许自动数据对象具有SAVE属性(对象的属性可能因呼叫而异,这与SAVE维持从调用到调用的值不一致)。提供初始值设定项也意味着SAVE属性。
如果n
是参数而不是伪参数,则代码将符合。
答案 1 :(得分:2)
以下是IanH已经解释过的两个允许的例子。在一种情况下,初始化器是一个常量表达式,因为M
是一个参数。另一方面,虽然初始化不是常量表达式,但它不是声明的一部分。
program test5
integer :: j
integer :: n = 3
integer, parameter :: M = 4
integer, dimension(3*(M-1)) :: b = [ (j,j=4,3*M,1) ]
write (*,*) b
call it(n)
contains
subroutine it(n)
integer n,j
integer, dimension(3*(n-1)) :: a
a = [ (j,j=4,3*n,1) ]
write(*,*) a
end subroutine it
end program test5