Fortran - Ponteiros

Na maioria das linguagens de programação, uma variável de ponteiro armazena o endereço de memória de um objeto. No entanto, em Fortran, um ponteiro é um objeto de dados que possui mais funcionalidades do que apenas armazenar o endereço da memória. Ele contém mais informações sobre um determinado objeto, como tipo, classificação, extensões e endereço de memória.

Um ponteiro é associado a um destino por alocação ou atribuição de ponteiro.

Declaração de uma variável de ponteiro

Uma variável de ponteiro é declarada com o atributo ponteiro.

Os exemplos a seguir mostram a declaração de variáveis ​​de ponteiro -

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

Um ponteiro pode apontar para -

  • Uma área de memória alocada dinamicamente.

  • Um objeto de dados do mesmo tipo do ponteiro, com o target atributo.

Alocando espaço para um ponteiro

o allocateinstrução permite que você aloque espaço para um objeto de ponteiro. Por exemplo -

program pointerExample
implicit none

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

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

1
5

Você deve esvaziar o espaço de armazenamento alocado pelo deallocate declaração quando não é mais necessária e evita o acúmulo de espaço de memória não utilizado e inutilizável.

Metas e associação

Um alvo é outra variável normal, com espaço reservado para ele. Uma variável de destino deve ser declarada com otarget atributo.

Você associa uma variável de ponteiro a uma variável de destino usando o operador de associação (=>).

Vamos reescrever o exemplo anterior, para demonstrar o conceito -

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

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

1
1
5
5
8
8

Um ponteiro pode ser -

  • Undefined
  • Associated
  • Disassociated

No programa acima, temos associatedo ponteiro p1, com o alvo t1, usando o operador =>. A função associada testa o status de associação de um ponteiro.

o nullify declaração desassocia um ponteiro de um destino.

Nullify não esvazia os alvos, pois pode haver mais de um ponteiro apontando para o mesmo alvo. No entanto, esvaziar o ponteiro implica também na anulação.

Exemplo 1

O exemplo a seguir demonstra os conceitos -

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

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

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

Observe que cada vez que você executa o código, os endereços de memória serão diferentes.

Exemplo 2

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

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

2  2  2  4