Автоматическиемассивы
В процедуреможет бытьзадан локальныймассив, размерыкоторого могутменяться приразных вызовахпроцедуры.
Такиемассивы, также как и локальныестроки переменнойдлины (разд.10.4), относятсяк автоматическимобъектам.
Фортранподдерживаетрекурсивныевызовы внешних,модульных ивнутреннихпроцедур.
Процедураназываетсярекурсивной,еслиона обращаетсясама к себе иливызывает другуюпроцедуру,которая, в своюочередь,
вызываетпервую процедуру.В первом случаерекурсия называетсяпрямой,вовтором - косвенной.
Операторобъявлениярекурсивнойпроцедурыдолжен предварятьсяпрефиксомRECURSIVE.Внутри рекурсивной
процедурыинтерфейс кэтой процедуреявляется явным(см. разд. 16.4.3).
Пример.Разработатьподпрограммуsubst,котораяв данной строкезаменяет всевхожденияподстроки sub1
наподстроку sub2.Так,если дана строка'abc1abc2abc3'и sub1= 'abc',asub2=' d',то результатомдолжна бытьстрока ' dld2d3'.
program stgo
character(len= 20) :: st ='abc1abc2abc3'
callsubst(st, 'abc', d') ! subst содержитпрямую
write(*,*) st !рекурсиюd1 d2 d3
end
recursivesubroutine subst(st,subl, sub2)
character(len= *) st, sub1, sub2 ! Длинакаждой строкиопределяется
integerip!длиной соответствующего
ip= index(st,sub1) ! фактическогопараметра
if(ip> 0) then
st = st(:ip - 1) // sub2 // st(ip+ len(subl):)
callsubst(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
БОК
ENDDO (имя]
задаетбесконечныйцикл. Поэтомутакой циклдолжен содержатьпо крайнеймере
одиноператор, напримерEXIT[имя],обеспечивающийвыход из этогоцикла.
Имя конструкции,если оно присутствует,должно появлятьсявоператорахDOи ENDDO.
Рекомендуемаяформа DO-циклас параметром:
[имя:] DO dovar = start, stop [, inc]
БОКENDDO [имя]
dovar- целаяпеременная,называемаяпеременнойцикла или параметромцикла;
start,stop- целыескалярныевыражения,задающие диапазонизмененияdovar;
inc- целоескалярноевыражение,задающее лагизмененияdovar.Значениеincнеможет
бытьравным нулю.Если параметрincотсутствует,то он принимаетсяравным единице.
Рекомендуемаяформа DOWHILE-цикла:
[имя]DOWHILE(ЛB)?
БОК
ENDDO [имя]
ЕслиDOWHILE-циклне содержитоператоровпрерыванияцикла,
БОКвыполняетсядо тех пор, покаистинно скалярноеЛВ.
DO-цикл,DO-циклс параметроми DOWHILE-циклмогут быть
рваныоператорамиGOTO,EXITи CYCLE,а также в результате
выполненияоператораRETURN,обеспечивающеговозврат изподпрограммы.
ОператорEXIT[имя}
передаетуправлениеиз DO-конструкциина первый следующийза kohiрукцией
выполняемыйоператор. Еслиимяопущено,то EXITобеспечив;выход из текущегоцикла,
впротивномслучае EXITобеспечиваетвыход цикла,имякоторогоприсутствуетв оператореEXIT.
ОператорCYCLE[имя]
передаетуправлениена началоDO-конструкции.При этом операторрасположенные
междуCYCLEи операторомENDDOконца цикла,не выполняются.Если имяопущено,то CYCLE
обеспечиваетпереход наначало текущегоцикла, в противномслучае CYCLEобеспечивает
переходна началоцикла, имякоторогоприсутствуетв оператореCYCLE.
Условныйлогическийоператор IF
IF(ЛВ)оператор
Еслиистинно ЛВ, товыполняетсяоператор,впротивномслучае управлениепередаетсяна
последующийоператор программы.
КонструкцияIF THEN ENDIF
[имя-.]IF(ЛВ)THEN
БОК
ENDIF [имя]
БОКвыполняется,если истинноЛВ. Если присутствуетимя конструкции,то оно должно
бытьи в первом и впоследнемоператореконструкции,например:
swap:if(x
hold= х; х = у; у = hold
end if swap
Замечание.ЕслиБОК содержитодин оператор,то лучше использовать
оператор
IF(ЛВ)оператор
КонструкцияIF THEN ELSE ENDIF
[имя:]IF(ЛВ)THEN
БОК1
ELSE[имя]
БОК1
ENDIF [имя]
Вслучае истинностиЛВ выполняетсяБОК1 и выполняетсяБОК2, если ЛВложно.
Имяконструкции,если оно задано,должно обязательноприсутствоватьи перед IF,
ипослеEND IF.
КонструкцияIF THEN ELSE IF
[имя:]IF(ЛВ)THEN
БОК1
ELSEIF(ЛВ2)THEN [имя]
БОК2
…
[ELSE[имя]
БОКn
ENDIF [имя]
В случаеистинностиЛВ1 выполняетсяБОК1 и управлениепередаетсяна
следующийза ENDIFоператор. ЕслиЛВ1 ложно, тоуправление
передаетсяна следующийELSEIF,то есть вычисляетсязначение
ЛВ2и, если оноистинно, товыполняетсяБОК2. Если оноложно, то
управлениепередаетсяна следующийELSEIF,и так далее.Если ложны все
ЛВ,то выполняетсяследующий зазавершающимELSEБОКп.
ЕслизавершающийELSEотсутствует,то управлениепередаетсяна расположенный
заENDIFоператор.Число операторовELSEIFв конструкцииможет быть
произвольным.Имяв ELSEи в ELSEIFможно задавать,если это имяимеют
операторыIFи ENDIF.Имя, если онозадано, во всехчастях
конструкциидолжно бытьодинаковым.
КонструкцияSELECT CASE
[имя:] SELECT CASE (тест-выражение)
CASE(CП1)[имя]
[БОК1]
[CASE(CП2)[имя]
[БОК2]]
…
[CASEDEFAULT [имя]
[БОКп]]
ENDSELECT[имя]
Тест-выражение- целочисленное,символьноетипа CHARACTER(l)
Илилогическоескалярноевыражение.
СП- список констант,тип которыхдолжен соответствоватьтипу тест-выражения.
КонструкцияSELECTCASE-работаеттак: вычисляетсязначениетест-выражения.Если
полученноезначение находитсяв списке СП1,то выполняетсяБОК1; далееуправление
передаетсяна следующийза ENDSELECTоператор. Еслизначение в СП1не находится,
топроверяется,есть ли оно вСП2,и так далее.Если значениетест-выраженияне найдено
нив одном спискеи присутствуетоператор CASEDEFAULT,то выполняетсяБОКп, а далее
выполняетсярасположенныйза ENDSELECTоператор. Еслиже значениетест-выражения
ненайдено ни водном спискеи CASEDEFAULTотсутствует,то ни один изБОКл не выполняется
иуправлениепередаетсяна следующийза ENDSELECTоператор.
Списокконстант СПможет содержатьодно значение,или состоятьиз разделенных
запятымиконстант, илибыть задан какдиапазон разделенныхдвоеточиемзначений,
например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. Поиск.Постановказадачи. Дихотомическийпоиск.
Границыразмерностеймассивов - формальныхпараметровмогут определятьсяпередаваемымив процедуру
значениямидругих параметров.Так, в рассмотреннойв разд. 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
subroutineswap(a, b, m, n)
integerm,n
reala(m*n),b(m*n) ! а и b– массивы заданнойформы)
realc(size(a)) ! с -автоматическиймассив
с = а
a=b
endsubroutineswap
В общем случаедля формальногопараметра -массива могутвычислятьсякак нижняя,
так и верхняяграницы размерности.Общий видразмерноститаких массивов:
[нижняя граница]: [верхняя граница]
Нижняя иверхняяграницы - целочисленныеописательныевыражения.Вычисленные
границы массивафиксируютсяна время выполненияпроцедурыи не меняютсяпри
изменениизначениясоответствующегоописательноговыражения.
При работе стакими массиваминеобходимоследить, чтобыразмер массива- формального
параметране превосходилразмера ассоциированногосним массива- фактическогопараметра.
Еслифактическимпараметромявляется многомерныймассив и соответствующимему формальным
параметромявляется массивзаданной формыс тем же числомизмерений, тодля правильного
ассоциированиянеобходимоуказать размерностимассива - формальногопараметратакими же,
Как и у массива- фактическогопараметра.Исключениеможет составлятьверхняя граница последней
размерностимассива, котораяможет меньшесоответствующейграницы массива- фактическогопараметра.
Если в качествефактическогопараметра задан элемент массива,т формальныйпараметр
ассоциируетсяс элементамимассива-родителяначиная с данногоэлемента идалее по порядку.
Такие массивы- формальныепараметрыперенимаютформу у соответствующегофактического
параметра. Врезультатеранг и формафактическогои формальногопараметровсовпадают. Приописании
формы формальногопараметракаждая размерностьимеет вид: [нижняяграница] :
где нижняяграница - этоцелое описательноевыражение,которое може!зависеть отданных в процедуре
или другихпараметров.Если нижняяграница опущена,то ее значениепо умолчаниюравно единице.
Например»ПРИвызове
real х(0:3,0:6, 0:8)
interface
subroutine asub(a)
real a(:,:,:)
end
endinterface
callasub(x)
Соответствующийперенимающийформу массивобъявляетсятак:
subroutine asub(a)
real a(:, :, :)
prnt *,lbound(a, 3), ubound(a, 3) ! 1 9
Так какнижняя границав описаниимассива аотсутствует,то после вызоваподпрограммыв ней будет
определенмассив а(4, 7, 9). Еслинужно сохранитьсоответствиеграниц, то массива следуетобъявить так:
reala(0:,0:, 0:)
В интерфейсномблоке по-прежнемумассив аможнообъявить:
realа(:, :, :)
Процедуры,содержащиев качествеформальныхпараметровперенимающиеформу массивы,
должныобладать явнозаданным интерфейсом.
Сортировка
Основноеназначениесортировки- обеспечитьбыстрый поискданных. Помимоэтого, в отсортированном
файлеили массивегораздо быстреевыполнятьмногие вычисления.
Сортировкаметодом пузырька
Сортировкаметодом пузырьканаиболее простадля реализации,но имеет посравнению
с другими методаминаименьшуювычислительнуюэффективность.
Не теряя общности,будем для простотыизложения вдальнейшемрассматриватьзадачу
сортировкимассива хцелыхчисел, в которомпервые я чиселдолжны быть
отсортированытак, чтобы хiXjдля 1 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.
Сечение массива
В Фортранеможно получитьдоступ не толькок отдельномуэлементу массива,но и к некоторомуподмножествуего элементов.
Такоеподмножествоэлементовмассива называетсясечениеммассива. Сечениемассива можетбыть полученов результатеприменения
индексноготриплета иливекторногоиндекса, которыепри заданиисечения подставляютсявместо одногоиз индексовмассива.
Индексныйтриплет имеетвид: [нижняяграница] : [верхняяграница] [.шаг]
Каждый изпараметровтриплета являетсяцелочисленнымвыражением.Шаг измененияиндексов можетбыть и положительными
отрицательным,но не можетравняться нулю.Все параметрытриплета являютсянеобязательными.
Индексныйтриплет задаетпоследовательностьиндексов, вкоторой первыйэлемент равенего нижнейгранице,
а каждый последующийбольше (меньше)предыдущегона величинушага. В последовательностинаходятся все
задаваемыетаким правиломзначения индекса,лежащие междуграницамитриплета. Еслиже нижняя границабольше
верхней и шагположителенили нижняяграница меньшеверхней и шаготрицателен,то последовательностьявляется пустой.
Пример.
reala(1:10);,
а(3:7:2) = 3.0! Триплетзадает сечениемассива с элементами
!а(3), а(5), а(7), которыеполучат значение3.0
а(7:3:-2) = 3.0 !Элементы а(7),а(5), а(3) получатзначение 3.0