next up previous contents
След.: Упражнения Выше: Массивы Пред.: Упражнения   Содержание


Указатели

В современном Фортране имеется концепция указателя, ограниченная настолько, чтобы быть удобной для вычислительных целей и безопасной. Указатель -- это переменная, содержащая информацию о расположении в памяти другого объекта данных, с которым указатель связан. Объявляется указатель назначением атрибута POINTER. В Фортране связанный с объектом указатель является псевдонимом объекта: он может фигурировать в левой и правой части присваиваний, к нему может применяться индексация и секция массива и т.п.

Связь указателя с именованным объектом осуществляет оператор присвоения указателю =>. Указатель может быть связан с безымянным массивом, память под который будет выделена на этапе выполнения оператором ALLOCATE. В этом случае доступ к массиву возможен только через указатель (в том числе и другой, если он будет связан с этим объектом). Разрыв связи с именованным (а также и безымянным, но это чревато утечками памяти) объектом осуществляется при помощи оператора NULLIFY(P1[,...]) или путем связывания с результатом функции NULL. Освобождение памяти производит оператор DEALLOCATE. Подробнее операторы размещения и освобождения описаны в параграфе про размещаемые массивы.

Целью указателя может быть не всякий массив. Во-первых, тип и атрибут DIMENSION указателя определяют тип и ранг массива, который может быть целью (границы массива опускаются -- они определяются при связывании). Во-вторых, потенциальная цель должна быть объявлена с атрибутом TARGET -- в противном случае связь невозможна. Атрибут TARGET несовместим с атрибутом POINTER.

Отметим, что невозможно непрямую объявить массив указателей: атрибут DIMENSION и атрибут POINTER совместно определяют указатель на массив. Это ограничение можно обойти[3], определив производный тип с одним полем-указателем и массив этого типа.

В левой части оператора => -- указатель. Если справа тоже указатель, левая часть связывается с тем же объектом, который связан с указателем справа. Если справа объект, он связывается с указателем. Теперь указатель можно использовать вместо объекта в любой ситуации. Объекты в левой и правой частях оператора присваивания указателю должны быть одного типа (включая разновидность) и одного ранга.

Объекты при присваивании указателю не копируются. Если два указателя связаны с одним объектом, каждый может независимо быть связан с другим посредством оператора присваивания указателю или размещения. Однако уничтожение объекта через один указатель опасно, поскольку Стандарт не требует автоматически назначить другому указателю статус пустого.

В операторе присваивания указателю можно указывать нижние границы (верхние определяются исходя из конфигурации массива-цели). Возможно изменение конфигурации, если в правой части достаточно большой одномерный массив. Примеры [12]:

P(0:,0:) => A

P(1:M,1:2*M) => A(1:2*M*M)

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

REAL, DIMENSION(52), TARGET:: A

REAL, DIMENSION(:), POINTER:: P

...

P=>A

После этого P может быть использован как синоним A. Возможно даже связывание с секцией: P=>A(7:40), причем не обязательно непрерывной: P=>A(7:38:2)

Еще пример [2]:

REAL, TARGET, DIMENSION(M,N):: MATR

REAL, POINTER:: ROW(:), WINDOW(:,:)

ROW => MATR(M,:)

WINDOW => MATR(I-1:I+1,J-1:J+1)

Атрибут POINTER не совместим атрибутами TARGET и ALLOCATABLE.

Проверка статуса указателя возможна с помощью функции ASSOCIATED, принимающей один или два аргумента: первый, обязательный -- указатель, второй -- переменная или указатель. Если второй аргумент опущен, функция проверяет статус связанности указателя с чем бы то ни было; если указана переменная, проверяется наличие связи с нею; наконец, для указателя проверяется, одна ли у них цель. Результат -- логический.

Функция NULL() без аргументов возвращает неопределенный указатель (тип и ранг определяются из контекста) и служит для инициализации указателя (оператором =>). Если указан аргумент (указатель или размещаемый массив), возвращается неопределенный указатель того же типа и ранга, что и аргумент (он может быть не связан и не размещен).

Указатель не может быть связан с коиндексированным объектом, иными словами -- указывать на другой образ.

В Fortran-2003 введены указатели на процедуры. Они описаны в § 11 «Процедуры».

Указатель может иметь целью и скалярный объект -- это имеет смысл для производных типов (см. стр. [*]).



Подсекции

Ilya A. Chernov 2012-12-19
X