2
GEO764 - Programação
avançada em Geofísica
Argumento mudo tipo conjunto
] Dois tipos de conjunto podem ser usados como
argumento mudo.
] Forma explícita: todos limites especificados.
REAL, DIMENSION(8,8), INTENT(IN)::f_expl
O argumento efetivo associado deve ser similar em
tamanho e forma.
] Forma assumida: nenhum limite é especificado. Eles são
herdados do argumento efetivo.
REAL, DIMENSION(:,:), INTENT(IN)::f_as
Uma interface explícita deve ser fornecida.
] O argumento mudo não pode ser ALLOCATABLE.
FORTRAN 90: Aula no 5
Procedimentos
(continuação)
março de 07
Hédison K. Sato
Conjunto explícito como
argumento
O argumento efetivo e o mudo têm formas e tamanhos similares.
PROGRAM Main
IMPLICIT NONE
INTEGER, DIMENSION(8,8) :: A1
INTEGER, DIMENSION(64)
:: A2
INTEGER, DIMENSION(16,32):: A3
...
CALL subby(A1)
! Certo
CALL subby(A2)
! Errado
CALL subby(A3(::2,::4))
! Certo
CALL subby(RESHAPE(A2,(/8,8/)))
! Certo
...
CONTAINS
SUBROUTINE subby(f_expl)
INTEGER, DIMENSION(8,8), INTENT(IN):: f_expl
...
END SUBROUTINE subby
END PROGRAM Main
3
Conjunto como argumento
mudo de forma assumida
PROGRAM Main
IMPLICIT NONE
INTEGER, DIMENSION(40)
:: X
INTEGER, DIMENSION(40,40)
:: Y
...
CALL jogos(X, Y)
CALL jogos(X(1:39:2), Y(2:4,4:4))
CALL jogos(X(1:39:2), Y(2:4,4))
...
CONTAINS
SUBROUTINE jogos(a, b)
REAL, INTENT(IN):: a(:), b(:,:)
...
END SUBROUTINE jogos
END PROGRAM Main
! Inválido
] O argumento efetivo não deve estar vetorialmente subscrito, nem
ser um conjunto de tamanho assumido.
] No procedimento, o limite inferior inicia em 1.
4
5
Conjuntos automáticos
Conjuntos automáticos
] Conjuntos que dependem de argumentos mudos,
denominados conjuntos automáticos,
PROGRAM Main
SIZE e argumentos
IMPLICIT NONE
mudos podem ser
INTEGER :: IX(10,20), IY(3,7)
usados para declarar
...
conjuntos automáticos
CALL une_bus_riot(IX,2,3)
CALL une_bus_riot(IY,7,2)
A1 e A2 podem ter
CONTAINS
diferentes tamanhos
SUBROUTINE une_bus_riot(A,M,N)
em chamadas distintas.
INTEGER, INTENT(IN):: M,N
INTEGER, INTENT(INOUT):: A(:,:)
! Assumido
REAL:: A1(M,N), A2(SIZE(A,1),SIZE(A,2)) ! AUTO
...
END SUBROUTINE une_bus_riot
END PROGRAM Main
\ seus tamanhos são determinados pelos argumentos mudos, e
\ eles não podem ter o atributo SAVE, nem ser iniciados.
7
Atributo SAVE e conjuntos
SUBROUTINE sub1(dim)
REAL,ALLOCATABLE,DIMENSION(:,:),SAVE:: X
INTEGER, INTENT(in)
::dim
REAL,DIMENSION(dim)
:: Y
...
IF(.NOT.ALLOCATED(X)) ALLOCATE(X(20,20))
] Como X tem o atributo SAVE, ele irá reter sua marca de
alocado entre as chamadas, caso contrário, ele
desapareceria.
] Como Y depende de argumento mudo, ele não pode ter
o atributo SAVE.
6
Argumento mudo tipo caracter8
de comprimento explícito
] Neste caso, ele deve, em ordem e variedade, concordar
com o argumento efetivo. Todavia, pode ser mais curto.
\ PROGRAM Main
IMPLICIT NONE
CHARACTER(LEN=3), DIMENSION(10):: word
...
CALL char_example(word(3), word(6:))
CONTAINS
SUBROUTINE char_example(wird, werds)
CHARACTER(LEN=10) :: wird
CHARACTER(LEN=10) :: werds(:)
...
END SUBROUTINE char_example
END PROGRAM Main
Argumento mudo tipo caracter9
de comprimento assumido
] O argumento mudo caracter pode herdar seu
comprimento do argumento efetivo.
] A variedade e ordem precisam, ainda, coincidir.
10
Função retornando conjunto
] Funções podem devolver um conjunto.
\ PROGRAM Main
IMPLICIT NONE
INTEGER, PARAMETER
:: m=6
INTEGER, DIMENSION(m,m) :: im1, im2
...
im2=fun(im1,1)
DIMENSION não pode
CONTAINS
aparecer junto a “function”
FUNCTION fun(ima,scal)
INTEGER, INTENT(IN)
:: scal, ima(:,:)
INTEGER,
DIMENSION(SIZE(ima,1),SIZE(IMA,2))::fun
fun=ima*scal
END FUNCTION fun
END PROGRAM Main
\ PROGRAM Main
IMPLICIT NONE
CHARACTER(LEN=10):: var1
CHARACTER(LEN=20):: var2
CALL char_lady(var1); CALL char_lady(var2)
CONTAINS
SUBROUTINE char_lady(word)
CHARACTER(LEN=*), INTENT(IN):: word
...
PRINT*,”Comprimento do arg. e’”, LEN(word)
END SUBROUTINE char_lady
END PROGRAM Main
11
Função tipo caracter
] Pode retornar uma cadeia caracter.
\ FUNCTION reverse(word)
CHARACTER(LEN=*), INTENT(IN):: word
CHARACTER(LEN=LEN(word))
:: reverse
INTEGER
:: lw
lw=LEN(word)
DO i=1,lw
reverse(lw+1-i:lw+1-i)=word(i:i)
END DO
END FUNCTION reverse
] O comprimento da função é determinada por um
argumento mudo.
12
Função com efeito colateral
] Considerando
INTEGER FUNCTION itera1(a,b)
...
a=a*a
! modificação do argumento
itera1=a/b
e
INTEGER FUNCTION itera2(a,b)
...
a=a*2
! modificação do argumento
itera2=a/b
13
Procedimentos recursivos
14
Exemplo de função recursiva
] O procedimento recursivo pode chamar a si próprio,
tanto direta como indiretamente.
] É uma técnica que produz soluções elegantes.
] Pode incorrer em certa sobrecarga computacional.
] A recursividade deve ser explicitamente declarada.
] A declaração da função precisa conter a palavra-chave
RESULT, e a declaração de tipo, se houver, se referirá
tanto ao nome da função, como a variável contendo o
resultado.
] Cálculo do fatorial usando n! = n ( n - 1)!
\ PROGRAM Main
IMPLICIT NONE
PRINT*, fact(12)
CONTAINS
RECURSIVE FUNCTION fact(n) RESULT(n_fact)
INTEGER, INTENT(IN)
:: n
INTEGER :: n_fact ! também define fact
IF(n > 0)THEN;
n_fact=n*fact(n-1)
ELSE;
n_fact=1
END IF
END FUNCTION fact
END PROGRAM Main
15
Simulação de uma pilha
16
Implementação de uma pilha
2
push(2)
2
push(6)
6
push(1)
2
1
6
2
Pos
2 6
Pos
1
1
6
2
pop
6
2
6
pop
2
2 6 1
push(6)
Pos
2 6 1
2 6
Pos
Pos
2
pop
push(2)
Pos
push(1)
pop
2
Pos
pop
Pos
pop
O topo da pilha é marcado pela seta. O dado entra à sua direita. No “pop”,
sai o dado localizado à sua esquerda.
17
Programa sobre pilha: exemplo
18
Módulos: reutilização
] A conversão em MODULE permite seu uso em qualquer
lugar. Isto denomina-se encapsulamento.
PROGRAM pilha
INTEGER, PARAMETER:: size=100
INTEGER SAVE:: store(size), pos=0
...
CONTAINS
SUBROUTINE push(i)
INTEGER, INTENT(IN)
:: i
IF(pos<size) THEN; pos=pos+1; store(pos)=i
ELSE; STOP ’Erro: pilha cheia’; END IF
END SUBROUTINE push
SUBROUTINE pop(i)
INTEGER, INTENT(OUT) :: i
IF(pos>0) THEN; i=store(pos); pos=pos-1
ELSE; STOP ’Erro: pilha vazia’;
END IF
END SUBROUTINE pop
END PROGRAM pilha
\ MODULE stack
IMPLICIT NONE
INTEGER, PARAMETER:: size=100
INTEGER SAVE:: store(size), pos=0
CONTAINS
SUBROUTINE push(i)
......
END SUBROUTINE push
SUBROUTINE pop(i)
......
END SUBROUTINE pop
END MODULE stack
19
Módulos: reutilização
] A pilha pode, agora, ser acessada por outros programas.
O comando USE o anexa ao programa.
\ PROGRAM Uso_do_Stack
USE stack
IMPLICIT NONE
...
CALL push(14); CALL push(21)
CALL pop(i); CALL pop(j)
...
END PROGRAM Uso_do_Stack
20
Reutilização - Módulo II
] Pontos levantados no “slide” anterior:
\ Dentro de um módulo, funções e subrotinas denominam-se
procedimentos módulo.
\ Procedimentos módulo podem conter procedimentos internos
(como PROGRAMs)
\ Objetos em módulo que retenham seus valores devem ter o
atributo SAVE.
\ Módulos podem também ser usados (USE) por procedimentos e
outros módulos.
\ Módulos podem ser compilados separadamente, mas antes do
programa que os utiliza.
21
Restringindo a visibilidade
22
Restringindo a visibilidade
] No exemplo da pilha, o programa principal tem acesso a
store e pos e, assim, pode modificá-los. Isto é
perigoso. Os atributos de visibilidade podem ser
controlados.
PRIVATE :: pos, store, size ! invisível
PUBLIC :: pop, push
! visível
] Alternativamente, a questão da visibilidade pode ser
feita com um comando ou atributo:
PUBLIC
! visível como regra geral
INTEGER, PRIVATE, SAVE:: store(size),pos
INTEGER, PRIVATE, PARAMETER:: size=100
Assim, no programa principal:
CALL push(21)
! OK
CALL pop(i)
! OK
pos=23
! proibido
store(pos)=99
! proibido
] Este atributo torna o módulo mais seguro e permite que
os elementos internos do módulo sejam alterados sem
modificar o programa do usuário.
23
Facilidade renomear no USE
] O comando USE atribui nomes a objetos de um módulo
cujas definições públicas estejam acessíveis. Sintaxe:
USE <nome_do_módulo> &
[,<novo_nome> => <nome_usado>...]
] Exemplo:
USE stack, integer_pop => pop
O objeto pop passa a ter integer_pop como nome.
24
Comando USE ONLY
] Outra forma de se evitar o choque de nomes, é usar
somente os objetos necessários. Sintaxe:
USE <nome_do_módulo> [, ONLY: <lista>...]
a <lista> também pode conter troca de nome (=>)
] Exemplo:
USE stack, ONLY:pos, integer_pop => pop
Somente pos e pop passam a ser acessíveis.
pop passa a ter integer_pop como nome.
O comando ONLY dá ao compilador a opção de incluir
somente as entidades requisitadas.
25
Módulo: Forma geral
Módulos: uma perspectiva
] A unidade de programa MODULE facilita:
MODULE modulo
! Definição de tipos, dados globais, ...
CONTAINS
SUBROUTINE sub(...)
! comandos executáveis
CONTAINS
SUBROUTINE int1(...); ...; END SUBROUTINE
SUBROUTINE int2(...); ...; END SUBROUTINE
END SUBROUTINE sub
FUNCTION fun(...)
! comandos executáveis
CONTAINS
! etc
END FUNCTION fun
END MODULE modulo
\ A declaração de objetos globais.
\ A declaração de procedimentos, incluindo as definições de
operadores.
\ A extensão semântica.
\ O controle do acesso às características acima referidas, por
diferentes programas ou unidades de programa.
\ O empacotamento de conjuntos completos.
27
FIM
] Fazer os exercícios.
26
Download

Procedimentos (continuação) - CPGG-UFBA