Найти в Дзене

Программные единицы в Фортране: от главной программы до модулей

Fortran, один из старейших и всё ещё чрезвычайно востребованных языков в научных и инженерных расчётах, построен на концепции программных единиц (program units). Это логически обособленные части программы, которые взаимодействуют друг с другом через чётко определённые интерфейсы. Понимание этих единиц — ключ к написанию структурированного, эффективного и поддерживаемого кода на современном Fortran (стандарты Fortran 90 и новее). Это точка входа в приложение. Каждая выполняемая программа на Fortran должна иметь ровно одну главную программу. Пример: Этот пример не будет сейчас работать, поскольку в нём используются неизвестные программе модуль и подпрограмма. Но дальше мы сделаем его рабочим. Это фундаментальные единицы для структурирования кода. Они содержат логику и вычисления. а) SUBROUTINE (подпрограмма) Пример: б) FUNCTION (функция) Пример: Ключевое отличие: SUBROUTINE используется для действий, FUNCTION — для вычисления значения. Для функций рекомендуется всегда использовать RESUL
Оглавление

Fortran, один из старейших и всё ещё чрезвычайно востребованных языков в научных и инженерных расчётах, построен на концепции программных единиц (program units). Это логически обособленные части программы, которые взаимодействуют друг с другом через чётко определённые интерфейсы. Понимание этих единиц — ключ к написанию структурированного, эффективного и поддерживаемого кода на современном Fortran (стандарты Fortran 90 и новее).

1. Главная программа (Main Program)

Это точка входа в приложение. Каждая выполняемая программа на Fortran должна иметь ровно одну главную программу.

  • Структура: Начинается с ключевого слова PROGRAM, за которым следует имя, и заканчивается END PROGRAM [имя].
  • Назначение: Организация общего потока управления: вызов подпрограмм, управление вводом-выводом, определение основных структур данных.
  • Особенность: В отличие от подпрограмм, главная программа не имеет списка аргументов.

Пример:

Этот пример не будет сейчас работать, поскольку в нём используются неизвестные программе модуль и подпрограмма. Но дальше мы сделаем его рабочим.

2. Подпрограммы: SUBROUTINE и FUNCTION

Это фундаментальные единицы для структурирования кода. Они содержат логику и вычисления.

а) SUBROUTINE (подпрограмма)

  • Структура: SUBROUTINE Имя(арг1, арг2, ...) ... END SUBROUTINE Имя.
  • Назначение: Выполнение действий (например, модификация массивов, вывод данных, итерационный процесс). Может возвращать множество значений через свои аргументы.
  • Возврат данных: Аргументы могут иметь определённое направление передачи данных INTENT(IN - вход), INTENT(OUT - выход) или INTENT(INOUT - вход-выход), что делает код надёжным и читаемым.
  • Вызов: С помощью ключевого слова CALL.

Пример:

-2

б) FUNCTION (функция)

  • Структура: FUNCTION Имя(арг1, арг2, ...) RESULT(имя_результата) ... END FUNCTION Имя.
  • Назначение: Вычисление одного значения (скаляра, массива, строки). Должна вести себя как математическая функция, то есть не иметь побочных эффектов (предпочтительно), не выполнять дополнительных действий, которые выходят за рамки функционала.
  • Возврат данных: Через переменную RESULT, тип которой объявляется в заголовке функции.
  • Вызов: Используется внутри выражений.

Пример:

-3

Ключевое отличие: SUBROUTINE используется для действий, FUNCTION — для вычисления значения. Для функций рекомендуется всегда использовать RESULT и атрибут PURE (чистая функция, без побочных эффектов), где это возможно.

3. МОДУЛИ (MODULE) — основа современного Фортрана

Модули — это мощнейшая абстракция, представляющая собой контейнер для объединения данных, подпрограмм, производных типов и интерфейсов.

  • Структура: MODULE Имя ... END MODULE Имя.
  • Назначение:
  • Объявление глобальных данных: Константы (PARAMETER), переменные, общие для группы подпрограмм. Заменяют устаревший COMMON.
  • Создание библиотек подпрограмм: Группировка связанных процедур.
  • Определение производных типов данных (структур): TYPE :: Person.
  • Создание общих интерфейсов (INTERFACE): Для перегрузки процедур (generic procedures).
  • Использование: Программная единица, которая хочет использовать содержимое модуля, должна включить оператор USE Имя_Модуля. Для контроля видимости используются USE, ONLY: ... и PRIVATE/PUBLIC.

Пример:

-4

А теперь сделаем так, чтобы программа, приведённая в первом примере, заработала:

-5

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

4. Подпрограмма-блок (BLOCK) — внутренняя единица

Не является независимой программной единицей в классическом понимании, но важна для локализации.

  • Структура: BLOCK ... END BLOCK.
  • Назначение: Создание локальных областей видимости внутри процедуры или главной программы. Переменные, объявленные внутри блока, не видны снаружи. Полезно для временных вычислений и управления временем жизни объектов.
  • Контекст: Может содержать собственные объявления и исполняемые операторы.

Пример внутри подпрограммы:

-6

Конструкция BLOCK доступна только в Фортран 2008 и выше. То есть в Фортран 90/95 она работать не будет (программа не скомпилируется).

Взаимодействие программных единиц: иерархия

Типичная структура современной программы на Fortran:

-7

Заключение

Сила современного Fortran заключается в грамотном использовании его программных единиц.

  • Разделяйте код на логические подпрограммы (FUNCTION для значений, SUBROUTINE для действий).
  • Инкапсулируйте связанные данные и процедуры в MODULE. Это замена устаревшим COMMON и INCLUDE.
  • Используйте главную программу только для управления потоком выполнения.
  • Чётко определяйте интерфейсы (через модули или явные INTERFACE блоки) для проверки типов на этапе компиляции.
  • Применяйте INTENT для всех аргументов подпрограмм — это предотвращает ошибки и документирует код.

Такой модульный подход превращает Fortran из языка "простого вычисления формул" в мощный инструмент для создания больших, сложных, но при этом ясных и надёжных научных приложений.

На этом всё. Подписывайтесь на канал, чтобы ничего не пропустить.