- •Предисловие
- •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. Управление операциями с плавающей точкой
- •Литература
- •Предметный указатель
- •Оглавление
О. В. Бартеньев. Современный ФОРТРАН
• для формальных параметров - процедур (формальных процедур).
8.11.3. Явные и неявные интерфейсы
Интерфейс между процедурой и вызывающей ее программной единицей считается заданным, если вызывающей программной единице известны имя процедуры, ее вид (подпрограмма или функция), свойства функции (если процедура - функция), имена, положение и свойства формальных параметров.
ВФортране 77 интерфейс к вызываемой процедуре полностью неизвестен и он устанавливается при вызове по списку фактических параметров. Устанавливаемый таким образом интерфейс называется неявным. Такие вызовы могут быть причиной ряда ошибок, поскольку компилятор не всегда имеет возможность, например, проверить, соответствуют ли фактические и формальные параметры так, как это им положено.
Вызовы внешних процедур с неявным интерфейсом допустимы и в современном Фортране. В случае функции при неявном интерфейсе ее тип
иразновидность типа задаются в одном из операторов объявления типа вызывающей программной единицы или устанавливаются в соответствии с действующими правилами умолчания.
Однако формальные параметры процедур и процедуры-функции могут обладать дополнительными свойствами, о которых должен знать компилятор, чтобы правильно организовать доступ к коду процедуры. Чтобы сообщить компилятору такие сведения, между вызывающей программной единицей и процедурой должен существовать явный интерфейс.
Вслучае внутренней процедуры вызывающая программная единица и ее процедура компилируются как единое целое, поэтому компилятор знает все
олюбой внутренней процедуре, т. е. между внутренней процедурой и вызывающей программной единицей существует явный интерфейс.
Модульная процедура вызывается либо в самом модуле, либо из программной единицы, где вызову предшествует оператор USE для этого модуля. Поэтому в обоих случаях компилятор знает все о вызываемой процедуре и, следовательно, ее интерфейс является явным.
Также все встроенные процедуры заведомо обладают явным интерфейсом.
Вслучае внешней процедуры к ней также может быть установлен явный интерфейс. Это делается при помощи интерфейсного блока, имеющего вид:
INTERFACE
тело интерфейса
END INTERFACE
Тело интерфейса содержит описание одного и более интерфейсов процедур. Как правило, интерфейс процедуры - это точная копия заголовка
240
8. Программные единицы
процедуры, объявлений ее формальных параметров, типа функции в случае процедуры-функции и оператора END процедуры. Однако в интерфейсном блоке:
•имена параметров могут отличаться от имен соответствующих формальных параметров процедуры;
•могут быть добавлены дополнительные спецификации (например, объявления локальных переменных) за исключением описаний внутренних процедур и операторов DATA и FORMAT;
•можно представлять ту же информацию при помощи другой комбинации операторов объявления.
Пример:
subroutine sub1(i1, i2, r1, r2) |
|
integer :: i1, i2 |
|
real :: r1, r2 |
! В разделе объявлений процедуры атрибут |
... |
! OPTIONAL может быть опущен. Достаточно того, |
end subroutine sub1 |
! что он задан в интерфейсном блоке |
|
program idem
interface ! Интерфейс подпрограммы sub1 subroutine sub1(int1, int2, real1, real2)
integer :: int1, int2
real, optional :: real1, real2 end subroutine sub1
end interface
Также |
может |
быть задан интерфейс внешних процедур, написанных |
на других языках программирования, например на ассемблере или CИ. |
||
Наличие |
таких |
интерфейсов позволяет создавать разноязычные |
приложения [1].
Задание интерфейса означает, что упоминаемые в нем процедуры рассматриваются как внешние. Любая встроенная процедура с таким же именем становится недоступной. Такой же эффект имеет и упоминание имени процедуры в операторе EXTERNAL. Одновременное упоминание имени процедуры в теле интерфейса и операторе EXTERNAL недопустимо.
Интерфейсный блок размещается среди операторов описания. Удобнее всего собрать интерфейсные блоки в одном или нескольких модулях и подключать их по мере необходимости при помощи оператора USE.
Задание явного интерфейса необходимо, если:
•процедура имеет необязательные формальные параметры;
•результатом процедуры-функции является массив (разд. 4.11);
•формальным параметром процедуры является перенимающий форму массив (разд. 4.9.2), ссылка или ее адресат (разд. 3.11.8);
241
О. В. Бартеньев. Современный ФОРТРАН
•длина результата символьной функции не является константой и не перенимается из вызывающей программной единицы;
•результатом процедуры-функции является ссылка;
•процедура является динамической библиотекой. Также интерфейсные блоки употребляются:
•при вызове процедуры с ключевыми словами (разд. 8.11.4);
•при использовании задаваемого присваивания (разд. 8.12.2);
•при использовании задаваемых операций (разд. 8.12.2);
•при использовании в вызове родового имени (разд. 8.12);
•для доступа к внешним, написанным на других языках процедурам [1].
8.11.4. Ключевые и необязательные параметры
При некоторых вызовах процедуры часть фактических параметров может не использоваться. Примером такой процедуры может послужить встроенная функция SUM(array [, dim] [, mask]) (разд. 4.12.1), имеющая два необязательных параметра dim и mask. В этом случае соответствующие формальные параметры должны быть объявлены с атрибутом OPTIONAL. Как и другие атрибуты, OPTIONAL может быть использован в операторе объявления типа и как самостоятельный оператор.
Пример. Создать функцию npe(array, me, sig), возвращающую:
•сумму me первых положительных элементов массива array, если sig > 0;
•сумму me первых отрицательных элементов массива array, если sig < 0;
•сумму me первых элементов массива array, если sig = 0 или отсутствует;
•сумму всех заданных посредством sig-знака элементов массива, если отсутствует параметр me.
program tesop
integer, parameter :: m = 3, n = 10
integer :: a(n) = (/ 1, -1, 2, -2, 3, -3, 4, -4, 5, -5 /)
|
! Необходимо явно задать интерфейс к процедуре |
|
interface |
! с необязательными формальными параметрами |
|
integer function npe(array, me, sig) |
|
|
integer, intent(in) :: array(:) |
|
|
integer, intent(in), optional :: me, sig |
||
end function npe |
|
|
end interface |
|
|
print *, npe(a, m, 1) |
! |
6 |
print *, npe(a, sig = -1) |
! |
-15 |
print *, npe(a) |
! |
0 |
end program tesop |
|
|
integer function npe(array, me, sig) integer, intent(in) :: array(:)
integer, intent(in), optional :: me, sig integer mval, sval
242
|
8. Программные единицы |
integer, allocatable :: temp(:) |
|
if(.not. present(sig)) then |
! Использовать неассоциированный |
sval = 0 |
! необязательный формальный параметр |
else |
! можно только в качестве аргумента |
sval = sig |
! функции PRESENT |
end if |
|
if(present(me)) then |
|
mval = me |
|
else |
|
mval = size(array) |
|
end if |
|
select case(sval) |
! Размер temp может быть меньше mval |
case(1:) |
|
allocate(temp(min(mval, count(array > 0)))) |
|
temp = pack(array, array > 0) |
|
case(:-1) |
|
allocate(temp(min(mval, count(array < 0)))) |
|
temp = pack(array, array < 0) |
|
case(0) |
|
allocate(temp(mval)) |
|
temp = array(1:mval) |
|
endselect |
|
npe = sum(temp) |
! Возвращаемый результат |
deallocate(temp) |
|
end function npe |
|
Синтаксис оператора OPTIONAL: OPTIONAL [::] vname
Синтаксис атрибута OPTIONAL: type-spec, OPTIONAL [, attrs] :: vname
type-spec - спецификация любого типа данных.
vname - разделенные запятыми имена формальных параметров. Атрибут может быть использован только для формальных параметров
процедур. Интерфейс процедуры, содержащей атрибут OPTIONAL, должен быть описан явно. Формальный параметр, имеющий атрибут OPTIONAL, может дополнительно иметь только атрибуты DIMENSION, EXTERNAL, INTENT, POINTER и TARGET.
Если необязательный формальный параметр не задан, то ему не может быть присвоено значение и его нельзя использовать в выражении. Для определения того, задан формальный параметр или нет, используется встроенная функция
PRESENT(a)
243