В Фортране 90 нельзя ли ссылаться на ранее объявленные переменные в операторе объявления новой переменной? - PullRequest
4 голосов
/ 28 июня 2011

В Фортране возможно ли, чтобы операторы объявления для переменных ссылались на ранее объявленные переменные? Например, когда я пытаюсь сделать следующее:

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 a / 2 в выражении, отдельном от объявления b , он компилируется и работает нормально:

PROGRAM test3
  IMPLICIT NONE

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

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

, который дает мне правильный вывод:

2286         762

Почему это так - ранее объявленные переменные не могут быть включены в операторы объявления новых переменных? Я делаю что-то неправильно? Или это просто "Фортранский факт жизни"?

Большое спасибо за потраченное время!

Ответы [ 3 ]

8 голосов
/ 28 июня 2011

Позвольте мне добавить еще одну вещь: Инициализация такой переменной работает в основных программах и для параметров (ну, у вас есть для их инициализации таким образом для параметров), но она может вас удивить своей поведение, если вы слишком привыкли к его использованию и начинаете использовать его в подпрограммах и функциях:

Например, большинство из нас изначально предполагали бы, что эта программа:

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) и увеличивает его на единицу.

Так что моя причина написания этого состоит в том, чтобы предупредить вас, чтобы не слишком удобно инициализировать переменные во время объявления. Я рекомендую делать это для параметров, а также в основной программе (где вы не решите эту проблему, поскольку вы входите в основную программу только один раз) и еще немного.

6 голосов
/ 28 июня 2011

Сообщение об ошибке довольно явное.Инициализаторы, используемые в объявлениях переменных, должны быть постоянными значениями.В вашем примере a не является константой.

Это должно работать так:

PROGRAM test3
  IMPLICIT NONE

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

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

, потому что тогда a является константой.

3 голосов
/ 28 июня 2011

Добавьте «, параметр» к объявлению «а». Это позволит вам использовать значение a в другой декларации. Это также означает, что значение «переменной» a нельзя изменить.

...