- •Предисловие
- •1. Элементы языка
- •1.1. Свободная форма записи программы
- •1.2. Консоль-проект
- •1.2.1. Создание проекта в CVF
- •1.2.2. Создание проекта в FPS
- •1.2.3. Операции с проектом
- •1.2.4. Файлы с исходным текстом
- •1.3. Операторы
- •1.4. Объекты данных
- •1.5. Имена
- •1.6. Выражения и операции
- •1.7. Присваивание
- •1.8. Простой ввод/вывод
- •1.8.1. Некоторые правила ввода
- •1.8.2. Ввод из текстового файла
- •1.8.3. Вывод на принтер
- •1.9. Рекомендации по изучению Фортрана
- •1.10. Обработка программы
- •2. Элементы программирования
- •2.1. Алгоритм и программа
- •2.2. Базовые структуры алгоритмов
- •2.2.1. Блок операторов и конструкций
- •2.2.2. Ветвление
- •2.2.3. Цикл
- •2.2.3.1. Цикл "с параметром"
- •2.2.3.2. Циклы "пока" и "до"
- •2.2.4. Прерывание цикла. Объединение условий
- •2.3. Программирование "сверху вниз"
- •2.3.1. Использование функций
- •2.3.2. Использование подпрограмм
- •2.3.3. Использование модулей
- •2.4. Этапы проектирования программ
- •2.5. Правила записи исходного кода
- •3. Организация данных
- •3.1. Типы данных
- •3.2. Операторы объявления типов данных
- •3.2.1. Объявление данных целого типа
- •3.2.2. Объявление данных вещественного типа
- •3.2.3. Объявление данных комплексного типа
- •3.2.4. Объявление данных логического типа
- •3.3. Правила умолчания о типах данных
- •3.4. Изменение правил умолчания
- •3.5. Буквальные константы
- •3.5.1. Целые константы
- •3.5.2. Вещественные константы
- •3.5.3. Комплексные константы
- •3.5.4. Логические константы
- •3.5.5. Символьные константы
- •3.6. Задание именованных констант
- •3.7. Задание начальных значений переменных. Оператор DATA
- •3.8. Символьные данные
- •3.8.1. Объявление символьных данных
- •3.8.2. Применение звездочки для задания длины строки
- •3.8.3. Автоматические строки
- •3.8.4. Выделение подстроки
- •3.8.5. Символьные выражения. Операция конкатенации
- •3.8.6. Присваивание символьных данных
- •3.8.7. Символьные переменные как внутренние файлы
- •3.8.8. Встроенные функции обработки символьных данных
- •3.8.9. Выделение слов из строки текста
- •3.9. Производные типы данных
- •3.9.1. Объявление данных производного типа
- •3.9.2. Инициализация и присваивание записей
- •3.9.2.1. Конструктор производного типа
- •3.9.2.2. Присваивание значений компонентам записи
- •3.9.2.3. Задаваемые присваивания записей
- •3.9.3. Выражения производного типа
- •3.9.4. Запись как параметр процедуры
- •3.9.5. Запись как результат функции
- •3.9.6. Пример работы с данными производного типа
- •3.9.7. Структуры и записи
- •3.9.7.1. Объявление и присваивание значений
- •3.9.7.2. Создание объединений
- •3.9.8. Итоговые замечания
- •3.10. Целочисленные указатели
- •3.11. Ссылки и адресаты
- •3.11.1. Объявление ссылок и адресатов
- •3.11.2. Прикрепление ссылки к адресатам
- •3.11.3. Инициализация ссылки. Функция NULL
- •3.11.4. Явное открепление ссылки от адресата
- •3.11.5. Структуры со ссылками на себя
- •3.11.6. Ссылки как параметры процедур
- •3.11.7. Параметры с атрибутом TARGET
- •3.11.8. Ссылки как результат функции
- •4. Массивы
- •4.1. Объявление массива
- •4.2. Массивы нулевого размера
- •4.3. Одновременное объявление объектов разной формы
- •4.4. Элементы массива
- •4.5. Сечение массива
- •4.6. Присваивание массивов
- •4.7. Маскирование присваивания
- •4.7.1. Оператор и конструкция WHERE
- •4.7.2. Оператор и конструкция FORALL
- •4.8. Динамические массивы
- •4.8.1. Атрибуты POINTER и ALLOCATABLE
- •4.8.2. Операторы ALLOCATE и DEALLOCATE
- •4.8.3. Автоматические массивы
- •4.9. Массивы - формальные параметры процедур
- •4.9.1. Массивы заданной формы
- •4.9.2. Массивы, перенимающие форму
- •4.9.3. Массивы, перенимающие размер
- •4.10. Использование массивов
- •4.11. Массив как результат функции
- •4.12. Встроенные функции для массивов
- •4.12.1. Вычисления в массиве
- •4.12.2. Умножение векторов и матриц
- •4.12.3. Справочные функции для массивов
- •4.12.3.1. Статус размещаемого массива
- •4.12.3.2. Граница, форма и размер массива
- •4.12.4. Функции преобразования массивов
- •4.12.4.1. Элементная функция MERGE слияния массивов
- •4.12.4.2. Упаковка и распаковка массивов
- •4.12.4.3. Переформирование массива
- •4.12.4.4. Построение массива из копий исходного массива
- •4.12.4.5. Функции сдвига массива
- •4.12.4.6. Транспонирование матрицы
- •4.13. Ввод/вывод массива под управлением списка
- •4.13.1. Ввод/вывод одномерного массива
- •4.13.2. Ввод/вывод двумерного массива
- •5. Выражения, операции и присваивание
- •5.1. Арифметические выражения
- •5.1.1. Выполнение арифметических операций
- •5.1.2. Целочисленное деление
- •5.1.3. Ранг и типы арифметических операндов
- •5.1.4. Ошибки округления
- •5.2. Выражения отношения и логические выражения
- •5.3. Задаваемые операции
- •5.4. Приоритет выполнения операций
- •5.5. Константные выражения
- •5.6. Описательные выражения
- •5.7. Присваивание
- •6. Встроенные процедуры
- •6.1. Виды встроенных процедур
- •6.2. Обращение с ключевыми словами
- •6.3. Родовые и специфические имена
- •6.4. Возвращаемое функцией значение
- •6.5. Элементные функции преобразования типов данных
- •6.6. Элементные числовые функции
- •6.7. Вычисление максимума и минимума
- •6.8. Математические элементные функции
- •6.8.1. Экспоненциальная, логарифмическая функции и квадратный корень
- •6.8.2. Тригонометрические функции
- •6.9. Функции для массивов
- •6.10. Справочные функции для любых типов
- •6.11. Числовые справочные и преобразовывающие функции
- •6.11.1. Модели данных целого и вещественного типа
- •6.11.2. Числовые справочные функции
- •6.12. Элементные функции получения данных о компонентах представления вещественных чисел
- •6.13. Преобразования для параметра разновидности
- •6.14. Процедуры для работы с битами
- •6.14.1. Справочная функция BIT_SIZE
- •6.14.2. Элементные функции для работы с битами
- •6.14.3. Элементная подпрограмма MVBITS
- •6.14.4. Пример использования битовых функций
- •6.15. Символьные функции
- •6.16. Процедуры для работы с памятью
- •6.17. Проверка состояния "конец файла"
- •6.18. Неэлементные подпрограммы даты и времени
- •6.19. Случайные числа
- •6.20. Встроенная подпрограмма CPU_TIME
- •7. Управляющие операторы и конструкции
- •7.1. Оператор GOTO безусловного перехода
- •7.2. Оператор и конструкции IF
- •7.2.1. Условный логический оператор IF
- •7.2.2. Конструкция IF THEN END IF
- •7.2.3. Конструкция IF THEN ELSE END IF
- •7.2.4. Конструкция IF THEN ELSE IF
- •7.3. Конструкция SELECT CASE
- •7.4. DO-циклы. Операторы EXIT и CYCLE
- •7.5. Возможные замены циклов
- •7.6. Оператор STOP
- •7.7. Оператор PAUSE
- •8. Программные единицы
- •8.1. Общие понятия
- •8.2. Использование программных единиц в проекте
- •8.3. Работа с проектом в среде DS
- •8.4. Главная программа
- •8.5. Внешние процедуры
- •8.6. Внутренние процедуры
- •8.7. Модули
- •8.8. Оператор USE
- •8.9. Атрибуты PUBLIC и PRIVATE
- •8.10. Операторы заголовка процедур
- •8.10.1. Общие характеристики операторов заголовка процедур
- •8.10.2. Результирующая переменная функции
- •8.11. Параметры процедур
- •8.11.1. Соответствие фактических и формальных параметров
- •8.11.2. Вид связи параметра
- •8.11.3. Явные и неявные интерфейсы
- •8.11.4. Ключевые и необязательные параметры
- •8.11.5. Ограничения на фактические параметры
- •8.11.6. Запрещенные побочные эффекты
- •8.12. Перегрузка и родовые интерфейсы
- •8.12.1. Перегрузка процедур
- •8.12.2. Перегрузка операций и присваивания
- •8.12.3. Общий вид оператора INTERFACE
- •8.13. Ассоциирование имен
- •8.14. Область видимости имен
- •8.15. Область видимости меток
- •8.16. Ассоциирование памяти
- •8.16.1. Типы ассоциируемой памяти
- •8.16.2. Оператор COMMON
- •8.16.3. Программная единица BLOCK DATA
- •8.17. Рекурсивные процедуры
- •8.18. Формальные процедуры
- •8.18.1. Атрибут EXTERNAL
- •8.18.2. Атрибут INTRINSIC
- •8.19. Оператор RETURN выхода из процедуры
- •8.20. Оператор ENTRY дополнительного входа в процедуру
- •8.21. Атрибут AUTOMATIC
- •8.22. Атрибут SAVE
- •8.23. Атрибут STATIC
- •8.24. Атрибут VOLATILE
- •8.25. Чистые процедуры
- •8.26. Элементные процедуры
- •8.27. Операторные функции
- •8.28. Строка INCLUDE
- •8.29. Порядок операторов и директив
- •9. Форматный ввод/вывод
- •9.1. Преобразование данных. Оператор FORMAT
- •9.2. Программирование спецификации формата
- •9.3. Выражения в дескрипторах преобразований
- •9.4. Задание формата в операторах ввода/вывода
- •9.5. Списки ввода/вывода
- •9.5.1. Элементы списков ввода/вывода
- •9.5.2. Циклические списки ввода/вывода
- •9.5.3. Пример организации вывода
- •9.6. Согласование списка ввода/вывода и спецификации формата. Коэффициент повторения. Реверсия формата
- •9.7. Дескрипторы данных
- •9.8. Дескрипторы управления
- •9.9. Управляемый списком ввод/вывод
- •9.9.1. Управляемый именованным списком ввод/вывод
- •9.9.1.1. Объявление именованного списка
- •9.9.1.2. NAMELIST-вывод
- •9.9.1.3. NAMELIST-ввод
- •9.9.2. Управляемый неименованным списком ввод/вывод
- •9.9.2.1. Управляемый неименованным списком ввод
- •9.9.2.2. Управляемый неименованным списком вывод
- •10. Файлы Фортрана
- •10.1. Внешние и внутренние файлы
- •10.2. Позиция файла
- •10.3. Устройство ввода/вывода
- •10.4. Внутренние файлы
- •10.5. Внешние файлы
- •10.6. Записи
- •10.6.1. Типы записей
- •10.6.2. Записи фиксированной длины
- •10.6.3. Записи переменной длины
- •10.6.4. Сегментированные записи
- •10.6.5. Потоки
- •10.6.6. CR-потоки
- •10.6.7. LF-потоки
- •10.7. Передача данных с продвижением и без
- •10.8. Позиция файла перед передачей данных
- •10.9. Позиция файла после передачи данных
- •10.10. Двоичные последовательные файлы
- •10.11. Неформатные последовательные файлы
- •10.12. Текстовые последовательные файлы
- •10.13. Файлы, подсоединенные для прямого доступа
- •10.14. Удаление записей из файла с прямым доступом
- •10.15. Выбор типа файла
- •11. Операции над внешними файлами
- •11.1. Оператор BACKSPACE
- •11.2. Оператор REWIND
- •11.3. Оператор ENDFILE
- •11.4. Оператор OPEN
- •11.5. Оператор CLOSE
- •11.6. Оператор READ
- •11.7. Оператор ACCEPT
- •11.8. Оператор FIND
- •11.9. Оператор DELETE
- •11.10. Оператор UNLOCK
- •11.11. Оператор WRITE
- •11.12. Оператор PRINT
- •11.13. Оператор REWRITE
- •11.14. Оператор INQUIRE
- •11.15. Функция EOF
- •11.16. Организация быстрого ввода/вывода
- •12.1. Некоторые сведения об объектах ActiveX
- •12.2. Для чего нужен конструктор модулей
- •12.3. Интерфейсы процедур управления Автоматизацией
- •12.4. Идентификация объекта
- •12.5. Примеры работы с данными Автоматизации
- •12.5.1. OLE-массивы
- •12.5.2. BSTR-строки
- •12.5.3. Варианты
- •12.6. Другие источники информации
- •12.7. Как воспользоваться объектом ActiveX
- •12.8. Применение конструктора модулей
- •12.9. Пример вызова процедур, сгенерированных конструктором модулей
- •Приложение 1. Вывод русского текста в DOS-окно
- •Приложение 2. Нерекомендуемые, устаревшие и исключенные свойства Фортрана
- •П.-2.1. Нерекомендуемые свойства Фортрана
- •П.-2.1.1. Фиксированная форма записи исходного кода
- •П.-2.1.2. Оператор EQUIVALENCE
- •П.-2.1.3. Оператор ENTRY
- •П.-2.1.4. Вычисляемый GOTO
- •П.-2.1.5. Положение оператора DATA
- •П.-2.2. Устаревшие свойства Фортрана, определенные стандартом 1990 г.
- •П.-2.2.1. Арифметический IF
- •П.-2.2.2. Оператор ASSIGN присваивания меток
- •П.-2.2.3. Назначаемый GOTO
- •П.-2.2.4. Варианты DO-цикла
- •П.-2.2.5. Переход на END IF
- •П.-2.2.6. Альтернативный возврат
- •П.-2.2.7. Дескриптор формата H
- •П.-2.3. Устаревшие свойства Фортрана, определенные стандартом 1995 г.
- •П.-2.4. Исключенные свойства Фортрана
- •Приложение 3. Дополнительные процедуры
- •П.-3.1. Запуск программ
- •П.-3.2. Управление программой
- •П.-3.3. Работа с системой, дисками и директориями
- •П.-3.4. Управление файлами
- •П.-3.5. Генерация случайных чисел
- •П.-3.6. Управление датой и временем
- •П.-3.7. Ввод с клавиатуры и генерация звука
- •П.-3.8. Обработка ошибок
- •П.-3.9. Аргументы в командной строке
- •П.-3.10. Сортировка и поиск в массиве
- •П.-3.11. Управление операциями с плавающей точкой
- •Литература
- •Предметный указатель
- •Оглавление
О. В. Бартеньев. Современный ФОРТРАН
real, public :: a = 3.0, b = 4.0 |
|
|
public :: length |
! Подпрограмма square доступна |
|
private :: square |
||
contains |
! только в модуле pupr |
|
real function length(x, y) |
|
|
real, intent(inout) :: x, y |
|
|
call square(x, y) |
|
|
length = sqrt(x + y) |
|
|
end function |
|
|
subroutine square(x1, y1) |
|
|
real, intent(inout) :: x1, y1 |
|
|
x1 = x1 * x1 |
|
|
y1 = y1 * y1 |
|
|
end subroutine |
|
|
end module pupr |
|
|
program gopu |
|
|
use pupr |
|
|
print *, length(ep%x, ep%y) |
! |
5.000000 |
print *, length(a, b) |
! |
5.000000 |
end |
|
|
8.10. Операторы заголовка процедур
Полный синтаксис оператора заголовка подпрограммы: |
|
[RECURSIVE] SUBROUTINE имя подпрограммы |
& |
[([список формальных параметров])] |
|
Общий вид оператора заголовка функции: |
|
[type] [RECURSIVE] FUNCTION имя функции |
& |
([список формальных параметров]) [RESULT (имя результата)]
8.10.1. Общие характеристики операторов заголовка процедур
Имя процедуры (подпрограммы и функции) может быть глобальным
ивнешним или внутренним в процедуре-носителе. Имя процедуры не может появляться в операторах AUTOMATIC, COMMON, EQUIVALENCE, DATA, INTRINSIC, NAMELIST, SAVE. Имя подпрограммы не может появляться в операторах объявления типа.
Список формальных параметров может содержать имена переменных
иформальных процедур. В случае подпрограммы формальным параметром может быть и обозначающая альтернативный возврат звездочка. Формальные параметры могут отсутствовать, если передача данных выполняется посредством use-ассоциирования, ассоциирования через носитель или com- mon-блоки.
Процедура может содержать любые операторы, кроме BLOCK DATA
иPROGRAM. До оператора CONTAINS процедура не может содержать
232
8. Программные единицы
операторы FUNCTION и SUBROUTINE. Внутренние процедуры не могут содержать операторы ENTRY и CONTAINS и другую внутреннюю процедуру. Внутренние процедуры размещаются между операторами CONTAINS и END главной программы или процедуры-носителя.
Если процедура внешняя, то ее имя является глобальным и не должно совпадать с другим глобальным именем, а также не должно быть использовано для локального имени в вызывающей программной единице. В случае внутренней процедуры ее имя является локальным и область его действия ограничена носителем.
Если формальный параметр имеет атрибут OPTIONAL, то при вызове соответствующий фактический параметр может быть опущен. Типы формальных параметров могут быть заданы внутри процедуры как неявно, так и явно (последнее предпочтительнее). Имена формальных параметров не могут появляться в операторах AUTOMATIC, COMMON, DATA, EQUIVALENCE, INTRINSIC, SAVE или STATIC.
При вызове процедуры передаваемые фактические параметры должны быть согласованы с соответствующими формальными по порядку (за исключением случаев, когда используются вызовы с ключевыми словами), по числу (за исключением случаев, когда заданы атрибуты OPTIONAL или C), по типу и разновидности типа. Компилятор проверяет соответствие параметров. При обнаружении несоответствия, как правило, генерируются ошибки. Полная проверка соответствия фактических и формальных параметров выполняется компилятором при явном задании интерфейса к процедуре. Явным интерфейсом обладают модульные и внутренние процедуры.
Полезно явно задавать интерфейс и к внешним процедурам, а в большом числе случаев он просто необходим (разд. 8.11.3).
Если вызываемая процедура находится в динамической библиотеке (DLL), то необходимо задавать ее интерфейс и использовать с ней атрибуты
DLLEXPORT или DLLIMPORT [1].
Выход из процедуры осуществляется в результате выполнения либо оператора END, либо оператора RETURN. Последний может быть размещен где угодно среди исполняемых операторов процедуры.
8.10.2. Результирующая переменная функции
Функция обязана содержать результирующую переменную, в которую помещается возвращаемый функцией результат.
Имя результирующей переменной задается предложением RESULT или совпадает с именем функции, если это предложение опущено. Задаваемое предложением RESULT имя результата не может совпадать с
именем функции.
Тип результирующей переменной определяет тип функции и может быть задан посредством указания type в заголовке функции.
233
О. В. Бартеньев. Современный ФОРТРАН
type - объявление типа и разновидности типа результирующей переменной (возвращаемого функцией результата). Может быть любого встроенного типа.
type может быть опущен. Тогда тип результирующей переменной может быть задан явно в одном из операторов объявления функции, в операторе IMPLICIT или неявно. Последнее невозможно, если заданы оператор IMPLICIT NONE или директива $DECLARE.
Если в операторе заголовка задан type, то имя результирующей переменной не должно появляться в разделе объявлений функции.
Примеры объявления результирующей переменной:
function imax(a, n) |
! Результирующая переменная imax; |
integer a(n) |
! ее тип INTEGER задан неявно |
... |
! Исполняемые операторы |
logical function flag(a, n) |
! Результирующая переменная flag; |
integer a(n) |
! ее тип LOGICAL задан явно |
function flag(a, n) |
! Результирующая переменная flag; |
logical flag |
! ее тип LOGICAL задан явно |
function flag(a, n) result(vf) |
! Результирующая переменная vf; |
logical vf |
! ее тип LOGICAL задан явно |
Если тип внешней |
функции определен без учета правил умолчаний |
о типах данных или заданы оператор IMPLICIT NONE или директива $DECLARE, то тип функции либо должен быть объявлен в вызывающей программной единице, либо там должен быть задан интерфейс к этой функции. На модульные и внутренние функции это требование не распространяется, поскольку они и без того имеют явно заданный интерфейс.
Пример:
logical function flag(a, n) result (vf)
...
vf = ... ! Определяем значение результирующей переменной end
program fude |
! Объявляем функцию flag в вызывающей программе |
logical flag, fl |
|
... |
! Тип объявляемой функции определяется типом |
fl = flag(a, n) |
! результирующей переменной |
... |
|
end |
|
Если результатом функции является переменная производного типа, массив или ссылка, то type опускается и результирующая переменная объявляется в разделе объявлений функции.
234
8. Программные единицы
Результирующая переменная подобна параметру с видом связи OUT. При входе в функцию она не определена, далее получает значение, которое затем используется в вызывающей программной единице.
Результирующая переменная может использоваться в выражениях функции, и в результате вычислений она должна получить значение. Последнее значение результирующей переменной используется в выражении, из которого функция вызвана. Результирующая переменная после выполнения функции может быть не определена, если она является ссылкой и вызов функции выполнен не из выражения (разд. 3.11.8). Обычно результирующая переменная получает значение в результате присваивания. Но это необязательно. Например, в случае символьной функции результирующая переменная может быть определена после выполнения оператора (разд. 3.8.7)
WRITE(имя результата, спецификатор формата) выражение
Результирующая переменная может быть скаляром или массивом любого встроенного и производного типа, также она может быть и ссылкой (разд. 3.11.8). Результатом функции не может быть перенимающий размер массив.
Так же как и в случае подпрограммы, функция может возвращать данные и через передаваемые по ссылке параметры (параметры с видом связи OUT или INOUT). Однако такой способ передачи данных может привести к побочным эффектам (разд. 8.11.6) ипоэтому не может быть рекомендован.
Пример. Найти сумму последних отрицательных элементов массивов a и b. Поиск последнего отрицательного элемента в массиве выполним в функции finel.
program nel
integer :: a(8) = (/1, -1, 2, -2, 3, -3, 4, -4 /) integer :: b(10) = (/1, 2, 3, 4, 5, -1, -2, -3, -4, -5 /)
integer :: finel |
! |
Объявляем тип функции |
print *, finel(a, 8) + finel(b, 10) ! |
Вызов функции из выражения |
|
end |
! |
-9 |
function finel(c, n) |
|
|
integer finel |
! Объявляем тип результирующей переменной |
|
integer c(n), i |
! Используем массив заданной формы |
|
finel = 0 |
! Определим результирующую переменную на |
|
do i = n, 1, -1 |
! случай, если в массиве нет отрицательных |
|
if(c(i) < 0) then |
! элементов |
|
finel = c(i) |
|
|
return |
! Возвратим последний отрицательный элемент |
|
end if |
|
|
end do
end function
235