Как обрабатывать глобальные распределяемые переменные Fortran в модуле между подпрограммами

У меня есть следующий модуль с выделяемой переменной, которая определена в модуле, выделена в подпрограмме, а затем также используется во второй подпрограмме, вызываемой первой подпрограммой. В этой ситуации я должен передать переменную второй подпрограмме и объявить INTENT(inout)? Или, поскольку это глобальная переменная, ее не нужно передавать в качестве аргумента?

MODULE test

  IMPLICIT NONE
  SAVE

  REAL,ALLOCATABLE,DIMENSION(:,:,:) :: total

CONTAINS

  !--- 1st subroutine
  SUBROUTINE my_subr1(n,m,z)
    IMPLICIT NONE
    INTEGER,INTENT(in) :: n,m,z
    ALLOCATE(total (n,m,z))
    total=.9
    CALL my_subr2(n)

  END SUBROUTINE my_subr1

  !-- 2nd subroutine
  SUBROUTINE my_subr2(n)
    IMPLICIT NONE
    INTEGER,INTENT(in) :: n

    total(n,:,:)=total(n-1,:,:)
  END SUBROUTINE my_subr2
END MODULE test

person Herman Toothrot    schedule 25.02.2019    source источник
comment
Используйте тег fortran для всех вопросов Fortran.   -  person Vladimir F    schedule 25.02.2019
comment
Все подпрограммы в модуле имеют доступ к total. Переменные модуля также сохраняются по умолчанию. Однако в вашем коде есть проблемы (нет объявления фиктивных аргументов в my_subr1 и нет end module ....   -  person Pierre de Buyl    schedule 25.02.2019


Ответы (1)


мне нужно передать переменную второй подпрограмме и объявить INTENT(inout)?

Нет, не знаешь. Любая переменная, декольированная в теле модуля, по умолчанию имеет атрибут save. Однако вы должны убедиться, что вторая подпрограмма вызывается только после выполнения первой, иначе программа завершится ошибкой, поскольку total еще не будет инициализирована.

Все функции и подпрограммы, объявленные в модуле, будут иметь доступ к total по ассоциации с хостом.


Кстати, есть некоторые проблемы, которые вы должны решить в своем коде, как упоминал @PierredeBuyl в комментариях:

  • Переменные, объявленные в теле модуля, по умолчанию сохраняются; вы должны удалить оператор SAVE.
  • Процедуры, объявленные в модуле, наследуют директиву IMPLICIT из области модуля, нет необходимости повторно объявлять ее в подпрограмме, если вы не будете ее менять.
  • Вам не хватает объявления аргументов в my_subr1.
person Rodrigo Rodrigues    schedule 25.02.2019
comment
Атрибут save здесь не очень актуален. Даже в стандартах Фортрана, где этот атрибут отсутствует по умолчанию, вызов от my_subr1 к my_subr2 означает, что переменная не выходит за пределы области видимости между ними. - person francescalus; 25.02.2019
comment
спасибо за объяснение, я прочитал о SAVE и IMPLICIT - person Herman Toothrot; 26.02.2019