- •Предисловие
- •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. Параметры процедур
Обмен данными между процедурой и вызывающей программной единицей может быть выполнен через параметры процедуры.
Параметры, используемые при вызове процедуры, называются
фактическими.
Параметры, используемые в процедуре, называются формальными.
Пример. Сформировать вектор c1 из элементов вектора a, которых нет в векторе b1. Затем сформировать вектор c2 из элементов вектора a, которых нет в векторе b2. Формирование массивов выполним в подпрограмме fobc.
program part
integer, parameter :: na = 10, nb1 = 5, nb2 = 7 integer :: a(na) = (/ 1, -1, 2, -2, 3, -3, 4, -4, 5, -5 /) integer :: b1(nb1) = (/ 1, -1, 2, -2, 3 /)
integer :: b2(nb2) = (/ 1, -1, 2, -2, 3, -3, 4 /) integer c1(na), c2(na), nc1, nc2
call fobc(a, na, b1, nb1, c1, nc1) call fobc(a, na, b2, nb2, c2, nc2)
write(*, *) c1(:nc1) 5 -5 write(*, *) c2(:nc2)
end program
subroutine fobc(a, na, b, nb, c, nc) |
|
integer na, nb, a(na), b(nb) |
! Входные формальные параметры |
integer c(na), nc |
! Выходные формальные параметры |
integer i, j, va |
|
nc = 0 |
! Число элементов в формируемом массиве |
loop_a: do i = 1, na |
! Имя DO-конструкции использует |
va = a(i) |
! оператор CYCLE loop_a |
do j = 1, nb |
|
if( va == b(j) ) cycle loop_a |
|
end do |
|
nc = nc + 1 |
|
c(nc) = va |
|
end do loop_a |
|
end subroutine fobc |
|
В операторе CALL fobc присутствуют фактические параметры. Тогда как присутствующие в операторе SUBROUTINE fobc параметры a, na, bc
и m являются формальными.
8.11.1. Соответствие фактических и формальных параметров
При вызове процедуры между фактическими и формальными параметрами устанавливается соответствие (формальные параметры ассоциируются с соответствующими фактическими). Так, в нашем примере при первом вызове подпрограммы fobc фактическому параметру a
236
8. Программные единицы
соответствует формальный параметр a, фактическому параметру b1 - формальный параметр b и т. д. Типы соответствующих параметров совпадают. Как видно из примера, имена соответствующих фактических и формальных параметров могут различаться.
В нашем примере скорее всего фактический и соответствующий ему формальный параметр будут адресовать одну и ту же область памяти. Правда, это справедливо не во всех случаях. Так, если фактическим параметром является сечение массива, то при вызове процедуры компилятор создаст его копию, которую и будет адресовать формальный параметр. При выходе из процедуры (если параметр имеет вид связи OUT или INOUT) произойдет обратная передача данных из копии в сечениепараметр.
Фактическими параметрами могут быть выражения, в том числе буквальные и именованные константы, простые переменные, массивы и их сечения, элементы массивов, записи, элементы записей, строки и подстроки, а также процедуры и встроенные функции; в случае подпрограммы именем фактического параметра может быть и метка.
Формальными параметрами могут быть переменные (полные объекты), процедуры и звездочка (*).
Фактические и формальные параметры могут иметь атрибуты, например
POINTER или TARGET.
Устанавливая соответствие между фактическими и формальными параметрами, следует придерживаться приведенных в табл. 8.2 правил.
Таблица 8.2. Фактические и формальные параметры
|
Фактический параметр |
Формальный параметр |
|
|
|
|
Скалярное выражение |
Скалярная переменная |
|
|
|
|
Нескалярное выражение (массив, сечение массива...) |
Массив |
|
|
|
|
Процедура |
Процедура |
|
|
|
|
*Метка (только для подпрограмм) |
* (звездочка) |
|
|
|
|
|
|
Замечания:
1.Если формальный параметр является ссылкой, то и соответствующий фактический параметр тоже должен быть ссылкой.
2.Если фактическим параметром является строка, то формальным параметром может быть строка, перенимающая длину (разд. 3.8.2).
3.Если фактическим параметром является элемент массива, то соответствующим формальным параметром может быть массив (разд. 4.9.1).
237
О. В. Бартеньев. Современный ФОРТРАН
4.Если фактическим параметром является массив, то формальным параметром может быть массив заданной формы, или перенимающий форму массив, или перенимающий размер массив (разд. 4.9).
5.Если фактический параметр является внешней процедурой, то он должен иметь атрибут EXTERNAL. Если же фактический параметр является встроенной процедурой, то он должен быть объявлен с атрибутом INTRINSIC.
8.11.2. Вид связи параметра
Формальные параметры разделяются на входные, выходные и входные/выходные. Входной формальный параметр получает свое значение от соответствующего фактического параметра. Выходной - передает свое значение соответствующему фактическому параметру. Входные/выходные - осуществляют связь в двух направлениях.
В подпрограмме fobc (разд. 8.11) формальные параметры a, na, b и nb являются входными. Параметры c и nc – выходными, т. е. их значения определяются в процедуре и потом уже используются в вызывающей программной единице. Такое разделение формальных параметров примера на входные/выходные мы выполнили, исходя из совершаемых программой действий. На самом деле вид связи формального параметра можно задать явно, использовав атрибут INTENT, например:
subroutine fobc(a, na, b, nb, c, nc) integer, intent(in) na, nb, a(na), b(nb) integer, intent(out) c(na), nc
integer i, j, va
Для задания атрибута INTENT может быть применен оператор INTENT:
subroutine fobc(a, na, b, nb, c, nc)
integer na, nb, nc, a(na), b(nb), c(na), i, j, va intent(in) na, nb, a, b
intent(out) c, nc
Синтаксис оператора INTENT: INTENT (spec) [::] vname
Синтаксис атрибута INTENT: type-spec, INTENT (spec) [, attrs] :: vname
spec - вид связи формального параметра, spec может принимать одно из трех значений:
•IN - формальный параметр является входным и не может быть изменен или стать неопределенным в процедуре. Ассоциированный с ним фактический параметр может быть выражением, например константой или переменной;
238
8. Программные единицы
•OUT - формальный параметр является выходным. При входе в процедуру такой формальный параметр всегда не определен и поэтому должен получить значение до его использования. Ассоциированный с ним фактический параметр должен быть определяемым, например переменной, подстрокой или элементом записи;
•INOUT - формальный параметр может как получать данные от фактического параметра, так и передавать данные в вызывающую программную единицу. Как и в случае вида связи OUT, ассоциированный с ним фактический параметр должен быть определяемым (не должен быть, например, константой).
vname - разделенные запятыми имена формальных параметров. type-spec - спецификация любого типа данных.
attrs - список иных атрибутов формального параметра.
Если атрибут INTENT не задан, то способ использования формального параметра определяет ассоциированный с ним фактический параметр. Так, формальный параметр не должен переопределяться в процедуре, если ассоциированный с ним фактический параметр выражение или константа.
real :: length, x = 3.0, y = 4.0, r |
|
r = length(3.0, 4.0) |
! Этот вызов ошибочен |
r = length(x, y) |
! Этот вызов допустим |
end |
|
real function length(x, y) |
! Первый вызов ошибочен, поскольку |
real x, y |
! формальные параметры x и y |
call square(x, y) |
! переопределяются в подпрограмме square |
length = sqrt(x + y) |
|
end function |
|
subroutine square(x1, y1) |
|
real, intent(inout) :: x1, y1 |
|
x1 = x1 * x1 |
|
y1 = y1 * y1 |
|
end subroutine |
|
Если формальный параметр имеет вид связи IN, то он не должен быть использован в качестве фактического параметра, ассоциируемого с формальным параметром, вид связи которого OUT или INOUT. Так, в предыдущем примере формальные параметры x, y функции length не должны иметь вид связи IN.
Если функция задает перегружаемую операцию, то формальные параметры обязаны иметь вид связи IN. Если подпрограмма определяет задаваемое присваивание, то первый ее формальный параметр должен иметь вид связи OUT или INOUT, а второй - IN.
Недопустимо использование атрибута INTENT:
• для формальных параметров с атрибутом POINTER;
239