A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

CPC782 Fundamentos de Programação Introdução ao Fortran aula 3/3 Renato N. Elias / Marcos A. D. Martins material.

Apresentações semelhantes


Apresentação em tema: "CPC782 Fundamentos de Programação Introdução ao Fortran aula 3/3 Renato N. Elias / Marcos A. D. Martins material."— Transcrição da apresentação:

1 CPC782 Fundamentos de Programação Introdução ao Fortran aula 3/3 Renato N. Elias / Marcos A. D. Martins http://www.nacad.ufrj.br/~rnelias/fortran material disponível em: http://www.nacad.ufrj.br/~rnelias/fortran

2 Aula 3  Alocação dinâmica de memória –ALLOCATABLE, ALLOCATE, DEALLOCATE e ALLOCATED  Ponteiros em Fortran90  Subprogramação –SUBROUTINE, FUNCTION –RECURSIVE, PURE, ELEMENTAL  Passagem de argumentos para subprogramas –Formas tradicionais –MODULE

3 Exercício proposto  Fazer um programa que calcule as coordenadas dos nós de uma grade e grave as coordenadas obtidas em um arquivo de texto.  O programa deverá conter as seguintes linhas iniciais: program Grade real*8, parameter :: xmin = 0.d0, & ymin = 0.d0, & xmax = 10.d0, & ymax = 10.d0, & dx = 2.d0, & dy = 2.d0 real*8, allocatable :: xyz(:,:) ! Desenvolva o algoritmo aqui End program

4 Alocação Dinâmica de Memória  A alocação dinâmica de memória foi um grande avanço no Fortran a partir do padrão Fortran90 pois permitiu um uso mais racional da memória do sistema;  A alocação dinâmica de memória permite ao programador decidir pela requisição de uma quantidade de memória para uso em arrays somente quando esta se faz, realmente, necessária;  Tal recurso também viabilizou a compilação e execução de programas; que antes se utilizavam de alocação estática e que não eram viáveis devido ao excessivo consumo de memória; em computadores com disponibilidade de recursos limitado;  A tarefa de gerenciamento de memória em Fortran77 era árdua e normalmente feita através da manipulação explícita de grandes áreas de memória estaticamente alocadas. Tais áreas eram mutuamente utilizadas por arrays de tipos distintos e frequentemente era necessária alguma operação de manutenção dos espaços vazios deixados. Além disso, o programador tinha de se certificar que a alocação estática assumida era suficiente para o programa rodar.  Uma outra limitação da alocação estática era a necessidade de recompilação do programa a cada vez que a quantidade de memória requerida fosse diferente daquela existente no programa. Isso pode parecer algo simples para programas caseiros, mas imaginem um programa comercial tendo que ser recompilado simplesmente porque necessitou de mais memória.

5 Alocação Dinâmica de Memória - Curiosidades  Quanto representa a memória do computador para um programa? Para respondermos a essa pergunta, vamos fazer algumas considerações: –Suponha um computador com 1Gb de memória e que 100% desta memória estará disponível para o nosso programa. –Suponha também que o programa só utilizará números reais de precisão dupla, então: 1 GBytes = 1024 MBytes = 1024 2 KBytes = 1024 3 Bytes se 1 número real de dupla precisão consome 16 bytes, então: 1024 3 /16 = 67108864 números reais de precisão dupla Parece muito... mas o quanto isso equivale em relação a um array quadrado? 67108864 1/2 = 8192 CONCLUSÃO: O tamanho máximo do array, neste caso, seria: real*8, dimension(8192,8192) :: array  Obviamente que nosso programa não terá 100% da memória disponível  É óbvio também que a alocação dinâmica não soluciona esse problema, mas ajuda a amenizá-lo, pois a memória pode ser alocada e desalocada de acordo com a necessidade do programa;

6 Alocação dinâmica e seus comandos  Os comandos associados a alocação dinâmica de memória em Fortran90 são: –allocatable : específica que um array pode ser dinamicamente alocado durante a execução do programa; –allocate : comando utilizado no ato de alocação de memória; –deallocate : comando utilizado para desalocar, e consequentemente, devolver a memória para o sistema; –allocated : verifica se um array está alocado ou não

