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.