next up previous contents
След.: Оператор PROCEDURE и указатели Выше: Интерфейсы Пред.: Родовые интерфейсы и перегрузка   Содержание


Родовые интерфейсы и переопределение ввода/вывода

Переопределение операторов ввыода/вывода (точнее, чтения и записи) позволяет заменить ввод и вывод производных типов по умолчанию на свой. Оно осуществяется указанием READ(фмт) или WRITE(фмт), где фмт -- это FORMATTED или UNFORMATTED вместо родового имени. Соответственно, можно определить форматный и неформатный ввод и вывод.

Оператор ввода/вывода, вызывающий соответствующую пользовательскую процедуру, называется родительским. Процедура может (и это типично) сама вызывать операторы ввода и вывода, которые называются дочерними. Их выполнение дает тот же эффект, как если бы объект данных, вывод которого переопределен, был заменен на списки ввода/вывода дочерних операторов с соответствующими измененями форматирования. Переопределенный оператор может вызвать себя, если при выполнении дочернего оператора в его списке встретился объект производного типа. Такой ввод/вывод называется рекурсивным.

При выполнении дочернего оператора позиция в файле не меняется до передачи данных, а при неформатном вводе/выводе -- и после, а спецификатор ADVANCE игнорируется.

Все процедуры -- подпрограммы. Процедуры, реализующие форматный ввод, принимают шесть аргументов. Первый -- INTENT(INOUT) и производного типа; второй -- целочисленный, входящий -- номер устройства; третий -- символьный, перенимающий длину, входящий -- тип ввода; четвертый -- целочисленный одномерный массив, перенимающий конфигурацию, входящий -- список целых чисел, который может быть указан в дескрипторе DT § 10.2; пятый -- целый, исходящий, для кода возврата; шестой -- INTENT(INOUT), символьный, перенимающий длину -- для сообщения об ошибке.

Для форматного вывода аргументы те же, но первый -- входящий.

Для неформатного ввода аргументов четыре: объект данных производного типа, устройство, код возврата и сообщение об ошибке, с теми же атрибутами INTENT, что и в форматном случае.

Для неформатного вывода аргументы те же, но первый -- входящий.

Первый аргумент -- объект в списке ввода родительского оператора или значение объекта в списке вывода родительского оператора.

Если в родительском операторе указан номер устройства, он же передается в процедуру; если использовано устройство по умолчанию (символ * в качестве устройства, оператор PRINT или оператор READ в форме без устройства), передается номер устройства по умолчанию; в остальных случаях аргумент имеет отрицательное значение, зависящее от системы. Отрицательное значение возможно в случае внутреннего файла либо оно присвоено переменной, указанной спецификатором NEWUNIT; различить эти ситуации позволяет оператор INQUIRE спецификатор IOSTAT которого указывает переменную, которой в случае внутреннего файла присваивается значение IOSTAT_INQUIRE_INTERNAL_UNIT встроеннго модуля ISO_FORTRAN_ENV.

Аргумент, указывающий тип форматного ввода/вывода, может иметь одно из трех значений: 'LISTDIRECTED' в случае, если родительский оператор использует формат по умолчанию, 'NAMELIST', если используется именованный список, и 'DT' с присоединенной строкой, которая указана в соответствущем спецификаторе. Последовательность целых чисел, которая может быть также указана, передается в четвертом аргументе (в противном случае он имеет нулевой размер).

Коду возврата должно присваиваться нулевое знаение при успехе, положительное -- в случае ошибок, и значения констант IOSTAT_END и IOSTAT_EOR в случае обнаружения ситуаций «конец файла» и «конец записи». Если присваивается ненулевое значение, процедура должна разместить сообщеие об ошибке в последнем аргументе. Если значение нулевое, аргумент не должен изменяться.

Не допускается чтение и записьа в другие устройства, а также чтение из устройства, если родительский оператор -- записи, и наоборот. Однако допускается чтение и запись во внутренние файлы. Операторы OPEN, CLOSE, BACKSPACE, ENDFILE и REWIND не должны выполняться.

Надежная процедура ввода/вывода использует оператор запроса INQUIRE для определения режима ввода или вывода.

Ни родительский, ни дочерний операторы не должны быть асинхронными.

Внутри процедуры нельзя менять ничего, относящегося к текущему вводу/выводу, кроме объекта -- первого аргумента.

Процедура, релизующая пользовательский ввод или вывод, вызывается в случае неформатного ввода или вывода объекта производного типа или форматного под управлением дескриптора DT, формата по умолчанию или под управлением именованного списка.



Ilya A. Chernov 2012-12-19
X