7 Declarando arrays alocáveis  ALLOCATABLE : O comando allocatable é usado na declaração de um array para designar que o mesmo poderá ser dinâmicamente alocado durante a execução do programa. ! Forma 1: shape no nome da variavel real*8, allocatable :: arr1(:,:) ! Forma 2: shape no comando dimension real*8, allocatable, dimension(:,:) :: arr1 ! A forma 2 é útil quando se deseja declarar ! vários arrays alocáveis com o mesmo shape

8 Alocando arrays alocáveis  ALLOCATE : O comando allocate efetivamente faz a requisição de memória do sistema para que possa ser usada pelo array.  Forma geral: allocate(, stat= ) : um ou mais arrays que se deseja alocar juntamente com o tamanho do array. (OPCIONAL): Inteiro que retorna o valor 0 se o array for alocado com sucesso e maior que zero em caso de erro ! Exemplo: alocando 3 vetores real*8, allocatable :: a(:), b(:), c(:) n = 1000 allocate(a(n),b(n),c(n),stat=ierr) if (ierr.ne.0) print *, ‘Erro ‘, ierr, ‘ na alocacao de memoria’

9 Alocando arrays alocáveis  Outros exemplos: real*8, allocatable, dimension(:) :: arr1, arr2, arr3, arr4, arr5 print *, ‘ Entre com o tamanho do vetor arr1:’ read(*,*) n allocate(arr1(n)) ! A partir desse ponto o vetor arr1 pode ser usado ! alocacao com tamanho explicito allocate(arr2(1000)) ! alocacao com indice inicial diferente de 1 allocate(arr3(-100:100)) ! alocacao com verificacao allocate(arr4(10),stat=i) if (i.ne.0) print *, ‘ Algum problema ocorreu...’ ! alocacao de array nulo. allocate(arr5(0))

10 Desalocando arrays previamente alocados  DEALLOCATE : O comando Deallocate devolve a memória utilizada por um array desalocando-o da memória.  Forma geral: deallocate(, stat= ) : um ou mais arrays que se deseja alocar (OPCIONAL): Inteiro que retorna o valor 0 se o array for alocado com sucesso e maior que zero em caso de erro ! Exemplo: desalocando 3 vetores simultaneamente deallocate(a,b,c,stat=ierr) if (ierr.eq.0) ‘ Arrays desalocados com sucesso...’

11 Verificando se um array está alocado  ALLOCATED : O comando allocated é utilizado para verificar o status de alocação de um array e é normalmente utilizado em associação com o comando allocate. O comando retorna.true. caso o array esteja alocado e.false. caso contário.  Forma geral: allocated( ) ! verifica se a matriz já esta ALOCADA para não alocá-la novamente if (.not.allocated(arr1)) allocate(arr1(-10:10)) ! Só DESALOCA a matriz arr1 caso ela esteja ALOCADA if (allocate(arr1)) deallocate(arr1)

12 Programa-exemplo  Ler os dados do seguinte arquivo e armazená-los em um array devidamente alocado: arquivo dados.txt 10 3 -3.13-8.31 0.25 -7.32-4.43 9.86 -7.44 1.65 3.53 -6.35 9.87 4.24 1.56-5.45 2.84 -0.54-3.67 5.73 7.05-9.53-5.25 -1.80-1.82 3.38 8.98 6.84 9.96 6.57-2.82-0.84 program MemoryAllocation real*4, allocatable :: a(:,:) open(9,file="dados.txt") read(9,*) n1, n2 if (.not.allocated(a)) then allocate(a(n1,n2)) endif do i=1,n1 read (9,*) (a(i,j),j=1,n2) write(*,*) (a(i,j),j=1,n2) enddo close(9) end program 1-Alocacao

13 Alocação dinâmica (Resumo) Program AlocacaoDeMemoria ! Declara os arrays i1 e i2 como alocaveis dinamicamente integer, allocatable :: i1(:), i2(:,:) ! Aloca os arrays i1 com 10 elementos e ! i2 com 21 linhas (-10 a 10) e 10 colunas (1 a 10) Allocate(i1(10), i2(-10:10,10)) ! Testa se i1 e i2 foram alocados Allocated(i1) Allocated(i2) ! Desaloca os arrays liberando a memoria anteriormente ocupada Deallocate(i1,i2)

