在Fortran 90中,是否无法在新变量的声明语句中引用先前声明的变量?

发布于 2024-11-17 11:26:59 字数 743 浏览 7 评论 0原文

在 Fortran 中,变量的声明语句是否可以引用先前声明的变量?例如,当我尝试以下操作时:

PROGRAM test3
  IMPLICIT NONE

  INTEGER :: a=2286
  INTEGER :: b=a/3

  WRITE(*,*) a, b
END PROGRAM test3

我收到编译时错误消息:

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

另一方面,如果我在与b 的声明,它编译并运行良好:

PROGRAM test3
  IMPLICIT NONE

  INTEGER :: a=2286
  INTEGER :: b
  b=a/3

  WRITE(*,*) a, b
END PROGRAM test3

这给了我正确的输出:

2286         762

为什么会出现这种情况——先前声明的变量不能包含在新变量的声明语句中?我做错了什么吗?或者这只是“Fortran 生活中的事实”?

非常感谢您抽出时间!

In Fortran, is it possible for declaration statements for variables to refer to previously-declared variables? For example, when I try the following:

PROGRAM test3
  IMPLICIT NONE

  INTEGER :: a=2286
  INTEGER :: b=a/3

  WRITE(*,*) a, b
END PROGRAM test3

I get a compile-time error message:

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

On the other hand, if I assign b to a/2 in a statement separate from the declaration of b, it compiles and runs fine:

PROGRAM test3
  IMPLICIT NONE

  INTEGER :: a=2286
  INTEGER :: b
  b=a/3

  WRITE(*,*) a, b
END PROGRAM test3

which gives me the correct output:

2286         762

Why is this the case--that previously-declared variables cannot be included in declaration statements of new variables? Am I doing something wrong? Or is this just a "Fortran fact of life"?

Thank you very much for your time!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风苍溪 2024-11-24 11:26:59

让我再补充一件事:在主程序和参数中初始化这样的变量(好吧,您必须像这样为参数初始化它们),但它的行为可能会让您感到惊讶,如果您太习惯使用它并开始在子例程和函数中使用它:

例如,我们大多数人最初会假设该程序:

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

会打印

At start of bar: i =   3
At end of bar:   i =   4
At start of bar: i =   3
At end of bar:   i =   4

--- 但事实并非如此。它打印出

At start of bar: i =   3
At end of bar:   i =   4
At start of bar: i =   4
At end of bar:   i =   5

这是出于“历史原因”,因为当事情表现出明显错误的行为时,情况往往如此。在声明时初始化变量本质上将其转变为:

integer :: i

并且

integer, save :: i = 3

初始化仅在第一次完成。这意味着第二次,变量会记住它之前的值 (4) 并递增该值。

所以我写这篇文章的原因基本上是警告你不要在声明时初始化变量太舒服。我建议在参数和主程序中执行此操作(您不会遇到此问题,因为您只输入主程序一次),除此之外别无其他。

Let me just add one more thing: Initializing a variable like this works in main programs and for parameters (well, you have to initialize them like this for parameters), but it can surprise you with its behaviour if you get too used to using it and start using it in subroutines and functions:

For instance, most of us would initially assume that this program:

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

would print

At start of bar: i =   3
At end of bar:   i =   4
At start of bar: i =   3
At end of bar:   i =   4

--- but it doesn't. It prints

At start of bar: i =   3
At end of bar:   i =   4
At start of bar: i =   4
At end of bar:   i =   5

This is for "historical reasons", as things often are when they present behaviours which seem clearly wrong. Initializing a variable at declaration essentially turns this:

integer :: i

into

integer, save :: i = 3

and the initialization is done only the first time. That means the second time through, the variable remembers it's previous value (4) and increments that.

So my reason for writing this is basically to warn you not to get too comfortable initializing variables at declaration time. I recommend doing it for parameters, and in the main program (where you won't hit this issue since you only enter the main program once) and little else.

漫雪独思 2024-11-24 11:26:59

错误消息非常明确。变量声明中使用的初始值设定项必须是常量值。在您的示例中,a 不是常量。

它应该像这样工作:

PROGRAM test3
  IMPLICIT NONE

  INTEGER, PARAMETER :: a=2286
  INTEGER :: b=a/3

  WRITE(*,*) a, b
END PROGRAM test3

因为 a 是一个常量。

The error message is pretty explicit. Initializers used in variable declarations have to be constant values. In your example, a is not a constant.

It should work like this:

PROGRAM test3
  IMPLICIT NONE

  INTEGER, PARAMETER :: a=2286
  INTEGER :: b=a/3

  WRITE(*,*) a, b
END PROGRAM test3

because then a is a constant.

苏大泽ㄣ 2024-11-24 11:26:59

在“a”的声明中添加“,参数”。这将允许您在另一个声明中使用 a 的值。这也意味着“变量”a的值不能改变。

Add ", parameter" to the declaration of "a". This will allow you to use the value of a in another declaration. It also means that the value of the "variable" a cannot be changed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文