Apontadores e tipos derivados - CPGG-UFBA

Transcrição

Apontadores e tipos derivados - CPGG-UFBA
2
GEO764 - Programação
avançada em Geofísica
Variável e apontador
] Em programação, variável é um símbolo, formado por
letras e mais alguns caracteres, ao qual se associa um
endereço de memória.
\ Normalmente, é irrelevante o número do endereço associado.
\ Conjunto é uma forma ordenada para se promover a associação
e envolve vários dados do mesmo tipo (inteiros, real, etc.)
\ Nos dois casos, o espaço endereçado é preenchido com dados,
obedecendo-se o tipo de dado representado pelo símbolo
FORTRAN 90: Aula no 6
Apontadores e Tipos Derivados
] O apontador é um símbolo cujo endereço associado
pode ser alterado no programa.
mar-07
Hédison K. Sato
3
Apontador e alvo
Terminologia
] Assim, alternativamente, o “apontador” pode indicar
endereços distintos aos quais já existem símbolos
associados (Alvo1, Alvo2, Alvo3).
apontador
4
Alvo1
Alvo2
Alvo3
] Estados de um apontador
\ Associado, desassociado ou indefinido (o estado inicial do
apontador).
apontador
Associado
Desassociado
Indefinido
] O apontador utiliza menos espaço que o alvo.
] Em geral, uma referência ao apontador será uma
referência ao alvo.
alvo
Nulo
????
] A função intrínseca ASSOCIATED obtém o estado de
associação de um apontador.
5
Declaração de um apontador
6
Declaração de um apontador
] Um APONTADOR é uma variável com o atributo
POINTER,
] Como variável, a sua declaração define o seu tipo
estático, variedade e ordem. Por exemplo,
REAL, POINTER:: ptor
REAL, DIMENSION(:,:), POINTER:: ptoa
] Sendo assim, a sua declaração também determina e fixa
o tipo, variedade e ordem do alvo,
] Os apontadores de conjunto são declarados com a
especificação “de forma a determinar”,
\ A ordem de um alvo é fixada mas a forma pode variar.
\ ptor é um apontador para um alvo real escalar,
\ ptoa é um apontador para um conjunto 2D de reais.
7
Declaração do alvo
] Os alvos de um apontador devem ter o atributo
TARGET.
REAL, TARGET:: x, y
REAL, DIMENSION(5,3), TARGET:: a,b
REAL, DIMENSION(3,5), TARGET:: c
] Com essas declarações (e do penúltimo slide)
REAL, POINTER:: ptor
REAL, DIMENSION(:,:), POINTER: ptoa
\ x ou y podem ser associados a ptor,
\ enquanto a, b e c, a ptoa
8
Manipulação do apontador
Os seguintes operadores se aplicam aos apontadores:
] => atribuição de apontador: associa um apontador
com um determinado alvo.
] = atribuição usual: atribui um valor ao espaço
apontado pelo apontador.
] A atribuição de apontador faz o espaço do apontador ser
o mesmo do referenciado pela variável, enquanto que a
atribuição normal altera o valor contido naquele espaço
(indicado pelo apontador).
9
Atribuição com apontador
Associação com conjuntos
] Considerando
x = 3.141592654
ptor => y
ptor = x
3.141592654 x
ptor
3.141592654 y
x e ptor têm o mesmo valor
ptor é um apelido de y de forma que o último
comando faz y=3.141592654
se, posteriormente, o valor de x for alterado, os
valores de ptor e y não serão.
O código ptor=5.0 faz o valor de y igual a 5.0
Associação com conjuntos
(cont.)
] Supondo
REAL, DIMENSION(:,:), POINTER: ptoa
REAL, DIMENSION(5,3), TARGET:: a
\ São inválidas (ordem errada)
ptoa => a(1:1,2)
ptoa => a(1,2)
ptoa => a(1,2:2)
\ também é inválido (subscrito vetor)
v = (/2,3,2,1/)
ptoa => a(v,v)
10
] Um apontador de conjunto pode ser associado a uma
seção regular de um alvo de ordem compatível (tipo e
variedade também). Entretanto, ele não pode ser
associado com uma seção de conjunto subscrita de
forma vetorial. Assim, se
] REAL, DIMENSION(:,:), POINTER: ptoa
REAL, DIMENSION(5,3), TARGET:: a
] são válidos (seções 2D)
ptoa => a(3:5,::2)
ptoa => a(1:1,2:2)
11
Apontador de seção:
visualização
ptoa => a(3::2,::2)
ptoa(1,1)
a(3,1)
ptoa(2,1)
a(5,1)
ptoa(1,2)
a(3,3)
ptoa(2,2)
a(5,3)
12
13
Alvos dinâmicos
14
Atribuição automática
] Os alvos podem ser criados por alocação dinâmica. A
função intrínseca ALLOCATE pode abrir um espaço na
forma de alvo de um apontador.
] Alocando um simples real como alvo de ptor.
ALLOCATE(ptor, STAT=ierr)
] As variáveis apontadoras têm, implicitamente, o atributo
TARGET.
ptoa => a(3::2,1::2)
ptor => ptoa(2,1)
ptoa(1,1)
] Alocando um conjunto real de ordem 2 como alvo de
ptoa.
ALLOCATE(ptoa(n*n,2*k-1), STAT=ierr)
Quando uma nova associação é
estabelecida, qualquer associação
prévia é desfeita.
] Mesmo estando associado, um apontador de conjunto
pode ser alocado.
ptor
15
Status da associação
] O status de um apontador definido pode ser testado
com a função intrínseca:
ASSOCIATED(ptoa)
Se ptoa estiver definido e associado, então o valor será
.TRUE.; se estiver definido e desassociado, .FALSE..
Se estiver indefinido, o resultado também é indefinido.
] O alvo de um apontador definido pode ser testado:
ASSOCIATED(ptoa,arr)
Se ptoa estiver definido e associado a arr, a função
retorna .TRUE.; caso contrário, .FALSE..
16
Desassociação do apontador
Os apontadores desassociam-se de seus alvos por:
] anulação
NULIFY(ptor)
\ interrompe a conexão do apontador com o alvo.
\ desassocia o apontador.
\ é conveniente anular o apontador antes do uso.
] de-alocação
DEALLOCATE(ptoa, STAT=ierro)
\ mesmos efeitos de interrupção e desassociação.
17
Apontadores de conjuntos
versus conjuntos a-ser-alocado
] Existem diferenças sutis entre um apontador de
conjunto e um conjunto a-ser-alocado:
18
Exemplo
] Apontadores são úteis em problemas iterativos. Assim,
considere os seguintes passos:
\ O conjunto a-ser-alocado é mais eficiente.
\ O conjunto alvo pode ser referenciado por meio de diferentes
nomes.
\ O conjunto a-ser-alocado, mas presentemente de-alocado, não
pode ser um argumento efetivo, enquanto que um apontador
desassociado pode ser.
\ Em resumo, o conjunto a-ser-alocado é mais eficiente mas os
apontados são mais flexíveis.
\ estimativa da solução desejada;
\ use a estimativa como entrada de uma equação para produzir
uma aproximação melhorada;
\ use esta aproximação para obter uma aproximação melhorada,
e
\ repita até que um determinado número de vezes.
19
Exemplo (cont.)
! Raiz quadrada de um vetor
integer::i
real,target,dimension(3):: a, b, N=(/4,9,25/)
real, pointer, dimension(:):: antes, depois, temp
a=1;
antes=>a ; depois=>b
do i=1,10
depois=(n/antes+antes)/2
temp=>depois; depois=>antes; antes=>temp
enddo
print *, n, depois
end
Os apontadores evitam a cópia de grandes matrizes!
20
Apontadores e procedimentos
Nas subrotinas e funções, o argumento efetivo do tipo
apontador pode ser entendido de duas formas.
] Após de-referenciado, passa o alvo:
o argumento mudo não tem o atributo POINTER.
] Passa o apontador de forma que ele possa ser
manipulado como tal no procedimento:
o argumento mudo tem o atributo POINTER.
21
Apontadores e procedimentos
PROGRAM sup
IMPLICIT NONE
INTEGER, POINTER:: pint1, pint2
...
CALL beer(pint1, pint2)
...
CONTAINS
SUBROUTINE beer(arg1, arg2)
INTEGER, POINTER:: arg1
Um argumento mudo
INTEGER, INTENT(IN):: arg2 apontador não pode ter
...
o atributo INTENT.
END SUBROUTINE beer
Exige-se uma interface
END PROGRAM sup
explícita quando o
apontador é usado com
um argumento efetivo.
22
Função tipo apontador
PROGRAM main
IMPLICIT NONE
INTEGER, TARGET:: a, b
INTEGER, POINTER:: maior
a=...; b=...
maior => ptr()
PRINT*, maior
CONTAINS
FUNCTION ptr()
INTEGER, POINTER:: ptr
IF(a.GT.B) THEN; ptr => a; ELSE
ptr => b ; END IF
END FUNCTION ptr
END PROGRAM main
23
Apontador de E/S
Os apontadores colocados na lista de E/S:
] sempre são de-referenciados,
] não podem estar desassociados, assim como a dereferência não tem sentido.
\ PROGRAM main
IMPLICIT NONE
REAL, DIMENSION(3), TARGET:: arr=/(1.,2.,3./)
REAL, DIMENSION(:), POINTER:: p, q
p => arr;
PRINT*, p
ALLOCATE(q(5));
READ*, q; PRINT*, q
DEALLOCATE(q)
PRINT*, q
! inválido, nenhum alvo válido
END PROGRAM main
24
Tipos derivados
] Com freqüência, é vantajoso expressar algum objeto em
forma de estrutura agregada, por exemplo: coordenadas
(x, y, z).
] O Fortran 90 permite entidades compostas ou tipos
derivados
TYPE coords_3d
REAL:: x, y, z
END TYPE coords_3d
TYPE (coords_3d):: PONTO1, PONTO2
] A definição de tipos derivados devem ser colocadas em
um MODULE
25
Super tipos
26
Atribuição com tipos derivados
] Tipos pré-definidos podem ser utilizados como
componentes de outros tipos derivados.
TYPE esfera
TYPE (coords_3d) :: centro
REAL
:: raio
END TYPE esfera
] São duas maneiras de se atribuir valores a objetos de
tipos derivados
\ componente a componente,
\ como um objeto.
] Componente a componente, este é selecionado através
do caracter %
ponto1%x =1.0
bolha%raio = 3.0
bolha%centro%x = 1.0
] Desta maneira, objetos do tipo esfera podem ser
declarados
TYPE (esfera) :: bolha, bola
27
Atribuição com tipos derivados
] O objeto como um todo pode ser selecionado e atribuído
usando-se um construtor.
ponto1 = coords_3d(1., 2., 3.)
bolha%centro = coords_3d(4.,5.,6.)
bolha = esfera(bolha%centro, 10.)
bolha = esfera(coords_3d(4.,5.,6.), 10.)
] A atribuição entre dois objetos de mesmo tipo derivado
está inerentemente definida. Assim, é válido
bola=bolha
28
Conjuntos e tipos derivados
] É possível definir objetos de tipos derivados os quais
contêm conjuntos não alocáveis e conjuntos de objetos
de tipos derivados. Considerando
TYPE flobble
CHARACTER(LEN=6)
:: nome
INTEGER, DIMENSION(10,10)
:: harry
END TYPE flobble
TYPE (flobble)
:: bill
TYPE (flobble), DIMENSION(10) :: ben
29
Conjuntos e tipos derivados
30
E/S com tipos derivados
] É possível referir-se a um elemento ou subseção do
conjunto componente
bill%harry(7,7)
bill%harry(:,::2)
ben(1)%harry(7,7)
ben(9)%harry(:,:)
ben(:)%harry(7,7)
] E/S com tipos derivados, que não contenham
apontadores, podem ser feitos por meio de métodos
usuais.
PRINT*, bolha
é exatamente igual a
PRINT*, bolha%centro%x, bolha%centro%y, &
bolha%centro%z, bolha%raio
] mas não uma coleção de elementos ou subseções do
conjunto componente
ben(9:9)%harry(:,:) ! inválido
ben(:)%harry(:,::2) ! inválido
] Tipos derivados são manipulados à base dos
componentes.
Tipos derivados e
procedimentos
31
] Definições de tipos derivados devem ser empacotados em um
MODULE
MODULE VecDef
TYPE vec; REAL:: r, theta; END TYPE vec
END MODULE VecDef
] Uso do módulo para tornar visível o tipo definido
PROGRAM Up
USE VecDef
IMPLICIT NONE
TYPE (vec):: north
CALL Sub(north)
...
] Definição de tipos são
acessíveis, apenas, por
associação com
o hospedeiro ou USE.
CONTAINS
SUBROUTINE Sub(arg)
TYPE (vec), INTENT(IN):: arg
...
END SUBROUTINE Sub
END PROGRAM Up
32
Função de tipo derivado
] A função pode voltar um resultado de tipo derivado
arbitrário.
FUNCTION Poo(kanga, roo)
USE VecDef
TYPE (vec):: Poo
TYPE (vec), INTENT(IN):: kanga, roo
Poo = ...
END FUNCTION Poo
] Lembrar que a definição de VecDef precisa estar
acessível por associação com o hospedeiro ou USE.
33
FIM
] Fazer os exercícios.

Documentos relacionados