14 Ponteiros em Fortran90  PONTEIROS: –Diferentemente do que ocorre com as variáveis, os ponteiros armazenam o endereço de memória ao invés do dado propriamente dito; –Os ponteiros não ocupam espaço de memória além do necessário para armazenar o valor de um endereço; –O Fortran não suporta aritmética com ponteiros, ou seja, em Fortran não há como incrementar posições de memória como é feito em C/C++; –Por questões de otimização o Fortran obriga que uma variável “apontável” seja explicitamente especificada através da adição do atributo target junto da declaração da variável; –A declaração de um ponteiro ( pointer ) e de um alvo ( target ) seguem as mesmas regras previamente vistas, ou seja: real*8, target :: a real*8, pointer :: p_a

15 Ponteiros em Fortran90  PONTEIROS: –Alterar um ponteiro significa alterar a posição de memória para a qual ele aponta, ou seja, o conteúdo da memória permanece inalterado; CONTEÚDO do ponteiro significa modificar o valor armazenado no endereço de memória para o qual o ponteiro aponta; –Alterar o CONTEÚDO do ponteiro significa modificar o valor armazenado no endereço de memória para o qual o ponteiro aponta; –Em Fortran 90 utiliza 2 operadores para realizar as operações descritas acima: Fazendo um ponteiro apontar para uma variávelFazendo um ponteiro apontar para uma variável a => c Modificando o conteúdo da memória apontada por “a”Modificando o conteúdo da memória apontada por “a” a = 10.0 –Os ponteiros são famosos por serem flexíveis o suficiente para serem difíceis de se trabalhar tornando o gerenciamento do programa algo bastante complexo e em certos casos incompreensível, ou seja, SE NÃO PRECISAR DELES, NÃO USE!!! “A eficiência computacional é diretamente proporcional a simplicidade e inversamente proporcional a sofisticação”

16 Ponteiros em Fortran90 3 7 integer, target :: ivar = 3 integer, target :: jvar = 7 integer, pointer :: p_var 991B33AA F1D7E700 ivar jvar p_var => ivar p_var => jvar p_var = 9 ivar = 5 p_var 991B33AA F1D7E700 5 9

