Главная страница
Навигация по странице:

  • 9.6. Согласование списка ввода/вывода и спецификации формата. Коэффициент повторения. Реверсия формата

  • 9.7. Дескрипторы данных

  • современный фортран , Бортеньев. О. В. Бартеньев Современный Фортран


    Скачать 2.24 Mb.
    НазваниеО. В. Бартеньев Современный Фортран
    Анкорсовременный фортран , Бортеньев.pdf
    Дата28.05.2018
    Размер2.24 Mb.
    Формат файлаpdf
    Имя файласовременный фортран , Бортеньев.pdf
    ТипДокументы
    #19729
    страница33 из 49
    1   ...   29   30   31   32   33   34   35   36   ...   49
    299

    О. В. Бартеньев. Современный ФОРТРАН
    end do
    ! Вывод строки таблицы write(*, '(2x, f5.2, 9(1x, f7.2))') x, z(:k) x = x + dx end do write(*, 1) ('_', k = 1, 80)
    1 format(80a1)
    ! Формат вывода горизонтальной линии end program zxy
    Замечание. Для вывода значений z в одной строке в цикле по y можно использовать, применив дескриптор '\', непродвигающийся вывод. В этом случае можно обойтись без промежуточного массива z(1:10).
    9.6. Согласование списка ввода/вывода и спецификации
    формата. Коэффициент повторения. Реверсия формата
    Дескрипторы преобразований (ДП) подразделяются:

    на дескрипторы данных (ДД);

    на дескрипторы управления;

    на строки символов.
    Дескрипторы данных, например F8.2 или I6, определяют размер и форму полей В/В, в которых размещаются текстовые представления данных. При форматном В/В каждому элементу списка В/В соответствует дескриптор данных. Элементы списка В/В и ДД должны быть согласованы по типам.
    Так, нельзя передать вещественное число, применяя преобразование Iw.m.
    При вводе также должны быть согласованы внешние представления данных и ДД. Так, если поле ввода содержит символы и выполняется ввод с этого поля целого числа, то возникнет ошибка ввода.
    Если в списке В/В присутствует несколько элементов, то каждый элемент выбирает один ДД из списка ДП. Правило выбора таково: j-й элемент списка В/В выбирает j-й ДД (назовем этот порядок выбора
    правилом 1). При этом поля всех элементов списка В/В располагаются в одной записи. Это правило работает, когда число ДД не меньше числа элементов в списке В/В.
    Пример: integer k, n, m(9) read(*, '(I8, I5, I5, I5)') k, n, m(2), m(4)
    Переменная k выберет дескриптор I8, остальные - I5. На входе должна быть определена запись с данными (символ использован для обозначения пробела):
    123 345 346 347
    Последовательность одинаковых ДД можно записать, использовав
    коэффициент повторения - задаваемую перед ДД целую буквальную константу без знака или задаваемое в угловых скобках целочисленное
    300

    9. Форматный ввод/вывод выражение. Так, спецификацию формата в операторе ввода последнего примера можно записать компактнее: read(*, '(I8, 3I5)') k, n, m(2), m(4)
    ! 3 - коэффициент повторения
    Коэффициент повторения может быть применен и для группы ДП.
    Общий вид записи повторяющейся группы ДП таков:
    n[(] группа ДП [)]
    Круглые скобки можно опустить, если группа ДП включает лишь один
    ДД. В группу ДП могут входить как ДД, так и дескрипторы управления.
    Использование коэффициента повторения перед дескриптором управления или строкой возможно лишь в том случае, когда дескриптор заключен в скобки. Использование коэффициента повторения отдельно перед дескрипторами управления и строками недопустимо.
    Пример использования коэффициента повторения для группы ДП: write(*, '(2x, F3.0, 2x, F3.0, 2x, F3.0)') a, b, c write(*, '(3(2x, F3.0))') a, b, c
    Теперь рассмотрим ситуацию, когда число ДД в спецификации формата меньше числа элементов в списке В/В. Пусть число ДД равно m. Тогда первые m элементов списка В/В выберут ДД по правилу 1. Далее начнется следующая запись (следующая строка текстового файла), и последующие m элементов списка В/В вновь выберут те же ДД, следуя правилу 1, и так далее до исчерпания списка В/В. Причем при вводе новая запись будет браться из файла, даже если введены не все данные последней передаваемой записи. Это, правда, верно, если в операторе В/В не задан спецификатор ADVANCE = 'NO', обеспечивающий передачу данных без продвижения. Назовем этот порядок выбора правилом 2.
    Пример: integer k, n, m(9) read(*, '(I8, 3I5)') k, n, m(1:9)
    В списке ввода 11 элементов. Переменная k выберет ДП I8; n, m(1),
    m(2) - I5; m(3) - I8; m(4), m(5), m(6) - I5; m(7) - I8, m(8), m(9) - I5. В файле данных должны быть определены не менее трех записей, например:
    123 333 444 555
    -25 777 888 999 111 222 333 444 555
    В результате ввода переменные получат значения: k - 123, n - 333, m(1) -
    - 444, m(2) - 555, m(3) - 777, m(4) - 888, m(5) - 999, m(6) - 111, m(7) - 333,
    m(8) - 444, m(9) - 555.
    Правило 2 работает в том случае, когда один или несколько ДД не заключены в круглые скобки.
    301

    О. В. Бартеньев. Современный ФОРТРАН
    Круглые скобки употребляются, во-первых, если необходимо применить коэффициент повторения для последовательности ДД, во-вторых, чтобы установить формат В/В элементов списка В/В, для которых исчерпаны все
    ДД с учетом коэффициентов повторения.
    Пример: integer :: j, k, n, a(10), b(30) read(*, '(2I8, 5(I2, I3), 5(I4, 1X, I1))') k, n, a, (b(j), j=1,30)
    Число элементов в списке ввода равно 42. Число ДД с учетом коэффициентов повторения равно 22. Первые 22 элемента списка будут введены из первой записи файла, используя ДД по правилу 1. После ввода первых 22 элементов формат будет исчерпан. Для всех оставшихся записей будет применен последний заключенный в круглые скобки фрагмент формата - 5(I4, 1X, I1). Форматы 2I8 и 5(I2, I3) более использоваться не будут. Формат 5(I4, 1X, I1) будет применяться в соответствии с правилом 2, поэтому вторая и третья записи должны содержать не менее 10 полей данных каждая.
    Общее правило использования формата при наличии в спецификации формата выделенных в скобки компонентов таково: если формат содержит заключенные в скобки ДД, то в случае, если он будет исчерпан, в файле возьмется новая запись и управление форматом вернется к левой скобке, соответствующей предпоследней правой скобке, или к соответствующему коэффициенту повторения, если он имеется. В приведенном примере - к 5(I4, 1X, I1). Это правило называется реверсией формата.
    9.7. Дескрипторы данных
    Рассмотрим теперь детально дескрипторы данных Фортрана. Полный перечень ДД приведен в табл. 9.2.
    Таблица 9.2. Дескрипторы преобразования данных
    Дескриптор
    Тип аргумента
    Внешнее представление
    Iw[.m]
    Целый
    Целое число
    Bw[.m]
    "
    Двоичное представление
    Ow[.m]
    "
    Восьмеричное представление
    Zw[.m]
    Любой
    Шестнадцатеричное представление
    Fw.d
    Вещественный
    Вещественное число в F-форме
    Ew.d[Ee]
    "
    " " в Е-форме
    ENw.d[Ee]
    "
    " " "
    Dw.d
    "
    " " двойной точности
    Lw
    Логический
    Т и F, .T и .F, .TRUE. и .FALSE.
    302

    9. Форматный ввод/вывод
    A[w]
    Символьный
    Строка символов
    Gw.d[Ee]
    Любой
    Зависит от типа данных
    В таблице использованы следующие обозначения:

    w - длина поля, отведенного под представление элемента В/В;

    m - число ведущих нулей (m
    w);

    d - число цифр после десятичной точки (d < w).
    Замечание. Фортран 95 позволяет задать значение w, равное нулю, например I0 или F0.5. В этом случае длина поля определяется значением выводимого числа. Это свойство применимо с дескрипторами B, F, I, O и Z.
    Если же w > 0 и при форматном выводе число полученных в результате преобразования символов превосходит w, то все поле заполняется звездочками (*). Например: write(*, '(i0)') 123
    ! 123 write(*, '(i2)') 123
    ! ** write(*, '(f0.2)') 123.45
    ! 123.45 write(*, '(f5.2)') 123.45
    ! ***** end
    Общие правила преобразования числовых данных:

    внешним представлением элемента В/В является строка символов;

    при вводе поле, полностью состоящее из пробелов, всегда интерпретируется как нуль. В противном случае интерпретация пробелов управляется дескрипторами BN и BZ;

    при вводе знак + может быть опущен;

    при вводе с дескрипторами F, E, G и D число цифр после запятой определяется положением десятичной точки. При ее отсутствии - значением параметра d;

    при выводе символы выравниваются по правой границе поля и при необходимости добавляются ведущими пробелами;

    если при выводе число полученных в результате преобразования символов превосходит длину поля w, то все поле заполняется звездочками;

    если вещественное число содержит больше цифр после десятичной точки, чем предусмотрено параметром d, то отображается округленное до d знаков после десятичной точки значение числа;

    при работе с комплексными числами необходимо применять одновременно два дескриптора вида F, E, G или D: первый - для действительной, второй - для мнимой части комплексного числа;

    дескрипторы управления и строки могут появляться между ДД;

    с дескрипторами F, E, G и D может быть использован дескриптор kР, где k - коэффициент масштабирования (-127
    k ≤ 127). Действие
    303

    О. В. Бартеньев. Современный ФОРТРАН
    масштабного множителя k, если задан дескриптор kР, распространяется на все дескрипторы F, E, G и D списка до появления нового дескриптора
    kP;

    при чтении с дескрипторами I, B, O, Z, F, E, G, D или L входное поле может содержать запятую, которая завершает поле. При этом следующее поле начинается с символа, стоящего за запятой. Однако нельзя использовать в качестве разделителей запятые одновременно с дескрипторами позиционирования (T, TL, TR или nX), поскольку они изменяют позиции символов в записи.
    Опишем теперь ДД.
    При использовании дескриптора Iw[.m] при вводе во внутреннее представление преобразовывается последовательность пробелов и цифр (со знаком или без знака), не содержащая десятичной точки или десятичной экспоненты. В списке вывода операторов WRITE и PRINT могут присутствовать элементы только целого типа. В противном случае возникнет ошибка выполнения.
    Если задано положительное число m, то выводимое целое число будет дополнено m - n ведущими нулями, где n - число значащих цифр в числе.
    На ввод параметр m никакого влияния не оказывает. integer :: k1 = 123, k2 read(*, '(I4)') k2
    ! Введем: -123 write(*, '(1X, I12, I12.7)') k1, k2
    !
    123
    -0000123
    Bw[.m], Ow[.m], Zw[.m] - двоичный (B), восьмеричный (O) и шестнадцатеричный (Z) дескрипторы данных. Данные, соответствующие этим дескрипторам, не могут содержать десятичной точки или знака (+ и -), но содержат пробелы или символы соответствующей системы счисления: цифры 0 и 1 при использовании дескриптора B; цифры 0-7 при использовании дескриптора O; цифры 0-9 и буквы A - F в случае дескриптора Z.
    Дескрипторы B и O могут быть использованы только с целочисленными входными и выходными данными. Дескриптор Z может быть использован с данными любого типа. Кодировка чисел в B-, O- и Z-формах зависит от процессора
    (особенно отрицательных), поэтому программы, применяющие дескрипторы B, O и Z и соответствующие им формы данных, могут неадекватно работать на других компьютерах.
    Параметр w задает длину поля В/В, а m - минимальное число выводимых символов (m
    w). При отсутствии m минимальное число выводимых символов равно единице. Если выход меньше, чем w, то он дополняется ведущими пробелами. Если выход меньше, чем m, то он дополняется ведущими нулями до размера m. Двоичные числа легче читать при наличии ведущих нулей вместо пробелов.
    При вводе дескрипторы B, O и Z преобразовывают внешние двоичные, восьмеричные и шестнадцатеричные данные во внутреннее представление.
    304

    9. Форматный ввод/вывод
    Каждый байт внутреннего представления соответствует восьми двоичным символам, трем восьмеричным и двум шестнадцатеричным. Например: integer :: k(3) = 255 write(*, '(2x, b8, 1x, o3, 1x, z2)') k
    ! 11111111 377 FF
    Соответственно значение типа INTEGER(4) займет 32 двоичных,
    12 восьмеричных и 8 шестнадцатеричных символов.
    Если параметр w опущен, то длина поля В/В устанавливается по умолчанию: 8*n - для формата B, 3*n - для формата O и 2*n - для формата
    Z, где n – значение параметра разновидности типа элемента В/В.
    Порядок вывода символов элементов символьного типа совпадает с порядком их размещения в памяти. Байты числовых и логических типов выводятся в порядке их значимости слева направо (наиболее значимый байт выводится первым, т. е. расположен левее следующего по значимости байта).
    Дескриптор Z может быть применен с символьными данными, если длина строки не превышает 130 символов. Если же передается строка большей длины, то будут преобразованы только первые 130 символов.
    Вывод с применением дескрипторов B, O и Z выполняется по правилам
    (n - величина параметра разновидности типа):

    если w > 8*n (B), 3*n (O) или 2*n (Z), то символы выравниваются по правой границе поля и добавляются ведущие пробелы, увеличивающие поле до w символов;

    если w
    ≤ 8*n (B), 3*n (O) или 2*n (Z), то выводится w правых символов;

    если m > 8*n (B), 3*n (O) или 2*n (Z), то символы выравниваются по правой границе поля и добавляются ведущие нули, увеличивающие число символов до m;

    если m < 8*n (B), 3*n (O) или 2*n (Z), то параметр m не оказывает никакого действия.
    Правила ввода (параметр m не оказывает никакого действия):

    если w
    ≥ 8*n (B), 3*n (O) или 2*n (Z), то правые 8*n (B), 3*n (O) или
    2*n (Z) символов берутся из поля ввода;

    если w < 8*n (B), 3*n (O) или 2*n (Z), то первые w символов читаются из поля ввода. Недостающие до длины 8*n (B), 3*n (O) или 2*n (Z) символы замещаются пробелами.
    В отличие от других ДД при выводе с дескрипторами B, O или Z значения, большего, чем можно разместить в поле вывода, выводятся не звездочки, а w правых символов. При вводе из незаполненных слева полей ввода знаковый бит игнорируется.
    Пример: character(2) :: st(3) = 'ab' integer(2) :: k(3) = 3035
    305

    О. В. Бартеньев. Современный ФОРТРАН
    write(*, '(1x, z4.4, 1x, z2, 1x, z6)') st write(*, '(1x, z4.4, 1x, z2, 1x, z6)') k write(*, '(1x, b16.16, 1x, b2, 1x, b6)') k write(*, '(1x, o5.5, 1x, o2, 1x, o6)') k
    Результат:
    6162 62 6162 0BDB DB
    BDB
    0000101111011011 11 011011 05733 33 20005733
    Расположенные в поле ввода завершающие пробелы трактуются как нули, если в операторе OPEN задан спецификатор BLANK = 'ZERO' или действует дескриптор BZ, например: integer(1) :: k1, k2, k3 read(*, '(bn, b8, bz, b8, b8)') k1, k2, k3 write(*, '(1x, 3I5)') k1, k2, k3
    Введем (символ используем для обозначения пробела):
    1 1
    1000000
    Результат:
    1 64 64
    Дескриптор Fw.d обеспечивает вывод вещественных чисел одиночной или двойной точности. Вывод выполняется на поле длиной в w символов.
    Один символ отводится под десятичную точку. При выводе отрицательного числа еще один символ будет отведен под знак. Из оставшихся w - 1 или
    w - 2 символов d символов будут отведены под числа, следующие после десятичной точки числа. Оставшиеся символы будут либо пробелами, либо цифрами, расположенными слева от десятичной точки. Выводимое число при преобразовании во внешнее представление при необходимости округляется.
    При вводе с дескриптором Fw.d передача данных осуществляется с поля длиной в w символов, на котором можно разместить целочисленные или вещественные числа в F- или E-форме (со знаком или без знака). Если десятичная точка отсутствует, то число десятичных знаков вводимого вещественного числа будет равно d. При наличии во внешнем представлении десятичной точки число десятичных знаков вводимой величины определяется положением десятичной точки и может отличаться от значения d. Пробелы между десятичными цифрами или между десятичной точкой и цифрами интерпретируются как нули, если задан дескриптор BZ, и игнорируются, если задан дескриптор BN или если оба дескриптора в спецификаторе формата отсутствуют.
    Пример 1:
    306

    9. Форматный ввод/вывод real a, b, c, d, e
    ! Введем: read(*, 1) a, b, c, d, e
    !
    234 0.234 .234E2 -2.34E-3 .
    023 write(*, 1) a, b, c, d, e
    ! 2.34
    .23 23.40
    -.0023 .00023 1 format(2F6.2, F7.2, F10.4, BZ, F7.5)
    Пример 2. Все элементы массива a в результате ввода разных представлений числа 1.23 примут одно и то же значение. real a(5)
    ! Вводимые данные: read(*, 1) a
    !
    12300 1.23 12.3E-1 1 2300 .0123E2 write(*, 1) a
    ! 1.2300 1.2300 1.2300 1.2300 1.2300 1 format(10F8.4)
    Замечание. В последнем примере лучше воспользоваться выводом, управляемым списком В/В, указав во входном потоке, например, так: read(*, *) a
    ! 1.23 1.23 1.23 1.23 1.23 или так (поля данных разделяются запятой): read(*, *) a
    ! 1.23, 1.23, 1.23, 1.23, 1.23 или так: read(*, *) a
    ! 5*1.23
    Рассмотрим механизм преобразования числа -1.23 при выводе на примере дескриптора F8.3, т. е. результат выполнения оператора write(*,'(f8.3)') -1.23
    ! -1.230
    Число -1.23 расположится на поле длиной в 8 символов. Поскольку
    d = 3, а в числе только две цифры после десятичной точки, то последним символом будет 0, далее последуют символы 3, 2, десятичная точка,
    1 и знак -. Первыми двумя символами в отведенном под число поле будут пробелы. Правда, первый пробел на экране не отобразится и поэтому будет выведено -1.230.
    Применение дескриптора масштабирования kP оказывает следующие действия:

    при вводе дескрипторы kPFw.d означают, что после преобразования Fw.d введенное число будет умножено на 10
    -k
    ;

    при выводе с форматом kPFw.d выводимая величина прежде умножается на 10
    k
    , а затем выводится в соответствии с преобразованием Fw.d.
    Пример: write(*, '(5PF13.4)') -1.23
    ! -123000.0000 write(*, '(F13.4)') -1.23
    !
    -1.2300
    Если выводимое значение не может быть размещено в отведенном поле, то результатом вывода будут звездочки.
    1   ...   29   30   31   32   33   34   35   36   ...   49


    написать администратору сайта