современный фортран , Бортеньев. О. В. Бартеньев Современный Фортран
Скачать 2.24 Mb.
|
58 риложение3. Организация данных Пример 2. D-форма числа 3.8*10 -5 - 2.6*10 -2 i задает комплексную константу двойной точности: (3.8D-5, -2.6D-2) 3.5.4. Логические константы Логические константы используются для записи логических значений истина (.TRUE.) или ложь (.FALSE.). Отсутствие хотя бы одной обрамляющей точки в записи буквальной логической константы является ошибкой. По умолчанию буквальные логические константы занимают в памяти ЭВМ 4 байта. Разновидность типа буквальной логической константы может быть задана явно, подобно тому, как это выполняется для буквальных целых констант. Например: .true._1 или .false._2. Пример задания именованных логических констант: logical(1), parameter :: fl = .true._1 logical(2) gl parameter (gl = .false.) 3.5.5. Символьные константы Символьные константы - последовательность одного или более символов 8-битового кода. Далее последовательность символов мы будем называть строкой. Символьные константы могут быть записаны с указателем длины и без него. Символьные константы с указателем длины, называемые также холлеритовскими константами,имеют вид: nHпоследовательность символов, где n - целая константа без знака, задающая число символов в строке (ее длину); H (h) - буква, являющаяся разделителем между n и строкой. Число символов в последовательности символов должно быть равно n. Пример: 18hthis is a constant st = 16hthis is a string ! Константа как элемент выражения Символьная константа без указателя длины - это строка, заключенная в ограничители, апострофы или двойные кавычки. Ограничители вместе со строкой не сохраняются. Если строка должна содержать ограничитель, то она либо заключается в ограничители другого вида, либо ограничитель должен быть указан в строке дважды. Пример: 'Это константа' или "Это константа" "It's a constant" или 'It''s a constant' 59 О. В. Бартеньев. Современный ФОРТРАН Замечание. Символьные константы с указателем длины относятся к устаревшим свойствам Фортрана и не рекомендуются для применения. Можно задать СИ-строковую константу. Для этого к стандартной строковой константе Фортрана необходимо прибавить латинские буквы C или c. Как известно, CИ-строки заканчиваются нулевым символом, имеющим в таблице ASCII код 0. Пример СИ-константы: 'Это константа'с В СИ-строке символы могут быть представлены в восьмеричном или шестнадцатеричном коде, которые указываются при задании констант после обратной наклонной черты. Например, '\62'c и '\x32'c задают символ '2' в восьмеричном и шестнадцатеричном кодах (ASCII-код символа '2' равен 50). Также в СИ существует специальная запись приведенных в табл. 3.2 часто используемых управляющих символов. Таблица 3.2. Управляющие символы Символ ASCII-код Значение \0 0 Нулевой символ (null) \a 7 Сигнал \b 8 Возврат на шаг ("забой") \t 9 Горизонтальная табуляция \n 10 Новая строка \v 11 Вертикальная табуляция \f 12 Перевод страницы \r 13 Возврат каретки \" 34 Двойная кавычка \' 39 Апостроф \? 63 Знак вопроса \\ 92 Обратная наклонная черта \ooo Восьмеричная константа \xhh Шестнадцатеричная константа Пример: character :: bell = '\a'c ! или '\007'c, или '\x07'c character(20) :: st = '1\a\a\t1-1\n\r2'c write(*, *) bell ! Звуковой сигнал write(*, *) st 60 риложение3. Организация данных Вывод строки st на экран произойдет так: в первой позиции начальной строки выведется символ '1'; затем прозвучат два звуковых сигнала; далее после выполнения табуляции в строке будут выведены символы '1-1'; после этого будет выполнен переход в первую позицию новой строки экрана и выведется символ '2'; далее последуют завершающие пробелы и null- символ. В восьмеричном коде значение o находится в диапазоне от 0 до 7. В шестнадцатеричном коде h принимает значения от 0 до F. При записи СИ-строк могут быть использованы двойные кавычки, например апостроф может быть задан так: character quo /"\'"c/ ! или так: '\'''c Также можно задать символьную константу нулевой длины. character ch /''/ ! '' - константа нулевой длины print *, len(ch), len_trim(ch) ! 1 0 Поскольку символьные строки завершаются null-символом, то при их конкатенации (объединении) этот символ, если не принять специальных мер, окажется внутри результирующей строки, например: character(5) :: st1 = 'ab'c, st2 = '12'c character(10) res res = st1 // st2 ! Вернет ab\0 12\0 print *, ichar(res(3:3)), ichar(res(8:8)) ! 0 0 Длинная символьная буквальная константа, т. е. константа, которую не удается разместить на одной строке, задается с использованием символов переноса, например: character(len = 255) :: stlong = 'I am a very, very, very long & &the longest in the world symbol constant (indeed very long - & &longer any constant you know)' Замечание. В начале строки продолжения символ переноса может быть опущен. 3.6. Задание именованных констант Защитить данные от изменений в процессе вычислений можно, задав их в виде именованных констант. Именованная константа - это именованный объект данных с атрибутом PARAMETER. Задание атрибута можно выполнить отдельным оператором: PARAMETER [(] name = const [, name = const ...] [)] или в операторе объявления типа: typespec, PARAMETER [, attrs] :: name = const [, name = const] ... typespec - любая спецификация типа данных. name - имя константы. Не может быть именем подобъекта. 61 О. В. Бартеньев. Современный ФОРТРАН const - константное выражение. Выражение может включать имена констант, ранее введенных в той же программной единице. Допустимые операции константного выражения - арифметические и логические. Если тип константного выражения отличается от типа name, то любые операции преобразования типов выполняются автоматически. attrs - иные возможные атрибуты константы. Именованная константа может быть массивом или объектом производного типа. В первом случае для ее задания используется конструктор массива, во втором - конструктор производного типа. При использовании оператора PARAMETER задание именованной логической, символьной и комплексной константы должно выполняться после описания ее типа. Типы целочисленных и вещественных констант могут быть установлены в соответствии с существующими умолчаниями о типах данных. Попытки изменить значение именованной константы при помощи оператора присваивания или оператора READ приведут к ошибке компиляции. Именованная константа name не может быть компонентом производного типа данных, элементом массива и ассоциированным объектом данных, примененным, например, в операторах EQUIVALENCE или COMMON. Также именованная константа не может появляться в спецификации управляющего передачей данных формата. При использовании константы в качестве фактического параметра процедуры соответствующему формальному параметру следует задать вид связи INTENT(IN). Пример 1. Задание именованных констант в операторе PARAMETER. character(1) bell parameter (bell = '\a'C) ! СИ-строка parameter (g = 9.81, pi = 3.14159) ! Обрамляющие круглые скобки можно опустить complex(4) z ! Сначала объявляется тип, parameter (z = -(12.45, 6.784)) ! а затем задается значение write(*, *) bell ! Звуковой сигнал write(*, *) (bell, i = 1, 10) ! Продолжительный сигнал Пример 2. Использование PARAMETER в качестве атрибута. program pa complex(4), parameter :: z = -(12.45, 6.784) integer(2), parameter :: a(5) = (/ 1, 3, 5, 7, 9 /) ! a - массив-константа type made ! Задание типа made character(len = 8) bday character(len = 5) place end type made ! Задание константы pro типа made type(made), parameter :: pro = made('08/01/90', 'Mircu') write(*,'(1x, a10, 2x, a5)') pro end program pa 62 риложение3. Организация данных 3.7. Задание начальных значений переменных. Оператор DATA В Фортране существует две возможности задания начальных значений переменных: в операторах объявления типа и оператором DATA. Начальные значения присваиваются переменным на этапе компиляции программы. Синтаксис оператора DATA: DATA список имен /список значений/ & [, список имен /список значений/] ... Список имен - список переменных, их подобъектов и циклических списков. Элементы списка разделяются запятыми. Индексы элементов массивов и подстрок в списке имен должны быть целочисленными константными выражениями. Список значений - список констант и/или повторяющихся констант, разделенных запятыми. Повторяющаяся константа - элемент вида n*val, где n - целая положительная константа (буквальная или именованная); * - символ- повторитель. Такой элемент в списке значений означает, что n подряд расположенных переменных в списке имен получат в результате выполнения оператора DATA значение val. Пример: real(4) a(6, 7), d, r, eps, cmax character st*6, sth*20, chr integer(4) m, n logical(1) flag, yesno data a /1, 2, 3, 4, 5, 6, 7, 35*0/, & d, r /4, 6.7/, & eps /1.0e-8/, cmax /2.4e12/ data st /'Error!'/, chr /'Y'/, m, n /6, 7/ data sth /18hHollerith constant/ data flag, yesno /.true., .false./ При большом числе инициализируемых переменных следует для улучшения читаемости программы использовать строки продолжения или несколько операторов DATA. Переменные производного типа инициализируются посредством применения в DATA конструктора производного типа (разд. 3.9.2.1) или путем инициализации их отдельных компонентов: type pair real x, y end type pair type(pair) pt1, pt2 ! Используем для инициализации pt1 data pt1 / pair(1.0, 1.0) / ! конструктор структуры 63 О. В. Бартеньев. Современный ФОРТРАН data pt2.x, pt2.y / 2.0, 2.0 / ! Инициализации отдельных компонентов print '(1x, 4f5.1)', pt1, pt2 ! 1.0 1.0 2.0 2.0 Переменные, явно получившие атрибут AUTOMATIC, не могут появляться в операторе DATA. При необходимости тип данных каждого числового или логического элемента в списке значений преобразовывается в тип, заданный для соответствующей переменной в списке имен. Например, для инициализации вещественной переменной можно использовать целую буквальную константу. Число значений в каждом списке значений должно совпадать с числом элементов в соответствующем списке имен. Нельзя дважды в операторе DATA инициализировать одну и ту же переменную. Инициализация элементов двумерного массива выполняется по столбцам, например: real a(3, 2) data a / 1, 2, 3, 4, 5, 6 / ! Эта запись эквивалентна следующей data a(1,1), a(2,1), a(3,1), a(3,2), a(2,2), a(3,2) /1, 2, 3, 4, 5, 6/ Если символьный элемент в списке значений короче, чем соответствующая переменная или элемент массива в списке имен, его размер увеличивается до длины переменной посредством добавления завершающих пробелов. Если же символьный элемент длиннее соответствующей переменной, то избыточные символы отсекаются. Формальные параметры, переменные неименованных common-блоков и имена функций не могут появляться в операторе DATA. Переменные именованных common-блоков могут появляться в операторе DATA, если он используется в программной единице BLOCK DATA. Оператор DATA может содержать в списке имен циклические списки: (dolist, dovar = start, stop [, inc]) dolist - элемент массива, индексом которого является переменная dovar. start, stop, inc - целочисленные константные выражения, определяющие диапазон и шаг изменения dovar. Если выражение inc отсутствует, то шаг устанавливается равным единице. При использовании циклического списка можно выполнить инициализацию части массива. Возможна организация вложенных циклических списков. Пример: integer(4) a(20), b(5, 30), c(15, 15), row, col integer, parameter :: rma = 10, cma = 5 data (a(i), i = 4, 16, 2) / 4, 6, 8, 10, 12, 14, 16/ & ((b(i, j), j = 1, 12), i = 1, 2) /24 * -3/ & ((c(row, col), row = 1, rma), col = 1, cma) / 50 * 10/ 64 риложение3. Организация данных При задании начальных значений переменных в операторахобъявления типа начальное значение переменной следует сразу после объявления этой переменной. Возможно также, как и в случае оператора DATA, использование повторяющихся констант, например: real a(6, 7) /1, 2, 3, 4, 5, 6, 35*-1/, & d /4/, r /6.7/, & eps /1.0e-8/, cmax /2.4e12/ character st*6/'Error!'/, chr/'Y'/, sth*20/18hHollerith constant/ integer m /6/, n /7/ ! Ошибочна запись: integer m, n/6, 7/ ! или, используя синтаксис Фортрана 90: character(len = 6) :: st = 'Error!' integer :: m = 6, n = 7 ! Наличие разделителя :: обязательно Для инициализации переменных в операторах объявления типа могут использоваться конструкторы массивов и структур. Многомерный массив можно сконструировать из одномерного, применив функцию RESHAPE (разд. 4.12.4.3), например: real(4) :: b(42) = (/ 1, 2, 3, 4, 5, 6, (-1, k = 7, 42) /) real(4) :: c(6, 7) = reshape((/ 1, 2, 3, 4, 5, 6/ ), shape = (/ 6, 7 /), pad = (/ -1 /)) 3.8. Символьные данные 3.8.1. Объявление символьных данных Символьный тип данных в Фортране могут иметь переменные и константы, которые мы будем называть строками, а также массивы и функции. Элементом символьного массива является строка. Возвращаемый символьной функцией результат также является строкой. Символьные объекты данных объявляются оператором CHARACTER: CHARACTER [(type-param)] [[attrs] ::] vname type-param - длина vname и значение параметра разновидности; может иметь одну из следующих форм: • ([LEN = ] type-param-value); • (KIND = expr); • (KIND = expr, LEN = type-param-value); • ([LEN =] type-param-value, KIND = expr). type-param-value - может быть либо звездочкой (*), либо целой константой без знака в диапазоне значений от 1 до 32767, либо целочисленным константным выражением, вычисляемым со значением в диапазоне от 1 до 32767. Также если оператор CHARACTER объявляет формальные параметры и размещен в теле оператора INTERFACE или в разделе объявлений процедуры, то для задания type-param-value можно использовать и неконстантное описательное выражение (см. разд. 5.6). При этом если соответствующий фактический параметр задан, то формальный 65 О. В. Бартеньев. Современный ФОРТРАН параметр не может иметь атрибут SAVE, появляться в операторе DATA или быть инициализирован в операторе CHARACTER. Например, формальный параметр st3 подпрограммы sub: character(len = 15) :: st = 'example', st2*20 /'example_2'/ call sub(st, 15) call sub(st2, 20) end subroutine sub(st3, n) integer(4) n character(len = n) st3 ! длина st3 при первом вызове print *, len(st3) ! равна 15, а при втором - 20 end Если значение выражения, определяющего длину символьного элемента, отрицательное, то объявляемые символьные элементы будут нулевой длины. Если значение type-param не задано, то по умолчанию длина символьного объекта данных принимается равной единице. expr - целочисленное константное или описательное выражение, задающие разновидность символьного типа. Фортран поддерживает одно значение параметра разновидности (KIND = 1) для символьных объектов данных. attrs - один или более атрибутов, разделенных запятыми. Если хотя бы один атрибут задан, наличие разделителя :: обязательно. Используются те же, что и с оператором INTEGER (разд. 3.2.1) атрибуты. Если задан атрибут PARAMETER, то необходимо и инициализирующее выражение, например: character(len = 20), parameter :: st = 'Title' vname - имя переменной, константы или функции (внешней, внутренней, операторной, встроенной). По умолчанию строка, которой не задано начальное значение, состоит из null-символов. Поэтому функция LEN_TRIM вернет для этой строки ее полную длину. Полезно выполнять инициализацию строки, например, пробелами: character(30) fn, path /' '/ ! path получает начальное значение write(*, *) len(fn), len(path) ! 30 30 write(*, *) len_trim(fn), len_trim(path) ! 30 0 write(*, *) ichar(fn(1:1)), ichar(path(5:5)) ! 0 32 Если начальное значение строки содержит меньше символов, чем ее длина, то недостающие символы восполняются пробелами, которые 66 риложение3. Организация данных называются завершающими. Если начальное значение содержит больше символов, чем длина строки, то избыточные символы отсекаются. Можно использовать символьные буквальные СИ-константы, завершаемые null-символами, например: character(20) :: st = 'C string'c write(*, *) st Как и для других типов данных, можно использовать синтаксис оператора CHARACTER Фортрана 77, например: character*15 st1 /'first'/, st2 /'second'/ ! Строки длиной в 15 символов character*5 st3, st4*10, st5*15 ! Строки длиной в 5, 10 и 15 символов character*6 ast(10) /'Nick', 'Rose', 'Mike', 'Violet', 6*'???'/ character err*(*) parameter (err = 'Error!') Замечание. В FPS при инициализации с использованием коэффициента повторения необходимо следить за длиной инициализирующей буквальной символьной константы: ее длина должна совпадать с заданной в операторе CHARACTER длиной строки. Так, в операторе character*6 ast(10) /'Nick', 'Rose', 'Mike', 'Violet', 6*'???'/ не будет выполнена инициализация последних пяти элементов массива. Для правильной инициализации следует использовать повторяющуюся константу 6*'??? ', в которой символ означает пробел. В CVF таких проблем нет. 3.8.2. Применение звездочки для задания длины строки Применение звездочки (*) для задания длины символьного объекта данных возможно в трех случаях: 1) при объявлении символьных именованных констант (объектов, имеющих атрибут PARAMETER). В этом случае длина строки равна числу символов константы, например: character(*) st ! или character(len = *) st ! или character(len = *, kind = 1) st ! или character(*, kind = 1) st ! или character(kind = 1, len = *) st parameter (st = 'exam') или character(len = *), parameter :: st = 'exam'! и так далее Так же может быть объявлена символьная константа - массив: character(len = *), parameter :: ast(3) = (/'jan', 'febr', 'march'/) или |