17 Ponteiros e seus comandos  ASSOCIATED : Verifica se um ponteiro está atribuído (apontando) para alguma variável;  NULLIFY : Faz com que o ponteiro não esteja atribuído a nenhuma variável; integer, dimension(:), pointer :: a_pointer integer, dimension(3), target :: z_target a_pointer => z_target ! a_pointer aponta para z_pointer ! verificando se a_pointer esta associado a z_pointer if (associated(a_pointer, TARGET=z_pointer) then ! fazendo a_pointer não apontar para mais ninguém nullify(a_pointer) endif OBS: O comando associated também poderia ser usado sem o parâmetro TARGET. Neste caso, o comando verificaria se o ponteiro está associado a qualquer variável. 2-ponteiros

18 Criando um array diferente  Suponha que você precise de um array bidimensional no qual as linhas possuem tamanho variável, ou seja, uma linha possui 2 colunas, outra possui 10, etc.... Isso poderia ser facilmente criado através do uso de ponteiros.

19 Criando um array diferente program ArrayDiferente type TypeArray integer :: nterms integer, pointer :: terms(:) end type TypeArray type(TypeArray), allocatable :: array(:) integer :: buffer(10) allocate(array(13)) ! alocando as linhas ! Abrindo o arquivo onde os dados estao open(7,file=“dados.txt”) ! lendo e alocando as colunas do array do i=1,13 read(7,*)n,(buffer(k),k=1,n) array(i)%nterms = n allocate(array(i)%terms(n)) array(i)%terms(:) = buffer(1:n) enddo close(7) ! imprimindo as linhas do array do i=1,13 j = array(i)%nterms print *, array(i)%terms(1:j) enddo ! desalocando o “array diferente” do i=1,13 deallocate(array(i)%terms) enddo Deallocate(array) end program 3-ArrayDiferente

20 Ponteiros (Resumo) ! Define uma variável do tipo ponteiro integer, pointer :: p_a ! Define uma variável que pode ser apontada integer, target :: a = 1 ! Faz o ponteiro apontar para a área de memoria de a p_a => a ! Verifica se o ponteiro esta apontando para algo if (associated(p_a_)) print *, “ponteiro associado” ! Faz o ponteiro deixar de apontar para a nullify(p_a)

21 Exercício: Lista encadeada  Objetivo: –Desenvolver uma lista encadeada simples, capaz de armazenar uma quantidade, inicialmente desconhecida, de elementos inteiros. –Ingredientes: Definição do tipo que agrupará a informação que será armazenada e o ponteiro que indicará a posição de memória do próximo nó da lista. type (Integer_List) integer :: content type (Integer_List), pointer :: next end type Definição dos ponteiros: type(Integer_List), pointer :: head ! Marca inicio da list type(Integer_List), pointer :: node ! Cria os nós da lista type(Integer_List), pointer :: traverse ! Percorre a lista !( * * * VER PROGRAMA LINKEDLIST * * *)

22 Programação estruturada  O que é?! paradigma de programação –A programação estruturada é um paradigma de programação no qual um programa é visto como uma linha de montagem em que os trechos de programas são segmentados e agrupados em unidades específicas (os subprogramas) de acordo com sua utilidade e freqüência com que é (re)utilizada.  Subprogramas –Os subprogramas, também conhecidos como sub-rotinas, funções ou simplesmente rotinas, são módulos especializados na realização de uma determinada tarefa. – O Fortran possui duas estruturas básicas para construção de sub- programas: SUBROUTINE : As subrotinas realizam uma determinada tarefa sem retornar um valor explicitamente FUNCTION : As funções se assemelham as subrotinas, porém, elas retornam explicitamente um valor

23 Funções  Funções declaração: São funções que apresentam uma única expressão (aritmética, lógica ou caractere) –FORMA GERAL: ( ) = expressão real*8 :: avg2, a, b ! criando a função declaracao avg2 avg2(a,b) = (a+b)/2 ! usando a função criada print *, avg2(2.d0,1.2d0)

24 Funções  Funções: Funções que retornam um valor para o programa requisitante. As funções externas são implementadas em uma unidade separada do programa principal. As funções externas possuem a seguinte forma geral: FUNCTION ( ) [RESULT ( )]... end function pode ser: A declaração do tipo da função Uma das seguintes declarações: RECURSIVE, PURE, ELEMENTAL é o nome da função são os argumentos passados para a função [RESULT ( )] variável que conterá o resultado da função (essa construção é opcional)

25 Funções (exemplo) real(8) function AreaCircle(radius) result(c) real(8), intent(IN) :: radius ! <<< COMANDO NOVO: INTENT real(8), parameter :: pi = 3.14159265359d0 real(8) :: c c = pi*radius*radius return ! return, neste caso, é opcional e controla ! o ponto de retorno de uma rotina end function AreaCircle  O que é INTENT ? A declaração INTENT é opcional e serve para identificar se um parâmetro passado para a função ou subrotina é um parâmetro de entrada, INTENT(IN), de saída, INTENT(OUT), ou ambos INTENT(INOUT) 4-AreaCircle

26 Subrotinas  Subrotinas: São subprogramas que podem ou não retornar valores para o programa solicitante. As subrotinas são chamadas pelo programa principal através do comando CALL e possuem a seguinte forma geral: SUBROUTINE ( ) pode ser: Uma das seguintes declarações: RECURSIVE, PURE, ELEMENTAL é o nome da função são os argumentos passados para a função

27 Subrotinas (exemplo) ! Subrotina para inverter um vetor de n posicoes subroutine inverter(ivet,nsize) integer :: i, itmp integer, intent(in ) :: nsize integer, intent(inout) :: ivet(1) do i=1,nsize/2 itmp = ivet(nsize+1-i) ivet(nsize+1-i) = ivet(i) ivet(i) = itmp enddo return end subroutine inverter 5-Inverter

28 Observações sobre Funções e Subrotinas  As funções e subrotinas podem ser desenvolvidas em qualquer parte do programa ou em arquivos separados;  As declarações das funções e subrotinas não precisam preceder os pontos onde elas são chamadas (o compilador se encarrega de procurar as dependências);  Funções e subrotinas podem ser encapsuladas em módulos (será visto mais tarde) para a construção de bibliotecas.

29 Passagem de argumentos para subprogramas  Os programas em Fortran somente suportam a passagem de valores por referência para os subprogramas, ou seja, os valores passados para os subprogramas ao serem modificados retornam as suas modificações para o programa principal. program argumentos integer :: nval nval = 10 print *, altera(nval)! imprimira o valor 15 print *, nval ! também imprimira 15 pois n ! é passado por referência end program integer function altera(n) integer, intent(inout) :: n n = 15 altera = n end subroutine 6-Argumentos

30 Passagem de arrays para subprogramas  O Fortran 90 herdou as 3 formas clássicas de declaração de arrays passados para subprogramas e acrescentou mais uma. Nos slides a seguir veremos cada uma dessas formas.  A 4ª. forma, os módulos, será vista no fim...  Declarando arrays unitários: O array é declarado no subprograma como um array unitário. Neste caso o programador tem que garantir que os limites do array não serão violados. program Principal integer, dimension(10) :: nval = (/(i,i=1,10)/) call Imprime(nval,10)... subroutine Imprime(nums,n) integer :: nums(1) print *, nums(1:n) ! Neste caso não há como utilizar as funções intrinsecas e operações ! com arrays do Fortran 90 no interior da subrotina

31 Passagem de arrays para subprogramas  Declarando um array de tamanho assumido: Neste caso a dimensão do array é declarada dentro dos subprogramas com um símbolo de * para especificar que o array terá o mesmo tamanho que foi definido no programa principal. program Principal integer, dimension(10) :: nval = (/(i,i=1,10)/) call Imprime(nval,10)... subroutine Imprime(nums,n) integer :: nums(*) print *, nums(1:n) ! Neste caso também não há como utilizar as funções ! intrinsecas e operações com arrays do Fortran 90 no interior ! da subrotina

32 Passagem de arrays para subprogramas  Declarando explicitamente o array exceto pela última dimensão: Neste caso o shape é utilizado mas o ultimo tamanho omitido, ou seja, os arrays são declarados em todas as dimensões exceto pela última que é deixada ilimitada. program Principal integer, dimension(2,10) :: nval = (/(i,i=1,10)/) call Imprime(nval,2,10*2)... subroutine Imprime(nums,n,lenght) integer :: nums(n,*) k=lenght/n do i=1,n do j=1,k print *, nums(i,j)... ! Novamente não haverá como utilizar as funções intrinsecas e operações ! com arrays do Fortran 90 no interior da subrotina

33 Opções de subprogramas  Como vimos anteriormente os subprogramas podem ser declarados como RECURSIVE, PURE e ELEMENTAL. Agora veremos o que cada declaração dessa significa.  RECURSIVE : Um rotina recursiva é uma rotina que pode chamar a si própria. ! novamente calculando o fatorial de um numero... RECURSIVE function fact(n) result(answer) integer :: n, answer if (n >= 1) then answer = n*fact(n-1) else answer = 1 endif end function fact

34 Opções de subprogramas  PURE : Uma rotina pura é uma rotina que não provoca efeitos colaterais no programa principal, ou seja, uma rotina pura não modifica nenhum parâmetro de entrada ou qualquer outro dado. As rotinas puras somente irão produzir: –Em FUNCTIONS : somente retornarão o resultado da função; –Em SUBROUTINES : somente modificarão os valores do argumentos declarados como INTENT (OUT) ou INTENT (INOUT);  O argumento PURE é de grande importância pois declara ao compilador que a rotina poderá ser seguramente otimizada, ou seja, embora essa declaração seja opcional ela pode tornar um programa mais eficiente.

35 Um exemplo de função PURA PURE function length(x,y) implicit none real, intent(in) :: x, y real :: length length = sqrt(x**2 + y**2) end function length obs.: Qualquer rotina chamada de dentro de uma rotina pura também deverá ser pura.  A Seguinte função, pode ser considerada PURA? integer function altera(n) integer :: n n = 15 altera = n end subroutine

36 Opções de subprogramas  ELEMENTAL : As rotinas elementares são rotinas declaradas para argumentos escalares porém elas também podem ser aplicadas em arrays. Se os argumentos passados para a rotina forem escalares o resultado será escalar e se os argumentos forem arrays o resultado também será um array de mesma forma dos argumentos de entrada. ELEMENTAL function length(x,y) implicit none real, intent(in) :: x, y real :: length length = sqrt(x**2 + y**2) end function length OBS: Para as rotinas elementares funcionarem com arrays, seus cabeçalhos devem fazer parte de uma interface (ou serem encapsuladas em módulos)

37 Blocos de Interfaces  Os blocos de interface são usados para exibir o cabeçalho de uma rotina para a unidade na qual ela será utilizada  São obrigatórios para a utilização de alguns recursos, tais como: –Aplicação de rotinas elementares a argumentos do tipo array –Utilização de argumentos opcionais –Sobrecarga de operadores INTERFACE subroutine sort(a,n) implicit none real, dimension(:), intent(inout) :: a integer, intent(in) :: n end subroutine sort END INTERFACE

38 Exemplo de Função Elementar program ElementalFunctions ! INTERFACE DA FUNÇÃO ELEMENTAR INTERFACE elemental real*8 function length(x,y) real*8, intent(in) :: x, y end function length END INTERFACE integer, parameter :: n = 10 real*8, dimension(n) :: p1= (/(i,i=1,n)/) real*8, dimension(n) :: p2= (/(i,i=1,n)/) real*8, dimension(n) :: dists = 0.d0 print '(2F15.8)', ((p1(i),p2(i)),i=1,n) dists = length(p1,p2) print *, (dists(i),i=1,n) end program ELEMENTAL real*8 function length(x,y) implicit none real*8, intent(in) :: x, y length = dsqrt(x**2 + y**2) end function length 7-Elemental

39 Argumentos Opcionais e Palavras-Chave  As subrotinas e funcões podem ser declaradas com argumentos opcionais;  Além disso, quando as rotinas são acompanhadas de interfaces, os argumentos podem ser chamados fora da ordem de declaração com o auxílio de palavras-chave (keywords)

40 Exemplo de Palavras-Chave program foo INTERFACE real function calc( first, second, third ) implicit none real, intent(in) :: first, second, third end function END INTERFACE print *, calc(3., 1., 2.) print *, calc( first=3., second=1., third=2. ) print *, calc( second=1., third=2., first=3. ) print *, calc(3., third=2., second=1. ) end program real function calc( first, second, third) implicit none real, intent(in) :: first, second, third calc = ( first - second ) / third end function

41 Exemplo de Argumentos Opcionais program foo interface subroutine extremes(a, n, vmax, vmin) integer, intent(in ) :: n real, intent(in ) :: a(n) real, intent(out), OPTIONAL :: vmax, vmin end subroutine end interface real :: a(4) = (/.2,.5, 1., 1.2 /) real :: minimo, maximo call extremes( a, 4, vmax=maximo ) print *, ‘O valor maximo e: ‘, maximo call extremes( a, 4, vmin=minimo ) print *, ‘O valor minimo e: ‘, minimo call extremes( a, 4, maximo, minimo ) print *, ‘ Os extremos sao: ‘, maximo, minimo end program subroutine extremes(a, n, vmax, vmin) integer, intent(in ) :: n real, intent(in ) :: a(n) real, intent(out), OPTIONAL :: & vmax, vmin if (PRESENT(vmax)) vmax = maxval(a) if (PRESENT(vmin)) vmin = minval(a) end subroutine

42 Rotinas como Argumentos de Rotinas real function func_1() func_1 = 1. end function real function func_2() func_2 = 2. end function real function Evaluate (func, val) real, intent(in) :: val real, EXTERNAL :: func ! <-- DECLARA QUE FUNC É DEFINIDA EXTERNAMENTE Evaluate = val**func() end function program foo real, EXTERNAL :: func_1, func_2 ! <-- DECLARA AS FUNÇÕES-ARGUMENTO print *, Evaluate( func_1, 2. ) print *, Evaluate( func_2, 2. ) end program

43 Módulos – uma nova forma de passar parâmetros  MODULE : Os módulos foram adicionados ao padrão da linguagem Fortran 90 para substituir as antigas formas empregadas pelo Fortran 77 para disponibilizar dados entre subprogramas.  Mais abrangentes do que os antigos “ COMMOM BLOCKS ” e INCLUDES os módulos permitem não somente a disponibilização de variáveis como também estruturas, tipos, ponteiros e até subprogramas completos.  Os módulos podem ser construídos em qualquer parte do programa ou em unidades separadas, porém, eles devem ser compilados de acordo com sua ordem de dependência pelo programas e rotinas.  Rotinas declaradas dentro de módulos não necessitam de interfaces explícitas para usarem recursos como argumentos opcionais e palavras-chave

44 Sintaxe de Construção de Módulos module ! Declaração de variáveis e/ou constantes modulares real(8) :: a, b, c real(8), allocatable :: d(:) ! Declaração de rotinas modulares CONTAINS subrotine Add_two_Values(a, b) … end subroutine function Print_Result() … end function end module

45 Usando os Módulos  Para compartilharmos as informações contidas em um MODULE entre outras partes do programa basta adicionarmos o comando USE no inicio da unidade que desejamos que acesse os dados e rotinas do módulo. subroutine A use B ! A subrotina A estará acessando os dados do modulo B... program Teste use valores... module Valores... end module subroutine A use valores function B use valores function C... subroutine D...

46 Usando Módulos (um exemplo simples) module Dados real*8 :: xmin, xmax, ymin, ymax, dx, dy integer :: ndivx, ndivy real*8, allocatable :: xy(:,:) end module dados subroutine Grade use Dados... ! calculando as coords da grade... end subroutine Grade Program CalcularFuncao use Dados... print *, “Entre com os dados” call Grade... end program CalcularFuncao

47 (Algumas) observações sobre módulos:  Os módulos podem conter: –Somente dados –Somente rotinas –Ambos  Os módulos podem usar regras de escopo –PRIVATE : as entidades privadas só podem ser manipuladas dentro do próprio módulo –PUBLIC : as entidades ficam expostas para serem usadas for a dos módulos onde estão contidas  Podemos restringir o acesso ao conteúdo de um módulo externamente utilizando o comando ONLY

48 Módulo com regras de escopo module foo ! a1, b1 e c1 só podem ser alteradas por rotinas ! contidas dentro deste módulo real(8), private :: a1, b1, c1 ! d1 pode ser modificada for a do módulo ! inclusive alocada e desalocada real(8), allocatable, public :: d1(:) CONTAINS subroutine DoSomething() c1 = a1 + b1 end surboutine end module foo

49 Restringindo o Acesso a Dados ( ONLY ) module Dados real :: a, b, c, d end module Dados program foo ! embora o modulo exponha todos os seus dados (todos sao publicos) ! somente as variaveis a e b estão serão acessadas use Dados, only: a, b ! as variaveis abaixo só podem ser definidas pela restrição do acesso ! às variaveis c e d do modulo Dados. Caso contrario daria erro de ! compilação por duplicidade de nomes real :: c, d end program

50 OOP à moda Fortran 2003 module class_Circle implicit none private ! definindo o tratamento de escopo padrão para o modulo public :: Circle, circle_area, circle_print real, parameter :: pi = 3.1415926535897931d0 ! constante privada type Circle real :: radius end type Circle contains function circle_area(this) result(area) type(Circle), intent(in) :: this real :: area area = pi * this%radius**2 end function circle_area subroutine circle_print(this) type(Circle), intent(in) :: this real :: area area = circle_area(this) ! Call the circle_area function print *, 'Circle: r = ', this%radius, ' area = ', area end subroutine circle_print end module class_Circle

51 Usando uma “classe” Fortran program circle_test use class_Circle implicit none ! Declara variavel do tipo Circle type(Circle) :: c ! Utiliza o “construtor” implicito da “classe” c = Circle(1.5) ! Chama um “método” da “classe” circle call circle_print(c) end program circle_test ! Este exemplo talvez não funcione no GFortran


Carregar ppt "CPC782 Fundamentos de Programação Introdução ao Fortran aula 3/3 Renato N. Elias / Marcos A. D. Martins material."

Apresentações semelhantes


Anúncios Google