470 likes | 591 Views
CPC782 Fundamentos de Programação. Introdução ao Fortran Renato N. Elias / Marcos A. D. Martins. Antes de começarmos. Devemos saber responder algumas questões BASTANTE básicas: O que é um programa de computador? Por que eu preciso aprender a programar? O que é um arquivo ou código fonte?
E N D
CPC782 Fundamentos de Programação Introdução ao Fortran Renato N. Elias / Marcos A. D. Martins
Antes de começarmos... • Devemos saber responder algumas questões BASTANTE básicas: • O que é um programa de computador? • Por que eu preciso aprender a programar? • O que é um arquivo ou código fonte? • O que é um objeto ou arquivo compilado? • O que é uma linguagem de programação? • O que é lógica de programação? • O que é um pré-processador? • O que é um compilador? • O que é um linker? • O que é uma biblioteca?
Como aprender uma linguagem de programação?slide de (des)motivação para aprendizado de qualquer linguagem de programação • Precise dela!!!!! “Se eu não preciso, por que tenho de aprendê-la?” • Tenha prazer em programar como quem está para decifrar um enigma. “Como eu faço esse computador fazer o que eu quero?” • Pegue um programa simples, contendo bons comentários passo-a-passo e tente utilizar os fragmentos que se assemelham com o que se deseja fazer como um modelo. “Guarde esse programa-modelo em um cofre a sete chaves até se sentir seguro o suficiente para programar sozinho” • Comece a programar com a ajuda de um bom ambiente de programação. “mas nunca se torne escravo dele” • Não desanime, seja persistente! “Errar é a melhor parte do processo de aprendizado pois os erros, geralmente, são mais facilmente assimilados do que os acertos” • Não tenha medo de tentar! “O (bom) compilador adora nos humilhar mostrando nossos deslizes, além disso, um simples programa não irá fazer o computador explodir -- mas talvez ele precise ser reiniciado...” A good programmer is someone who looks both ways before crossing a one-way street. -- Doug Linder, systems administrator
Desenvolvendo programas • Planejar; • Lógica de programação • Desenvolver; • Linguagem (C/C++, Fortran, Java, etc...) • Ambiente de programação (Vi, Notepad, Visual Studio, KDE developer, etc...) • Pré-processar, compilar e “linkeditar” • Compiladores (Intel, G95, PGF90, Compaq, etc...) • Testar (depuração); • Ambiente de programação • Corrigir (depuração); • Ambiente de programação Commentary: most debugging problems are fixed easily; identifying the location of the problem is hard. -- unknown
Pré-processamento “linkedição” ou “linkagem” fonte arq1.f90 pré-processado arq1.i fonte arq2.f90 pré-processado arq2.i fonte arq3.f90 pré-processado arq3.i Construindo um programa Compilação compilado arq1.obj programa foo.exe compilado arq2.obj compilado arq3.obj
O que eu preciso para programar em Fortran? • Um editor de textos, um compilador ou um ambiente de programação que forneça o editor de textos e o compilador juntos • Em Windows: • Compaq Visual Studio (comercial) • Visual Studio + Intel Fortran (comercial) • Fortran Force (gratuito: http://www.guilherme.tk/) • Em Unix e similares: • G77 (gratuito – não recomendado); • Sun Studio (gratuito); • Intel Fortran (gratuito para uso não comercial) • Compilador do Portland Group (comercial)
Referências • Google, Google, Google • 34.300.000 referências para a palavra Fortran • Fortran Wikipedia: • http://pt.wikipedia.org/wiki/Fortran • Fortran Standards Technical Commitee • http://www.j3-fortran.org/ • Livros: • Stephen J. Chapman, “Fortran 90/95 for Scientists and Engineers” • James F. Kerrogan, “Migrating to Fortran 90” • Apostila: • http://www.nacad.ufrj.br/~rnelias/fortran
Fortran – Um pouco de história • Criada em 1954-57 por uma equipe da IBM chefiada por John Backus; • Nome da linguagem derivado de seu principal propósito FORmula TRANslator • Primeira linguagem de programação de alto nível desenvolvida para computadores; • Com sua rápida popularização surgiu a necessidade de uma padronização em 1966 (Fortran IV ou Fortran66) • Sofreu algumas modificações em 1977 (Fortran77) • Outras atualizações: • Fortran90 (1993); • Fortran95 (1997); • Fortran2003; • HPC (High Performance Fortran)
Motivos para NÃO APRENDER Fortran • Programação de interface gráfica (GUI); • Programação de bancos de dados; • Programação voltada para internet; • Programação que utilize manipulação intensiva de strings; • Programação dirigida a objetos (OOP).
Motivos para APRENDER Fortran • Fácil de aprender, desenvolver e depurar; • Extremamente eficiente na execução de CÁLCULOS; • Milhares de bibliotecas científicas testadas, otimizadas e distribuídas gratuitamente para uso com o Fortran;
Deficiências anteriores ao Fortran 90 • Exigência de uso de formato fixo para codificação; • Impossibilidade de acesso dinâmico de dados; • Inabilidade de representação implícita de operações em arrays • Falta de portabilidade (padrão definido pelo fabricante) • Impossibilidade de definição de tipos pelo programador; • Inexistência de recursividade; • Acesso aos dados globais através de COMMON blocks
Recursos adicionados ao Fortran90 • Formato livre de arquivos; • Sintaxe própria para operações com arrays • Alocação dinâmica e inclusão de pointers • Tipos de dados portáveis (KIND) • Tipos de dados derivados e operadores • Recursividade • Modules em substituição e extensão aos COMMON BLOCKS • Estruturas de controle mais aprimoradas • I/O aprimorado
O que iremos aprender? Fortran IV Fortran 90 FORTRAN Fortran 77 Fortran 95 Fortran 2003
Elementos da linguagem • O Fortran não é sensível à letras maiúsculas e minúsculas: Casa = casa = CASA = cASA = cAsA = CaSa • Formatos de arquivos aceitos pelo Fortran • Fixo (extensões *.for, *.f77, *.f, *.F) • Livre (extensões *.f90, *.F90) • Caracteres de comentário • Linhas contendo os caracteres “c” ou “C” na coluna 1 • Qualquer texto iniciado pelo caractere “!” • Rótulos (labels) • Números de (1 a 99999) colocados nas 5 primeiras colunas • Continuação de linha • Formato fixo: linha que possui qualquer caractere na coluna 6 • Formato livre: Qualquer linha finalizada com um ampersand (&) • Vários comandos em uma mesma linha • Separar os comandos com um ponto e vírgula “;”
FIXO LIVRE Formatos de arquivos
Comentários e continuação de linha Formato fixo (arquivo hello.f) Formato livre (arquivo hello.f90)
Outras perguntas básicas... • O que é uma variável? a = 1.0 i = 1 str = ‘Fortran’ • O que é um tipo? • O tipo de uma variável informa ao compilador, e consequentemente ao programa, como o computador deverá interpretar a variável. • No exemplo acima a, i e str ocupam quantidades distintas de memória devido aos seus TIPOS serem também diferentes.
Evitando dores de cabeça • Faça comentários significativos nos seus programas: • Comentário inútil i=0 ! i recebe valor 0 • Comentário útil i=0 ! i está sendo zerado pois será utilizado como ! contador do próximo loop • Crie nomes de variáveis auto-explicativos • Variável pouco explicativa: integer :: n • Variável auto-explicativa: integer :: NumberOfNodes • Endente seu programa para facilitar a leitura • Tente usar somente funções intrínsecas da linguagem • Compatibilidade = portabilidade = flexibilidade • Se for usar bibliotecas, procure se informar se essa biblioteca estará disponível nos sistemas que pretende usar
Estrutura básica de um programa Fortran program <nome_do_programa> ! declaracao de modules use dados ! declaracao de variaveis integer :: n, k, l ! corpo do programa n = 1 k = 2 l = n+k print *, l ! finalizacao do programa end program
Tipos de dados • Inteiro integer :: n = 1 • Real de precisão simples real*4 :: a = 3.0 ! 7 casas de precisão real(4) :: a = 3.0E1 real :: a = 3. • Real de precisão dupla double precision :: a = 2.5d0 ! 15 casas de precisão real*8 :: a = 2.5D0 real(8) :: a = 2.5D0 • Lógico logical :: ok = .false.
Tipos de dados (continuação) • Complexo de precisão simples complex*8 :: c = (1.,4.) complex :: c = (1.3,4.1E1) • Complexo de precisão dupla complex*16 :: c = (1.d0,4.d0) • Character character :: str*80 character(80) :: str character*80 :: str character*80 str
Tipos de dados derivados • Permite a criação de tipos de acordo com a necessidade do programador Type employee_name SEQUENCE ! (Opcional) preserva a ordem de armazenamento dos campos character(25) last_name character(15) first_name END TYPE employee_name Type employee_data TYPE (employee_name) :: name ! Usando o tipo previamente criado integer telefone integer age logical married END TYPE
Usando um tipo derivado Type(employee_data) :: employee employee%name%last_name = 'Elias' employee%name%first_name = 'Renato' employee%telefone = 25628080 employee%age = 30 employee%married = .true. ! Ver programa exemplo typeder.f90
Declaração implícita • Antagonicamente NÃO recomendado, porém, bastante útil • Declaração de tipo implicitamente determinada pela primeira letra do nome da variável: i,j,k,l,m,n: variáveis inteiras a-h, o-z:variáveis reais de precisão simples • Modificando a declaração implícita implicit real*8 (a-h,o-z) implicit integer (i-k) • Obrigando que todas as variáveis sejam explicitamente declaradas implicit none
program foo implicit real*8 (a-h,o-z) a = 2.d0 b = 3.d0 c = a+b print *, c end program program foo implicit none real*8 :: a,b,c a = 2.d0; b = 3.d0; c = a+b print *, c end program Na prática... program foo implicit none a = 2.d0 b = 3.d0 c = a+b print *, c end program ERRADO!!!! produzirá erro de compilação
Operadores Lógicos Exemplo: considere a=.true. e b=.false. para avaliar as seguintes operações lógicas c = a .and. b c = a .or. b c = .not. a c = a .eqv. b c = a .neqv. b Exemplo: considere a = .true. e b = .false. para avaliar as seguintes operações lógicas c = a .and. b ! c = .false. c = a .or. b ! c = .true. c = .not. a ! c = .false. c = a .eqv. b ! c = .false. c = a .neqv. b ! c = .true.
Hierarquia entre operações • Parênteses mais internos • Cálculo de funções • Potenciação • Menos unário • Multiplicação e divisão • Adição e subtração • Concatenação Exemplo: x+1/x-1 é diferente de (x+1)/(x-1)
Algumas funções intrínsecas • Observação: • algumas funções intrínsecas possuem versões específicas de acordo com o tipo de dado utilizado, por exemplo: dabs(x) ! x e o resultado da operação são real*8 iabs(n) ! n e o resultado da operação são integer
Programa PI • Programa PI: • Obter o valor de PI usando a função intrínseca ACOS do Fortran para obter o Arco-cosseno de -1 program PIValue real*4 :: pi_sp real*8 :: pi_dp pi_sp = acos(-1.) print *, ‘Pi in single precision is:’, pi_sp pi_dp = dacos(-1.d0) print *, ‘Pi in double precision is:’, pi_dp end program Inside every well-written large program is a well-written small program. -- Charles Antony Richard Hoare, computer scientist
Inteira 3/5 = 0 13/4 = 3 Real 3.0/5.0 = 0.6 3./5. = 0.6 13./4.0 = 3.25 Mista 3.0/5 = 0.6 13/4.0 = 3.25 Conversão automática de tipo: program conv integer :: nres nres = 1.25+9/4 print *, nres ! imprimirá 3 ao invés de 3.5 end program ATENÇÃO: Notem que embora o resultado da operação seja real, ele foi armazenado em uma variável do tipo inteiro ocasionando uma conversão automática. (EVITEM FAZER ISSO!!!) Aritmética inteira, real e mista
Evitando o uso de potenciação • A potenciação é internamente implementada como uma operação com logarítmos, portanto, uma operação lenta e sujeita a erros result = y**2.0 ! internamente seria result = exp(x*ln(2.0)) • Podemos evitar isso utilizando expoentes inteiros sempre que possível ou realizando a operação explicitamente: result = y**2 result = y*y
Operações com strings • Para o Fortran uma string é um array de characters program string character(3) :: str1, str2 character(6) :: str3 str1 = ‘ABC’ str2 = ‘DEF’ str3 = str1//str2 ! concatenando str1 com str2 print *, str3 print *, ‘ primeiras 2 letras de str1: ’, str1(:2) print *. ‘ ultimas 4 letras de str3: ‘, str3(3:6) end program
Let’s do something... • Programa DegToRad para converter graus em radianos • se 180º equivale a pi radianos, então, usando a nossa velha conhecida regra de 3: xo = x*pi/180 program DegToRad real*8 :: ang, PI PI = dacos(-1.d0) ang = 45 print *, ang ,‘ graus = ’, ang*PI/180.0, ‘ radianos’ end program
Comandos condicionais • Os comandos condicionais causam desvios no fluxo natural do programa de acordo com a avaliação de alguma expressão lógica • Em Fortran, os comandos condicionais básicos são: • IF (lógico) • IF, THEN, ELSEIF, ENDIF • CASE
Comandos condicionais • IF (lógico): • executa, ou não, uma operação de acordo com a avaliação de uma expressão lógica (Booleana) if (a<10.0) a = 0.0 • IF, THEN, ELSE, ELSEIF: • desvia a execução do programa de acordo com a avaliação de uma, ou várias, expressão(ões) lógica(s) nome: if (teste logico) then ! corpo do if end if nome ! os nomes são opcionais e geralmente utilizados para ! fins de identificacao
! Exemplo 1 if (b > c) then a = a+1 c = 0 else a = a–1 b = 10 endif ! Exemplo 2 idade: if (age>18) then print *, ‘maior’ else print *, ‘menor’ endif idade ! Exemplo 3 if (b > c) then a = a+1 c = 0 elseif (c.eq.a) then a = a-1 b = 10 else a = a+2 b = 0 endif Repare que o elseif nada mais é do que um if aninhado numa cláusula else IF, THEN, ELSE, ELSEIF (continuação...)
Comandos condicionais • SELECT CASE: • Este comando pode substituir uma série de if’s aninhados, porém, ele só pode ser utilizado com variáveis INTEGER e CHARACTER nome:select case (i) case(:-1) ! todos os valores inteiros menores que 1 print *, ‘numero negativo’ case(0) ! somente se i for igual a 0 print *, ‘ zero ‘ case(1:9) ! numeros inteiros entre 1 e 9 print *, ‘ numero de 1 unico digito: ‘ case(10:99) ! numeros inteiros entre 10 e 99 print *, ‘ numero de 2 digitos ‘ end select nome
Comandos de repetição • Os comandos de repetição, laços ou loops são utilizados na execução de um ou mais comandos repetidas vezes. • Em Fortran, os comandos de repetição são: • DO (simples e infinito) • WHILE • Loops implícitos (veremos mais tarde quando tratarmos de variáveis indexadas) • Existem comandos auxiliares que controlam a saída forçada de dentro de um laço, são eles: exit cycle [label]: goto [label]: return:
Comandos de repetição • DO: • Os laços DO em Fortran são a forma mais natural de se realizar uma ou mais operações repetidas vezes. Nesse tipo de laço uma variável de controle é utilizada como contador e, consequentemente, como critério de parada para o laço. • Forma geral: nome: DO <variável de controle> = inicio, fim, incr ! corpo do laço ENDDO nome • Observações: • Se o incremento for unitário o mesmo poderá ser omitido • O incremento poderá ser negativo (decremento) • A variável de controle não deve ser alterada no interior do laço
! Exemplo 1: DO i=1,10 print *, i ENDDO ! Exemplo 2: DO n=1,10,3 print *, n ENDDO ! Exemplo 3: DO j=10,1,-1 print *, j END DO ! Exemplo 4: i0=-5; i1=30; inc=4 DO n=i0,i1,inc print *, n ENDDO ! Exemplo 5: h=0.5 DO x=4.0,7.9,h print *, x ENDDO ! Exemplo 6: externo: DO i=5,10 interno: DO j=10,1,-1 print *, ‘i+j vale:’, i+j ENDDO interno ENDDO externo DO: O que podemos fazer...
! Exemplo 1: DO i=1,10 i = i+1 ! i não deve ser usado em ! calculos dentro do loop ENDDO ! Exemplo 2: DO i=1,10 DO i=10,1 ! 2 loops com a mesma ! variável de controle ENDDO ENDDO ! Exemplo 3: DO i=1,10 j = j+1 DO j=10,1 ! variavel de controle ! do segundo loop sendo ! usada no primeiro loop ENDDO ENDDO ! Exemplo 4 externo: DO i=1,10 interno: DO j=1,10 ! laços cruzados enddo externo enddo interno DO: O que NÃO podemos fazer...
Comandos de repetição • DO WHILE: • O laço DO WHILE executa uma ou mais operações “ENQUANTO” uma condição esteja sendo satisfeita (avaliada como verdadeira). • Forma geral: nome: DO WHILE <teste lógico> ! corpo do laço END DO nome • Observações: • Ao contrário do que ocorre com o laço DO, no DO WHILE a variável de controle utilizada no teste lógico, pode (e geralmente é) utilizada em alguma operação no corpo do laço
! Exemplo 1 i=0 DO WHILE (i<=10) print *, i i = i + 1 END DO ! Exemplo 2 logical :: Ok = .false. i=1; j=50 DO WHILE (.not.Ok) i=i+1 j=j-2 Ok = i>j print *, Ok, i, j ENDDO DO WHILE em exemplos:
Comandos de repetição • DO infinito: • O Fortran 90 introduziu o conceito de DO infinito, ou eterno. Nesse tipo de laço uma ou mais operações são repetidas indefinidamente (o que faz pouco sentido em programação) ou até que algum comando force a saída de dentro do laço • Forma geral: DO ! corpo do loop if <satisfeita uma condição> exit ENDDO
DO infinito em 1 exemplo program CelsiusToKelvin real*4 :: celsius character :: opt*1 DO print *, 'Entre com a temperatura em Celsius:' read(*,*) celsius ! falaremos do comando READ mais tarde print *, celsius, ' Celsius = ', celsius+273.15, ' Kelvin' print *, 'Deseja sair (S/N)' read(*,*) opt if (opt.eq.'s'.or.opt.eq.'S') exit ENDDO end program
Complicando o que deveria ser simples... program DOCycle cycle_loop:do i = 1, 5 print *,i if (i.gt.3) cyclecycle_loop print *,i end docycle_loop print *,'done!' end program ! Quando i torna-se maior que 3 o loop só é ! executado até o cycle