Автоматические
массивы
В процедуре
может быть
задан локальный
массив, размеры
которого могут
меняться при
разных вызовах
процедуры.
Такие
массивы, так
же как и локальные
строки переменной
длины (разд.
10.4), относятся
к автоматическим
объектам.
Рекурсивные
процедуры
Фортран
поддерживает
рекурсивные
вызовы внешних,
модульных и
внутренних
процедур.
Процедура
называется
рекурсивной,
если
она обращается
сама к себе или
вызывает другую
процедуру,
которая, в свою
очередь,
вызывает
первую процедуру.
В первом случае
рекурсия называется
прямой,
во
втором - косвенной.
Оператор
объявления
рекурсивной
процедуры
должен предваряться
префиксом
RECURSIVE.
Внутри рекурсивной
процедуры
интерфейс к
этой процедуре
является явным
(см. разд. 16.4.3).
Пример.
Разработать
подпрограмму
subst,
которая
в данной строке
заменяет все
вхождения
подстроки sub1
на
подстроку sub2.
Так,
если дана строка
'abc1abc2abc3'
и sub1
= 'abc',
a
sub2
=
' d',
то результатом
должна быть
строка ' dl
d2
d3'.
program stgo
character(len
= 20) :: st =
'abc1abc2abc3'
call
subst(st, 'abc', d')
! subst содержит
прямую
write(*,
*) st
!
рекурсию
d1 d2 d3
end
recursive
subroutine subst(st,
subl, sub2)
character(len
= *) st, sub1, sub2
! Длина
каждой строки
определяется integer
ip !
длиной соответствующего ip
= index(st,
sub1)
! фактического
параметра if(ip
> 0) then
st = st(:ip - 1) // sub2 // st(ip
+ len(subl):)
call
subst(st, subl, sub2) ! Рекурсивный
вызов подпрограммы endif
! выполняется
до тех пор, пока
end !
не выполнены
все замены subl
на sub2
Если
функция содержит
прямую рекурсии,
то есть непосредственно
вызывает сама
себя, результату
необходимо
дать имя,
отличное
от имени Функции.
Это выполняется
путем добавления
в заголовок
функции предложения
RESULT.
В случае
косвенной
рекурсии имя
результирующей
пе-Ременнрд
и имя функции
могут совпадать.
Символьные
типы данных
Символьный
тип данных
позволяет
задать объект,
состоящий из
последовательности
символов.
Такую
последовательность
мы будем строкой.
Символьный
тип данных
могут иметь
объекты: переменные,
константы
и функции. Символьный
тип является
встроенным
типом данных
для него существует
одна
встроенная
операция - операция
конкатенации
(обозначается
двумя слешами
//), позволяющая
выполнять
объединение
отдельных строк
или подстрок
символов. Объявление
символьных.данных
выполняется
оператором
CHARACTER,
например:
character
:: ch = 'а' !
Символьная
переменная
длиной в 1 символ
character(len
= 20) st ! Символьная
переменная
из 20 символов
st
= 'Example' !
Присвоим значение
символьной
переменной
st
== st // '_' // ch ! Возвращает:
Example_a
Оператор
CHARACTER
содержит в
скобках данные
о длине символьного
объекта. Если
длина не задана,
то по
умолчанию она
принимается
равной единице.
DO-Циклы.
Операторы EXIT
и CYCLE
Простейшая
конструкция
DO
[имя:]
DO
БОК
END
DO (имя]
задает
бесконечный
цикл. Поэтому
такой цикл
должен содержать
по крайней
мере
один
оператор, например
EXIT
[имя],
обеспечивающий
выход из этого
цикла.
Имя
конструкции,
если оно присутствует,
должно появляться
в
операторах
DO
и END
DO.
Рекомендуемая
форма DO-цикла
с параметром:
[имя:]
DO dovar = start, stop [, inc]
БОК
END
DO [имя]
dovar
- целая
переменная,
называемая
переменной
цикла или параметром
цикла;
start,
stop
- целые
скалярные
выражения,
задающие диапазон
изменения
dovar;
inc
- целое
скалярное
выражение,
задающее лаг
изменения
dovar.
Значение
inc
не
может
быть
равным нулю.
Если параметр
inc
отсутствует,
то он принимается
равным единице.
Рекомендуемая
форма DO
WHILE-цикла:
[имя]
DO
WHILE(ЛB)?
БОК
END
DO [имя]
Если
DO
WHILE-цикл
не содержит
операторов
прерывания
цикла,
БОК
выполняется
до тех пор, пока
истинно скалярное
ЛВ.
DO-цикл,
DO-цикл
с параметром
и DO
WHILE-цикл
могут быть
рваны
операторами
GOTO,
EXIT
и CYCLE,
а также в результате
выполнения
оператора
RETURN,
обеспечивающего
возврат из
подпрограммы.
Оператор
EXIT
[имя}
передает
управление
из DO-конструкции
на первый следующий
за kohi
рукцией
выполняемый
оператор. Если
имя
опущено,
то EXIT
обеспечив;
выход из текущего
цикла,
в
противном
случае EXIT
обеспечивает
выход цикла,
имя
которого
присутствует
в операторе
EXIT.
Оператор
CYCLE
[имя]
передает
управление
на начало
DO-конструкции.
При этом оператор
расположенные
между
CYCLE
и оператором
END
DO
конца цикла,
не выполняются.
Если имя
опущено,
то CYCLE
обеспечивает
переход на
начало текущего
цикла, в противном
случае CYCLE
обеспечивает
переход
на начало
цикла, имя
которого
присутствует
в операторе
CYCLE.
Условный
логический
оператор IF
IF(ЛВ)
оператор
Если
истинно ЛВ, то
выполняется
оператор,
в
противном
случае управление
передается
на
последующий
оператор программы.
Конструкция
IF THEN ENDIF
[имя-.]IF(ЛВ)
THEN
БОК
END
IF [имя]
БОК
выполняется,
если истинно
ЛВ. Если присутствует
имя конструкции,
то оно должно
быть
и в первом и в
последнем
операторе
конструкции,
например:
swap:
if(x < у)
then
hold
= х; х = у; у = hold
end if swap
Замечание.
Если
БОК содержит
один оператор,
то лучше использовать
оператор
IF(ЛВ)
оператор
Конструкция
IF THEN ELSE ENDIF
[имя:]
IF(ЛВ)
THEN
БОК1
ELSE
[имя]
БОК1
END
IF [имя]
В
случае истинности
ЛВ выполняется
БОК1 и выполняется
БОК2, если ЛВ
ложно.
Имя
конструкции,
если оно задано,
должно обязательно
присутствовать
и перед IF,
и
после
END IF.
Конструкция
IF THEN ELSE IF
[имя:]
IF(ЛВ)
THEN
БОК1
ELSE
IF(ЛВ2)
THEN [имя]
БОК2
…
[ELSE
[имя]
БОКn
END
IF [имя]
В случае
истинности
ЛВ1 выполняется
БОК1 и управление
передается
на
следующий
за END
IF
оператор. Если
ЛВ1 ложно, то
управление
передается
на следующий
ELSE
IF,
то есть вычисляется
значение
ЛВ2
и, если оно
истинно, то
выполняется
БОК2. Если оно
ложно, то
управление
передается
на следующий
ELSE
IF,
и так далее.
Если ложны все
ЛВ,
то выполняется
следующий за
завершающим
ELSE
БОКп.
Если
завершающий
ELSE
отсутствует,
то управление
передается
на расположенный
за
END
IF
оператор.
Число операторов
ELSE
IF
в конструкции
может быть
произвольным.
Имя
в ELSE
и в ELSE
IF
можно задавать,
если это имя
имеют
операторы
IF
и END
IF.
Имя, если оно
задано, во всех
частях
конструкции
должно быть
одинаковым.
Конструкция
SELECT CASE
[имя:]
SELECT CASE (тест-выражение)
CASE(CП1)
[имя]
[БОК1]
[CASE(CП2)
[имя]
[БОК2]]
…
[CASE
DEFAULT [имя]
[БОКп]]
END
SELECT
[имя]
Тест-выражение
- целочисленное,
символьное
типа CHARACTER(l)
Или
логическое
скалярное
выражение.
СП
- список констант,
тип которых
должен соответствовать
типу тест-выражения.
Конструкция
SELECT
CASE-работает
так: вычисляется
значение
тест-выражения.
Если
полученное
значение находится
в списке СП1,
то выполняется
БОК1; далее
управление
передается
на следующий
за END
SELECT
оператор. Если
значение в СП1
не находится,
то
проверяется,
есть ли оно в
СП2,
и так далее.
Если значение
тест-выражения
не найдено
ни
в одном списке
и присутствует
оператор CASE
DEFAULT,
то выполняется
БОКп, а далее
выполняется
расположенный
за END
SELECT
оператор. Если
же значение
тест-выражения
не
найдено ни в
одном списке
и CASE
DEFAULT
отсутствует,
то ни один из
БОКл не выполняется
и
управление
передается
на следующий
за END
SELECT
оператор.
Список
констант СП
может содержать
одно значение,
или состоять
из разделенных
запятыми
констант, или
быть задан как
диапазон разделенных
двоеточием
значений,
например
5:10 или T:'N'.
Левая граница
должна был
меньше
правой. Если
задается
диапазон
символов, то
код первого
символе
должен
быть меньше
кода второго.
Если
опущена
левая граница,
например :10,
то в СП содержатся
все значения,
меньшие
или
равные правой
границе.
И наоборот,
если опущена
верхняя граница,
например 5:,
то
в СП попадают
все значения,
большие или
равные нижней
границе. СП
можеч
включать
также и смесь
отдельных
значений и
диапазонов.
Разделителям!
между
отдельны
ми элементами
СП являются
запятые, например:
case(1,
5, 10:15, 33)
Нельзя
задать в СП
диапазон значений,
когда тест-выражение
имеег
логический
тип.
Каждое
значение, даже
если оно задано
в диапазоне
зна чений,
может появляться
только в одном
СП.
1.информация.
Количество
информации.
Представление
информации
в ЭВМ.
2.Решение
задач с использованием
ЭВМ. Понятие
об устройстве
ЭВМ.Организация
вычислительного
процесса б
ЭВМ.
3.Алгоритм.
Свойства алгоритма.
Способы представления
алгоритма.
Типы алгоритмов.
4.Порядок
подготовки
программы,
исходный текст,
трансляция
и интерпретация,
редактирование
связей. Язык
программирования
Фортран
5.Фортран.Злементы
языка. Алфавит,
лексемы, имена,
выражения и
операции, операторы.
8.Фортран.Встроенные
типы данных.
Объявление
данных. Правило
умолчания о
типах данных.
7.Фортран.
Встроенные
операции. Оператор
присваивания.
8.Конструкция
DO.
Разновидности
конструкции
DO.
Операторы
CYCLE,
EXIT.
9.Оператор
IF, конструкция
IF THEN ENDIF.
10.Конструкция
IF THEN ELSE ENDIF,
11.Инструкция
IF THEN ELSE IF.
12.Конструкция
SELECT CASE.
13.Программные
компоненты
и процедуры.
Главная программа.
14.Программные
компоненты
и процедуры.
Подпрограммы.
15.Программные
компоненты
и процедуры.
Функции.
16.Программные
компоненты
и процедуры.
Модули.
17.Обращение
к сопрограммам.
Параметры
процедур. Виды
связи
параметра.
Атрибут INTENT.
13.Явный
и неявный интерфейс.
Оператор INTERFACE.
19.Области
видимости имен
и меток.
20.Производные
типы данных.
Оператор TYPE.
21.Массивы
фиксированного
размера. Описание,
присвоение
значений. Выражения
с массивами.
Сечения массивов,
массивов.
22.Символьные
данные, символьные
вырашия. Текстовые
подстроки.
23.Оператор и
конструкция
WHERE.
24.Динамические
массивы. Размещаемые
массивы.
25.Динамические
массивы. Автоматические
массивы.
26.Массивы
- формальные
параметры
процедур. Массивы
заданной формы.
27.Массивы
- формальные
параметры
процедур. Массивы,
перенимаю-дше
форму.
28.Массивы
- формальные
параметры
процедур. Массивы,
перенимающие
размер.
29.Ассоциирование
памяти. Оператор
COuuO".
30.Ассоциирование
памяти. Оператор
EQUIVALENCE.
31.Рекурсия.
Рекурсивные
алгоритмы и
определения.
32.Рекурсивные
субпрограмны.
Предложение
RESULT.
Рекурсия "изнутри"
З9.Сортировка.
Постановка
задачи. Сортировка
выбором.
40. Пузырьковая
сортировка.
41. Пирамидальная
сортировка.
42. Быстрая
сортировка.
43. Поиск.
Постановка
задачи. Дихотомический
поиск.
Массив
- это объект
данных, который
содержит конечное
число скалярных
данных
одного типа.
В отличие от
простой переменной
массив обладает
атрибутом
DIMENSION.
Массивы
заданной формы
Границы
размерностей
массивов - формальных
параметров
могут определяться
передаваемыми
в процедуру
значениями
других параметров.
Так, в рассмотренной
в разд. 6.3.1 задаче
пользовательская
функция md
имеет
синтаксис
result
= md(d,n)
где d
- массив
- формальный
параметр заданной
формы; an-
целочисленный
скаляр, используемый
для задания
размера массива
d.
функция вызывается
3 раза:
а
= md(a, na); mb = md(b, nb); me = md(c, nc)
При каждом
вызове фактическим
параметром
является массив
той же формы,
что
и массив - формальный
параметр.
Передаваемые
размерности
пассивов имеют
разные значения.
Однако форма
ассоциируемых
при вызове
процедуры
массивов фактических
и формальных
параметров
может различаться,
что позволяет
в ряде случаев
упростить
написание
программы.
Так это происходит
при создании
подпрограммы
обмена содержимого
двух многомерных
массивов:
integer,
parameter :: n = 5, m = 10, k = m*n
real a(m, n) /k*1.0/, b(m, n) /k*2.0/
call swap(a, b, m, n)
write(*, *) b
end
subroutine
swap(a, b, m, n)
integer
m,
n
real
a(m*n),
b(m*n)
! а и b
– массивы заданной
формы)
real
c(size(a))
! с -
автоматический
массив
с = а
a=
b
end
subroutine
swap
В общем случае
для формального
параметра -
массива могут
вычисляться
как нижняя,
так и верхняя
границы размерности.
Общий вид
размерности
таких массивов:
[нижняя граница]
: [верхняя граница]
Нижняя и
верхняя
границы - целочисленные
описательные
выражения.
Вычисленные
границы массива
фиксируются
на время выполнения
процедуры
и не меняются
при
изменении
значения
соответствующего
описательного
выражения.
При работе с
такими массивами
необходимо
следить, чтобы
размер массива
- формального
параметра
не превосходил
размера ассоциированного
с
ним массива
- фактического
параметра.
Если
фактическим
параметром
является многомерный
массив и соответствующим
ему формальным
параметром
является массив
заданной формы
с тем же числом
измерений, то
для правильного
ассоциирования
необходимо
указать размерности
массива - формального
параметра
такими же,
Как и у массива
- фактического
параметра.
Исключение
может составлять
верхняя
граница последней
размерности
массива, которая
может меньше
соответствующей
границы массива
- фактического
параметра.
Если в качестве
фактического
параметра задан
элемент массива,
т формальный
параметр
ассоциируется
с элементами
массива-родителя
начиная с данного
элемента и
далее по порядку.
Массивы,
перенимающие
форму
Такие массивы
- формальные
параметры
перенимают
форму у соответствующего
фактического
параметра. В
результате
ранг и форма
фактического
и формального
параметров
совпадают. При
описании
формы формального
параметра
каждая размерность
имеет вид: [нижняя
граница] :
где нижняя
граница - это
целое описательное
выражение,
которое може!
зависеть от
данных в процедуре
или других
параметров.
Если нижняя
граница опущена,
то ее значение
по умолчанию
равно единице.
Например»
ПРИ
вызове
real х(0:3,
0:6, 0:8)
interface
subroutine asub(a)
real a(:,
:,
:)
end
end
interface
call
asub(x)
Соответствующий
перенимающий
форму массив
объявляется
так:
subroutine asub(a)
real a(:, :, :)
prnt *,
lbound(a, 3), ubound(a, 3) ! 1
9
Так как
нижняя граница
в описании
массива а
отсутствует,
то после вызова
подпрограммы
в ней будет
определен
массив а(4, 7, 9). Если
нужно сохранить
соответствие
границ, то массив
а следует
объявить так:
real
a(0:,
0:, 0:)
В интерфейсном
блоке по-прежнему
массив а
можно
объявить:
real
а(:, :, :)
Процедуры,
содержащие
в качестве
формальных
параметров
перенимающие
форму массивы,
должны
обладать явно
заданным интерфейсом.
Сортировка
Основное
назначение
сортировки
- обеспечить
быстрый поиск
данных. Помимо
этого, в отсортированном
файле
или массиве
гораздо быстрее
выполнять
многие вычисления.
Сортировка
методом пузырька
Сортировка
методом пузырька
наиболее проста
для реализации,
но имеет по
сравнению
с другими методами
наименьшую
вычислительную
эффективность.
Не теряя общности,
будем для простоты
изложения в
дальнейшем
рассматривать
задачу
сортировки
массива х
целых
чисел, в котором
первые я чисел
должны быть
отсортированы
так, чтобы хi
<= Xj
для 1 <=i <=
j
<= п.
Идея сортировки
методом пузырька
состоит в том,
чтобы просмотреть
массив последовательно
несколько раз.
Один просмотр
состоит из
сравнения
каждого элемента
массива со
следующим
за ним элементом
(xi сравнивается
с xj+1)
и обмена этих
двух элементов,
если они
располагаются
не в нужном
порядке (если
Xi
>xi+1)
Быстрая
сортировка
Рассмотрим
массив х
25
37 12
33 48 57 92
86
В нем число 48
характеризуется
тем, что, во-первых,
все расположенные
левее него
числа меньше
48
и, во-вторых,
числа, расположенные
правее него
больше 48. Назовем
такое число
разделителем
массива
. Нетрудно
понять,
что теперь мы
можем отдельно
решать задачу
сортировки
для чисел до
разделителя
и для чисел
после него.
Кроме того, сам
разделитель
находится
в нужной позиции,
то есть в
дальнейшей
сортировке
он уже не рассматривается.
Размещаемые
массивы
рассмотренный
массив marks
является
статическим
- его размер не
может быть
изменен в процессе
вычислений,
поэтому
мы вынуждены
задать 6го
размер с некоторым
запасом (чтобы
иметь возможность
использовать
массив
для любой
студенческой
группы). Это
приводит к
тому, что программа,
как правило,
занимает больше
памяти,
чем это требуется
на самом деле.
Подобного
перерасхода
памяти можно
избежать, если
применить
динамический
массив и каждый
раз выделять
под него столько
памяти, Сколько
нужно. Работа
с динамическим
массивом происходит
так:
выполняется
объявление
размещаемого
массива. В отличие
от статических
размещаемые
массивы объявляются
с атрибутом
ALLOCATABLE.
Кроме того,
каждое измерение
размещаемого
массива задается
в виде
двоеточия,
например: integer,
allocatable, dimension(:) :: marks
определяется
размер массива;
оператором
ALLOCATE
выделяется
память под
массив;
после выполнения
вычислений
выделенная
память освобождается.
Это
выполняется
оператором
DEALLOCATE;
после этого
массиву вновь
может быть
выделена свежая
область памяти.
При размещении
массива параметр
STAT=
позволяет
узнать, удалось
ли разместить
массив.
Этот параметр
может быть
опущен, но тогда
любая неудача
при выделении
памяти приведет
к ошибке этапа
исполнения
и остановке
программы.
Параметр указывается
в операторе
ALLOCATE
последним. При
удачном выделении
памяти целочисленная
статусная
переменная
ierr
возвращает
нуль, в противном
случае возвращается
код ошибки
размещения.
Причиной ошибки
может быть,
например,
недостаток
памяти или
"попытка разместить
ранее размещенный
и не освобожденный
оператором
DEALLOCATE
объект.
Аналогичную
роль играет
необязательный
параметр STAT=
и в операторе
DEALLOCATE.
Сечение массива
В Фортране
можно получить
доступ не только
к отдельному
элементу массива,
но и к некоторому
подмножеству
его элементов.
Такое
подмножество
элементов
массива называется
сечением
массива. Сечение
массива может
быть получено
в результате
применения
индексного
триплета или
векторного
индекса, которые
при задании
сечения подставляются
вместо одного
из индексов
массива.
Индексный
триплет имеет
вид: [нижняя
граница] : [верхняя
граница] [.шаг]
Каждый из
параметров
триплета является
целочисленным
выражением.
Шаг изменения
индексов может
быть и положительным
и
отрицательным,
но не может
равняться нулю.
Все параметры
триплета являются
необязательными.
Индексный
триплет задает
последовательность
индексов, в
которой первый
элемент равен
его нижней
границе,
а каждый последующий
больше (меньше)
предыдущего
на величину
шага. В последовательности
находятся все
задаваемые
таким правилом
значения индекса,
лежащие между
границами
триплета. Если
же нижняя граница
больше
верхней и шаг
положителен
или нижняя
граница меньше
верхней и шаг
отрицателен,
то последовательность
является пустой.
Пример. real
a(1:10);,
а(3:7:2) = 3.0 ! Триплет
задает сечение
массива с элементами
!
а(3), а(5), а(7), которые
получат значение
3.0 а(7:3:-2) = 3.0 !
Элементы а(7),
а(5), а(3) получат
значение 3.0
|