Учебники

Фортран — Указатели

В большинстве языков программирования переменная-указатель хранит адрес памяти объекта. Однако в Fortran указатель — это объект данных, который имеет больше функциональных возможностей, чем просто сохранение адреса памяти. Он содержит больше информации о конкретном объекте, например, тип, ранг, экстенты и адрес памяти.

Указатель связан с целью путем выделения или назначения указателя.

Объявление переменной-указателя

Переменная указателя объявляется с атрибутом указателя.

В следующих примерах показано объявление переменных-указателей —

integer, pointer :: p1 ! pointer to integer  
real, pointer, dimension (:) :: pra ! pointer to 1-dim real array  
real, pointer, dimension (:,:) :: pra2 ! pointer to 2-dim real array

Указатель может указывать на —

  • Область динамически выделяемой памяти.

  • Объект данных того же типа, что и указатель, с целевым атрибутом.

Область динамически выделяемой памяти.

Объект данных того же типа, что и указатель, с целевым атрибутом.

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

Оператор allocate позволяет вам выделить место для объекта указателя. Например —

Live Demo

program pointerExample
implicit none

   integer, pointer :: p1
   allocate(p1)
   
   p1 = 1
   Print *, p1
   
   p1 = p1 + 4
   Print *, p1
   
end program pointerExample

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

1
5

Вы должны очистить выделенное пространство памяти с помощью оператора deallocate, когда оно больше не требуется, и избегать накопления неиспользуемого и неиспользуемого пространства памяти.

Цели и Ассоциация

Цель — это еще одна нормальная переменная, для которой выделено пространство. Целевая переменная должна быть объявлена ​​с целевым атрибутом.

Вы связываете переменную-указатель с целевой переменной, используя оператор связи (=>).

Давайте перепишем предыдущий пример, чтобы продемонстрировать концепцию —

Live Demo

program pointerExample
implicit none

   integer, pointer :: p1
   integer, target :: t1 
   
   p1=>t1
   p1 = 1
   
   Print *, p1
   Print *, t1
   
   p1 = p1 + 4
   
   Print *, p1
   Print *, t1
   
   t1 = 8
   
   Print *, p1
   Print *, t1
   
end program pointerExample

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

1
1
5
5
8
8

Указатель может быть —

  • Неопределенный
  • ассоциированный
  • диссоциированного

В приведенной выше программе мы связали указатель p1 с целью t1, используя оператор =>. Функция, связанная, проверяет статус ассоциации указателя.

Оператор nullify разъединяет указатель от цели.

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

Пример 1

Следующий пример демонстрирует понятия —

Live Demo

program pointerExample
implicit none

   integer, pointer :: p1
   integer, target :: t1 
   integer, target :: t2
   
   p1=>t1
   p1 = 1
   
   Print *, p1
   Print *, t1
   
   p1 = p1 + 4
   Print *, p1
   Print *, t1
   
   t1 = 8
   Print *, p1
   Print *, t1
   
   nullify(p1)
   Print *, t1
   
   p1=>t2
   Print *, associated(p1)
   Print*, associated(p1, t1)
   Print*, associated(p1, t2)
   
   !what is the value of p1 at present
   Print *, p1
   Print *, t2
   
   p1 = 10
   Print *, p1
   Print *, t2
   
end program pointerExample

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

1
1
5
5
8
8
8
T
F
T
0
0
10
10

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

Пример 2

Live Demo

program pointerExample
implicit none

   integer, pointer :: a, b
   integer, target :: t
   integer :: n
   
   t = 1
   a => t
   t = 2
   b => t
   n = a + b
   
   Print *, a, b, t, n 
   
end program pointerExample

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —