- •Предисловие
- •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. Управление операциями с плавающей точкой
- •Литература
- •Предметный указатель
- •Оглавление
1. Элементы языка
1.2.4. Файлы с исходным текстом
В общем случае файлы с исходным текстом программы могут иметь расширения F90, F и FOR. Например, myp.f90, myp.f, myp.for. В первом случае компилятор считает, что файл написан в свободной форме. В двух последних по умолчанию предполагается, что исходный текст записан в фиксированной форме (прил. 2). Мы же будем использовать для файлов расширение F90 и свободную форму записи исходного текста.
1.3. Операторы
Написанная на Фортране программа - это последовательность операторов языка программирования. Операторы разделяются на выполняемые и операторы, которые не участвуют в вычислениях и называются невыполняемыми.
Выполняемый оператор описывает действия, которые должны быть произведены программой.
Невыполняемые операторы описывают элементы программы, например данные или программные компоненты.
Наиболее часто используется выполняемый оператор присваивания, имеющий вид:
имя переменной = выражение
В результате его выполнения переменной присваивается результат некоторого выражения. Например:
real :: d, a = 1.2 |
! Невыполняемый оператор объявления |
|
! типа данных, в котором переменная a |
|
! получила начальное значение 1.2 |
d = 2.3 |
! Читается: d присвоить 2.3 |
a = a + 4.0 * sin(d) |
! Значение a изменится с 1.2 на 4.182821 |
print *, a |
! Вывод значения переменной a |
end |
! Оператором END завершаем программу |
|
|
Замечание. Оператор |
присваивания будет лучше читаться, если перед |
и после знака оператора = поставить по одному пробелу.
Все используемые в программе объекты данных, например переменные, следует предварительно объявить, т. е. явно указать их тип и при необходимости другие свойства. Для этих целей существуют невыполняемые операторы объявления типа, например:
real x, y |
! Невыполняемый оператор REAL объявляет две переменные |
|
! x и y вещественного типа |
integer k |
! Невыполняемый оператор INTEGER объявляет переменную |
|
! k целого типа, принимающую целые положительные |
9
О. В. Бартеньев. Современный ФОРТРАН
! и отрицательные значение и нуль, например:
k = -55
Невыполняемые операторы объявления типа должны располагаться в программе ранее любого исполняемого оператора.
1.4. Объекты данных
Программа выполняет обработку данных. Данные представлены
впрограмме в виде переменных и констант. Объекты данных (переменные
иконстанты) различаются именами, типами и другими свойствами. Переменная, имя которой присутствует в программе, считается существующей. Существующая переменная может быть определенной и неопределенной. Переменная становится определенной после того, как она получит значение, например в результате присваивания или выполнения ввода. Константы бывают именованными и буквальными (неименованными).
Именованная константа объявляется с атрибутом PARAMETER. Значение именованной константы не может быть изменено в результате вычислений. Поэтому ее имя не может находиться в левой части оператора присваивания или быть элементом списка ввода.
real a, b |
! Объявляем вещественные переменные с именами a и b |
|
! Задание именованной константы n |
integer, parameter :: n = 5 |
|
|
! Все именованные константы имеют атрибут PARAMETER |
a = 4.5 |
! Теперь переменная a определена, ей присвоено |
|
! значение буквальной константы 4.5 |
read *, b |
! После ввода будет определена переменная b |
Замечание. При записи не имеющей десятичных знаков вещественной константы следует использовать десятичную точку, например:
real a |
|
a = 4 |
! Так записывать не следует |
a = 4.0 |
! Такая запись подчеркивает тип используемых данных и |
|
! не требует дополнительных преобразований типов данных |
Начальное значение переменной может быть установлено оператором объявления типа или оператором DATA. В случае задания начальных значений (посредством присваивания) или атрибутов оператор объявления типа должен содержать разделитель :: .
real :: a = 1.2, b, c |
! Разделитель :: необходим |
real d / 4.5 / |
! Разделитель :: может быть опущен |
data b, c / 1.5, 4.8 / |
! или: data b / 1.5 /, c / 4.8 / |
В приводимых выше примерах переменные содержат одно значение. Такие переменные называются простыми. Однако можно задать составные
10
1. Элементы языка
переменные, содержащие более одного значения. Примером такой переменной является массив. Используя имя составной переменной, можно обеспечить доступ сразу к нескольким значениям. Например:
real a(5) |
! Объявляем вещественный массив a из пяти элементов |
|
a(1) |
= 1.2 |
! a(1) - имя первого элемента массива a |
a(2) |
= 1.3 |
! Присвоим значение 1.3 второму элементу массива a |
a(3) |
= 1.4; a(4) = -4.2; a(5) = 0.0 |
|
print *, a |
! Вывод всех элементов массива a |
! Следующий вывод эквивалентен PRINT *, a print *, a(1), a(2), a(3), a(4), a(5)
end
Массив не может иметь в качестве элементов другие массивы. Рассмотренный в примере массив является одномерным. Могут быть
заданы и многомерные (с числом измерений не более семи) массивы. Протяженность каждого измерения массива задается нижней и верхней границами, которые разделяются двоеточием. Если нижняя граница равна единице, она может быть опущена. В этом случае опускается и разделяющее двоеточие. Например, каждое из следующих объявлений задает массив из 10 элементов:
real a(-4:5), b(0:9), c(1:10), d(10)
Число измерений массива называется его рангом. Объект данных, ранг которого равен нулю, называется скаляром.
В процессе вычислений значение переменной может быть определено или изменено, например, операторами ввода или присваивания. Есть ситуации, в которых значение переменной может стать неопределенным. Такой объект данных, как массив, считается неопределенным, если не определен хотя бы один из его элементов.
Для определения массива или его изменения можно использовать конструктор массива. Он может быть применен и в операторах объявления типа, и среди исполняемых операторов, например:
real :: a(5) = (/ 1.1, -2.1, 3.1, -4.5, 5.0 /) real b(5)
b = (/ 1.1, -2.01, 3.1, 4.05, 50.0 /)
Объекты данных различаются типом. Возможные типы данных: целый, вещественный, комплексный, логический, символьный и производный тип - структуры. Элементами массива могут быть объекты одного типа.
Примеры объявления объектов данных разных типов:
real :: c = 4.56, b(20)
complex :: z = (1.4142, 1.4142)
!c и b - вещественные переменные
!z - переменная комплексного типа
11
О. В. Бартеньев. Современный ФОРТРАН
character(30) :: fn = 'c:\dig.bin' |
! fn - символьная переменная |
real, parameter :: pi = 3.141593 |
! pi - вещественная константа |
В программе составной объект может быть использован целиком, можно также использовать и часть составного объекта, которая называется подобъектом. Так, в случае массива его подобъектом является отдельный элемент массива, а также и любая часть массива, которая называется
сечением массива. Например:
real a(5) |
! Объявляем вещественный массив a из пяти элементов |
a = 1.2 |
! Присвоим значение 1.2 всем элементам массива a |
a(2) = -4.0 |
! Присвоим значение -4.0 второму элементу массива |
print *, a(1:3) |
! Вывод сечения массива a - первых трех его элементов |
print *, a(1), a(2), a(3) |
! Этот вывод эквивалентен предыдущему |
1.5. Имена
Переменные, константы, программные компоненты имеют имена. Имя - это последовательность латинских букв, цифр, символа $ или подчеркивания, начинающаяся с буквы или символа $. Имя не должно содержать более 31 символа. Регистр букв не является значащим. Так, имена st, St, sT, ST есть одно и то же. Следует придумывать имена, отображающие смысл применяемых переменных, констант и других объектов программы.
Примеры имен: Cat1F_Name $var stlen
Имена разделяются на глобальные, например имя главной программы или встроенной процедуры, и локальные, например имя переменной или константы.
Разрешается создавать локальные имена, совпадающие с глобальными именами встроенных процедур. Но если в программной единице имя, например sum, использовано для имени локальной переменной, встроенная функция SUM в этой программной единице будет недоступна. Поэтому для создаваемых объектов следует придумывать имена, которые отличаются от имен встроенных процедур. Не стоит также давать создаваемым объектам имена, совпадающие с именами операторов идругих объектов Фортрана.
Замечание. Широко используется при формировании имен так называемая Венгерская нотация. В соответствии с ней имя объекта снабжается префиксом из строчных букв, указывающих его тип (если объект обладает типом). Последующая часть имени раскрывает его смысл. Причем каждая часть имени, отражающая отдельный смысловой компонент, начинается с прописной буквы. Например, имя iVectorSize может быть дано именованной константе, хранящей размер вектора, а имя SetInitValues может иметь подпрограмма, выполняющая инициализацию переменных. В
12