
- •Управление векторами и матрицами
- •Компиляция и выполнение Компиляция
- •Связывание (редактирование связей )
- •Выполнение
- •Примеры
- •Соглашения о записи кода
- •Арифметические выражения
- •Операции отношения
- •Логические выражения
- •Сравнение символов
- •Переносимость результата
- •Спецификация массивов
- •Сечения массива Индивидуальные элементы
- •Сечения
- •Векторные указатели
- •Память для массива Физическая память:
- •Присваивание массива Присваивание всего массива
- •Присваивание секции (вырезки) массива
- •Повторная нумерация
- •Основные встроенные процедуры
- •Массивы нулевого размера
- •Массивы и производные типы
- •Инициализация массивов Конструкторы
- •Оператор data
- •Встроенные функции для массива
- •Пример упрощения
- •Пример исследования (запроса)
- •Пример конструирования
- •Пример локализации
- •Я Операторы управления
- •Вложения
- •Порядок операторов
- •Синтаксис программы Main
- •Формат представления программы
- •Программные единицы
- •Уровни доступа
- •Дополнения
- •Спецификация входных-выходных параметров
- •Использование модуля
- •Родовые подпрограммы
- •Интерактивный ввод-вывод
- •Простой Input и Output
- •Форматирование по умолчанию
- •Форматированный ввод-вывод I/o
- •Дескрипторы редактора
- •Вещественные - форма с фиксированной точкой
- •Вещественные - экспотенциальная форма
- •Символьные
- •Логические
- •Заполнение пробелами (пропуск символьных позиций)
- •Специальные символы
- •Списки ввода-вывода
- •Производные типы данных
- •Неявный цикл do
- •Ввод-вывод без продвижения
- •Файловый ввод-вывод
- •Номера устройств
- •Операторы read и write
- •Оператор write
- •Оператор open
- •Оператор close
- •Оператор inquirе
- •Динамический массив
- •Распределяемые массивы
- •Спецификация
- •Выделение и возвращение памяти
- •Статус распределяемых массивов
- •Потоки памяти (куча)
- •Что есть указатели?
- •Указатели и адресаты
- •Спецификации указателя Общая форма для операторов определения указателя и адресата такая:
- •Присваивание указателя
- •Разыменование (Dereferencing)
- •Статус (состояние) связи указателя
- •Динамическая память
- •Общие ошибки
- •Указатели в производных типах данных
- •Связанные списки
- •Параметры - указатели
- •Функции для указателей
Соглашения о записи кода
В этих заметках все примеры кода написаны в стиле 'typewriter' , то есть
PROGRAM hi
! вывод сообщения
WRITE(*,*) 'Hello World!'
END PROGRAM hi
Соглашения о записи кода состоят в том, что
Все ключевые слова и имена встроенных процедур (эти команды и функции есть часть стандарта) набираются на верхнем регистре, все остальное на нижнем
Чтобы помочь чтению кода тела модуля программы, с отступом печатаются блоки INTERFACE, блоки DO , блоки IF , блоки CASE и т.д.
Имя программы, подпрограммы или функции включается в оператор конца END
В операторе USE фраза ONLY использована для явного документирования всех объектов, которые доступны из этого модуля
В операторе CALL и вызове функции ключевое слово аргумента всегда используется для необязательных аргументов.
Объекты данных
Говоря об объектах данных, будем иметь ввиду
•Встроенные типы
•Литеральные константы
•Неявноые типы
•Опреления численных и логических
•Определение символьных
•Константы (Параметры)
•Инициализация
Переменные
В разделе объясняется смысл понятия "переменная" и правила задания идентификаторов: составляются из букв, цифр, возможно подчеркивание, большие и малые буквы считаются эквивалентными.
Переменные величины хранятся в памяти, идентификатор дает название тому месту в памяти, где значения хранятся, с переменной соотносится значение (число, текст, другие значения), способ представления значений в памяти и размер памяти, требуемый для размещения значения, зависит от типа переменной, тип определяется специальным оператором или по умолчанию (см. далее).
В примерах текстов будут использоваться большие буквы для зарезервированных слов и идентификаторов, малые - для объектов пользователя.
В качестве примера можно привести следующие значения переменных
7
96.4
3.14159
с именами переменных:
daysinweek
temperature
pi
Тип переменных задается спецификацией типа. Имеется несколько форм численных данных, а именно:
Целые
Могут иметь только дискретные значения (такие как. -3124, -960, 10, 365, и т.п..)
Вещественные
Могут иметь дробную часть (такие как 10.3, -8.45, 0.00002, и т.п..) и обычно имеют больший диапазон возможных значений, чем целые
Комплексные числа
Имеют вещественную и мнимую части (например, 3-2i, -5+4i, и т.п.).
Целые более точны для дискетных значений и быстрее обрабатываются, но вещественные нужнее для многих вычислений. Комплексные нужны для некоторых научных приложений.
Иногда программы на фортране требуют и других типов данных. Отдельные буквы, слова и фразы могут быть представлены символьным типом, тогда как логические значения `true' и `false' представляются логическим типом.
Наконец, необходима возможность явно указывать значения величин, которые называют литеральными константами, например 3.14159.
Соглашения об именах
В программах на Фортране имена переменных должны соответствовать соглашению об именовании. Это соглашение разрешает длину имени от 1 до 31 алфавитно-цифровых символа - сформированных из 26 доступных букв: a...z; и 10 цифр 0...9; и символа подчеркивания _ - при этом первым символом должна быть буква.
Заметим, что бльшие и малые буквы считаются неразличимыми и считаются эквивалентными. Таким образом имена name, Name, NaMe и NAME все ссылаются на один и тот же объект.
В отличие от некоторых языков программирования, в которых определенные слова зарезервированы и могут использоваться программистом только в определенном смысле и контексте, Fortran не имеет таких ограничений. Тем не менее программист должен следить, когда при именовании переменных делается попытка использовать любые слова, входящие в язык.
Правильные имена переменных:
x, x1, mass, cost, day_of_the_week
Правильные имена переменных (но не используйте!):
real, integer, do, subroutine, program
Неправильные имена переменных :
ten.green.bottles, 1x, a thing, two-times, _time
Спецификации или объявления
Все переменные, использованные в программе, должны иметь ассоциированные с ними типы данных, такие как REAL, INTEGER или COMPLEX, которые обычно идентифицированы в начале прогаммы. Они называются объявлениями или спецификациями переменных, например:
REAL :: temperature, pressure
INTEGER :: count, hours, minutes
Объявляет 5 переменных, две их которых имеют значения, являющиеся вещественными числами, и три имеют целые значения.
Оператор объявления переменных может быть использован для присваивания начальных значений объявленным переменным. Если начальное значение не задано переменной, она не может быть принимать никаких значений до тех пор, пока не будет присвоено с помощью оператора присваивания.
REAL :: temperature=96.4
INTEGER :: days=365, months=12, weeks=52
В общей форме объявление переменной:
тип [,атрибуты...] :: список переменных
где тип один из встроенных типов данных:
INTEGER
REAL
COMPLEX
CHARACTER
LOGICAL
А атрибут ... необязательный список "ключевых слов", каждое отделяется запятой, ключевые слова используются для определения свойств переменных:
ALLOCATABLE INTENT(...) PARAMETER PUBLIC
DIMENSION(...) INTRINSIC POINTER SAVE
EXTERNAL OPTIONAL PRIVATE TARGET
CHARACTER и LOGICAL типы данных, обсуждаемые в отдельном разделе. Атрибуты введены как требуемые к ним заметки.
Параметры (Parameters)
Термин параметр в Фортране вводит в некоторое заблуждение. Он относится к значению, которое будет заменено во время выполнения программы. Например, программист может хотеть значение pi сделать неизменяемым программой. Тогда pi может объявлено:
REAL, PARAMETER :: pi=3.141592
REAL специфицирует тип данного; атрибут PARAMETER в дальнейшем определяет переменную pi. Всем параметрам должны быть даны значения в операторе их объявления (в нашем случае 3.141592). Параметры могут быть определены для других типов данных, например:
INTEGER, PARAMETER :: maxvalue=1024
INTEGER, PARAMETER :: repeatcount=1000
Считается ошибкой попытка переопределения значения параметра в ходе выполнения программы.
Неявные объявления
Фортран 90 разрешает тип переменных real и integer объявлять неявно без соответсвующего оператора объявления. Это свойство неявного объявления обеспечивает преемственность с более ранними определениями языка Фортран, но может создавать проблему программирования при неосторожности. Можно отключить это свойство с помощью оператора:
IMPLICIT NONE
В начале каждой программы. Это заставит программиста объявлять все переменные, которые использованы в программе, чтобы не приводить к ошибкам во время компиляции.
Явное объявление типов позволяет вместе с определениями типов задавать начальные значения. При неявном описании начальная буква имени определяет тип целый для имен, начинающихся на буквы I, J, K, L, M и N ; и тип вещественный для имен, начинающихся на буквы от A до H и от O до Z.
KIND
Каждый тип данных имеет одно или более значений параметра типа KIND, связанного с ним. Типы данных с различными значениями KIND используют различное число байтов для запоминания информации. Это означает, что числовые типы данных с различными параметрами типом KIND имеют различный диапазон допустимых значений и/или различного уровня числовой точности.
Например, компилятор NAG F90 использован для развития этого курса, обеспечившего три значения параметра типа KIND для типа INTEGER (KIND=1, 2 или 3); 3 являлось по умолчанию. Другие компиляторы или компилятор NAG F90 в различных системах могут поддерживать различные значения KIND. Переменные объявлены с желаемой точностью с помощью использования атрибута KIND:
тип (KIND = kind_type_value) [, атрибуты...] :: список переменных
Например:
INTEGER :: a ! по умолчанию KIND=3
INTEGER(KIND=3) :: b ! по умолчанию
INTEGER(KIND=1) :: c ! ограниченная точность -127 <= c <= 127
INTEGER(2) :: d ! KIND= необязательное
INTEGER :: e=1_2 ! e=1 и тип kind 2
Оба типа данных INTEGER, и LOGICAL имеют некоторые возможные значения типа KIND, каждый из которых использует меньше памяти, чем по умолчанию (которая в случае типа INTEGER приводит к меньшему диапазону возможных значений - так что остерегайтесь!). Эти альтернативные значения KIND обычно использованы только, когда память данных выше номинала.Для типа CHARACTER обычне имеется одно значение KIND .
Типы REAL (и COMPLEX) имеют два значения KIND. По умолчанию (KIND=1) дается более низкий уровень точности, чем (KIND=2). (Аналогично этим значениям KIND в Fortran 77 имеется одиночная и двойная точности переменных.) Обычно можно использовать REAL с KIND=2, чтобы хранить более высокую точность и/или когда предполагается большой диапазон значений , как показано ниже:
REAL :: a ! по умолчанию KIND=1
REAL(KIND=2) :: b, c ! большой диапазон и / или точность
COMPLEX(KIND=2) :: d ! большой диапазон и / или точность
Точный уровень точности значений может быть проверен с помощью встроенных функций. Встроенные функции RANGE(), HUGE(), PRECISION(), и др. Все дают информацию о пределах (ограничениях) KIND для переменных различных типов. Ниже примеры из компилятора NAG F90:
INTEGER :: a ! по умолчанию KIND=3
INTEGER(KIND=2) :: b
REAL :: c ! по умолчанию KIND=1
REAL(KIND=2) :: d ! большой диапазон и / или точность
HUGE( b ) ! наибольшее число = 32767
HUGE( c ) ! наибольшее число = 3.4028235E+38
HUGE( d ) ! наибольшее число = 1.7976931348623157*10**308
RANGE( a ) ! наибольшая степень = 9
RANGE( d ) ! наибольшая степень = 307
PRECISION( c ) ! точность (в цифрах) = 6
PRECISION( d ) ! точность (в цифрах) = 15
Переносимость
Количество и значение параметров всех KIND зависит от используемого компилятора. Вы поймете, что явно используя значение (такое как в (KIND=3) ), программа может не работать (или давать неожиданно ошибки), когда используются разные компиляторы. Например, некоторые компиляторы используют KIND=1,2 и 3 для типа INTEGER , тог как другие используют KIND=1,2 и 4.
Один способ редактирования программы для различных значений KIND это использование встроенных функций SELECTED_REAL_KIND() и SELECTED_INTEGER_KIND(). Для целых, SELECTED_INTEGER_KIND() делает управляемым сохранение данных с максимальной степенью данные (то есть 10r, где r есть диапазон) и функция возвращает параметр , ассоциированный с типом KIND. Для вещественных, SELECTED_REAL_KIND() делает выбираемым оба диапазона и десятичную точность и снова возвращает значение , ассоциированное с KIND .
INTEGER, PARAMETER :: k2 = SELECTED_REAL_KIND(10,200)
REAL(KIND=k) :: a ! диапазон=+/-10**200, 10 десятичных позиций
INTEGER, PARAMETER :: k5 = SELECTED_INTEGER_KIND(5)
INTEGER(KIND=k5) :: b ! диапазон=+/-10**5
Если компилятор не может поддержать запрашиваемый диапазон и/или уровень точности, функция SELECTED_type_KIND() возвращает отрицательное значение программа не будет компилироваться.
Преобразование типа
Когда присваивается одна переменная другой (или переменные одного типа, но с разными видами KIND ), нужно обеспечить, чтобы данные остались совместимыми. Когда присваиваемые данные различных типов (наприме, присваиваются вещественные целым) или когда присваиваемые данные различных типов kind (например, 4-байтное INTEGER присваивается однобайтовому INTEGER), где информация теряет смысл. Существует ряд встроенных функций, которые регулируют преобразование данных в достоверном и совместимом виде. Например,
REAL :: total=13.0, num=5.0
INTEGER :: share
share = total/num ! total/num=2.6, share=2
share = INT( total/num ) ! total/num=2.6, share=2
Результат total/num это вещественное число, поэтому он в примере REAL нужно присвоить целому INTEGER. Заметим, что значение, присвоенное величине share, будет усечено (nне округлено к ближайшему!). Встроенная функция INT() конвертирует ее аргумент (то есть результат для total/num) в целое, и может быть присвоена текущему, как только численные нецелые присвоены переменной типа INTEGER.
Другие типы данных имеют функции преобразования простого типа; REAL() преобразует ее аргумент к типу REAL и CMPLX()преобразует ее аргумент к типу COMPLEX (часто усекая мнимую часть). Возможно преобразовать данные CHARACTER в INTEGER (и наоборот) используя встроенные функции IACHAR() и ACHAR().
Чтобы разрешить преобразование различных типов KIND, каждая из функций преобразования должна быть снабжена значениями типа KIND , которые могут быть типами для конвертируемыми данными. Например:
INTEGER, PARAMETER :: k2=SELECTED_INT_KIND(2)
INTEGER :: long ! по умолчанию kind=3
INTEGER(KIND=K2) :: short
REAL(KIND=2) :: large
long = 99
short = INT( long, KIND=k2 ) ! конвертирует 99 в INTEGER(KIND=k2)
large = REAL( short, KIND=2 ) ! конвертирует 99 в REAL(KIND=2)
Остерегайтесь! Когда преобразуются данные из одного типа в другой, переменная, принимающая данные, должна быть способна хранить значение (диапазон и точность). Если не обеспечена, возникает ошибка:
INTEGER(KIND=1) :: short ! -127 <= short <= 127
INTEGER :: long=130 ! -32767 <= long <= 32767
short = long ! ошибка
short = INT( long, KIND=1 ) ! еще ошибка