And*_*rew 4 fortran declaration
在Fortran中,变量的声明语句是否可以引用先前声明的变量?例如,当我尝试以下操作时:
PROGRAM test3
IMPLICIT NONE
INTEGER :: a=2286
INTEGER :: b=a/3
WRITE(*,*) a, b
END PROGRAM test3
Run Code Online (Sandbox Code Playgroud)
我收到编译时错误消息:
test3.f90:5.16:
INTEGER :: b=a/3
1
Error: Parameter 'a' at (1) has not been declared or is a variable, which
does not reduce to a constant expression
Run Code Online (Sandbox Code Playgroud)
另一方面,如果我在一个与b的声明分开的语句中将b分配给/ 2,它编译并运行正常:
PROGRAM test3
IMPLICIT NONE
INTEGER :: a=2286
INTEGER :: b
b=a/3
WRITE(*,*) a, b
END PROGRAM test3
Run Code Online (Sandbox Code Playgroud)
这给了我正确的输出:
2286 762
Run Code Online (Sandbox Code Playgroud)
为什么会这样 - 先前声明的变量不能包含在新变量的声明语句中?难道我做错了什么?或者这只是"生活中的Fortran事实"?
非常感谢您的宝贵时间!
让我再添加一件事:初始化一个像这样的变量可以在主程序和参数中使用(好吧,你必须像参数一样初始化它们),但是如果你太习惯使用它会让你的行为感到惊讶并开始在子程序和函数中使用它:
例如,我们大多数人最初会假设这个程序:
program foo
call bar
call bar
contains
subroutine bar
integer :: i=3
print '(A,I3)','At start of bar: i = ', i
i = i + 1
print '(A,I3)','At end of bar: i = ', i
end subroutine bar
end program foo
Run Code Online (Sandbox Code Playgroud)
会打印
At start of bar: i = 3
At end of bar: i = 4
At start of bar: i = 3
At end of bar: i = 4
Run Code Online (Sandbox Code Playgroud)
---但事实并非如此.它打印
At start of bar: i = 3
At end of bar: i = 4
At start of bar: i = 4
At end of bar: i = 5
Run Code Online (Sandbox Code Playgroud)
这是出于"历史原因",因为事情通常是当他们表现出看似明显错误的行为时.在声明中初始化变量基本上会变成这样:
integer :: i
Run Code Online (Sandbox Code Playgroud)
成
integer, save :: i = 3
Run Code Online (Sandbox Code Playgroud)
并且初始化仅在第一次完成.这意味着第二次,变量会记住它的前一个值(4)并递增它.
所以我写这篇文章的理由基本上是警告你不要在声明时初始化变量.我建议在参数和主程序中执行此操作(因为您只输入一次主程序,因此您不会遇到此问题).
错误消息非常明确.在变量声明中使用的初始值设定项必须是常量值.在您的示例中,a不是常量.
它应该像这样工作:
PROGRAM test3
IMPLICIT NONE
INTEGER, PARAMETER :: a=2286
INTEGER :: b=a/3
WRITE(*,*) a, b
END PROGRAM test3
Run Code Online (Sandbox Code Playgroud)
因为那a是一个常数.