Upload
truongdat
View
235
Download
0
Embed Size (px)
Citation preview
1
Instituto Superior TécnicoDep. de Engenharia MecânicaGCAR, Secção de Sistemas
Introdução à Programação
Notas de apoio à disciplina de
Introdução à Programação 2001/2002
(Lic. Eng. Mecânica - 1º ano)
João Miguel da Costa Sousa
João Miguel C. Sousa GCAR , DEM, IST 2
Introdução
Title:
Creator:CorelDRAWPreview:This EPS picture was not savedwith a preview included in it.Comment:This EPS picture will print to aPostScript printer, but not toother types of printers.
João Miguel C. Sousa GCAR , DEM, IST 3
Informação geral
1 Bibliografia
• Nyhoff, L.R. and Leestma, S.C. Fortran90 for Engineers and Scientists. Prentice-Hall International, Inc. 1997.
• Sousa, J.M.C. Acetatos das aulas teóricas
1 Avaliação de conhecimentos• A nota final é dada pela seguinte formula :
NF = 0.15 MT + 0.35 NP + 0.5 NE• NF - Nota final• MT - Mini-testes• NP - Nota do projecto• NE - Nota exame • onde: NP, NE, NF ≥ 9.5
1 Página Web:• www.dem.ist.utl.pt/~m_ip
João Miguel C. Sousa GCAR , DEM, IST 4
Programa
1. Introdução à computação
2. Introdução ao Fortran
3. Estruturas de controlo: selecção
4. Estruturas de controlo: repetição
5. Operações de entrada/saída
6. Subprogramas: funções
7. Subprogramas: subrotinas
8. Tipos de dados estruturados: tabelas
9. Tipos de dados estruturados: fichas
10. Tipos de dados dinâmicos: ponteiros
2
João Miguel C. Sousa GCAR , DEM, IST 5
Introdução à Computação
1 Sistemas de computação• mecanização de operações (procedimentos)• armazenamento de programas e dados
1 Primeiros “computadores”• Máquina Analítica, Charles Babbage, Ada
Augusta (primeiro programador), 1822.• Máq. de cartões perfurados, censo nos EUA,
Herman Holleritm, fundador IBM, 1890.
1 Hardware: componentes físicos
1 Computadores electrónicos• 1ª geração - Válvulas, ENIAC 1946• 2ª geração - Transistores IBM 70990, 1958• 3ª geração - Circuitos integrados
IBM system/360 1964• 4ª geração - VLSI, chips de silicone. PCs,
workstations e supercomputadores• 5ª geração - Processamento paralelo
João Miguel C. Sousa GCAR , DEM, IST 6
Máquinas de computação
João Miguel C. Sousa GCAR , DEM, IST 7
Programas
1 Software - programas utilizados pelo computador
1 Sistema operativo - interface entre a máquina e o utilizador• UNIX, AT&T’s Bell Laboratories, 1971• MS-DOS, Microsoft, 1981• GUI - Apple Macintosh, Windows95
1 Linguagens de alto nível - Fortran, Pascal, BASIC, Lisp, C++, Java, etc.
1 Programa fonte - programa escrito em linguagem de alto nível
1 Programa objecto - tradução do programa de alto nível para linguagem máquinausando um compilador.
1 FORTRAN - FORmula TRANslator
João Miguel C. Sousa GCAR , DEM, IST 8
Computador
1 Sistema composto por componentes com funções diferentes a trabalhar para um objectivo comum
1 Componentes principais• CPU - Central Processing Unit1 Unidade de controlo1 ALU (Arithmetic and Logic Unit)
• Memórias - registos, RAM, ROM, memória virtual
• Memória externa - discos rígidos, disquettes• Outros periféricos - Input/Output: terminais,
monitores, scanners, impressoras, rato, etc.
Aplicações
SistemaOperativo
Drivers
3
João Miguel C. Sousa GCAR , DEM, IST 9
Organização da memória
1 Sistema binário - 0,1 bits (binary digits)
1 byte - conjunto de 8 bits. Medida da memória em bytes. 1K = 210=1024 bytes. 1 megabyte = 1024 K = 1048576 bytes.
1 word - conjunto de bytes igual ao usado nos registos do CPU. 16, 32, 64 bits
1 address - endereço associado a cada word.
1 Memória guarda instruções dos programas a serem executadas
1 Linguagem assembly
1 Assembler - traduz assembly para código máquina.
João Miguel C. Sousa GCAR , DEM, IST 10
Programa de computador
1 Conjunto de instruções a seguir para resolver um dado problema
1 Desenvolvimento de programas• Análise do problema• Projecto do algoritmo• Codificação do programa• Execução e testes
' Exemplo: Um físico nuclear investiga o polónio. A radiactividade do polónio baixa para metade ao fim de 140 dias. Pretende-se saber a quantidade ao fim de 180 dias, sabendo que a inicial era de 10mg.
1 Análise do problema. Especificação precisa com entradas e saídas.
Entradas (Input) Saídas (Output)Quantidade inicial: (10 mg) Quantidade restanteMeia-vida: (140dias)Período de tempo: (180 dias)
João Miguel C. Sousa GCAR , DEM, IST 11
Algoritmo
2 Projecto do algoritmo.
1 Algoritmo - Sequência finita de instruções bem definidas e não ambíguas, onde cada uma pode ser executada mecanicamente, com uma quantidade de esforço finito e num intervalo de tempo finito.
1 Tem duas partes:
1 Descrição dos objectos a manipular.
' Exemplo
1 Variáveis escolhidas; QuantidadeInicial, MeiaVida,Tempo e QuantidadeRestante
2 Descrição das acções a executar nesses objectos.
' Exemplo1 Recebe valores das variáveis2 Calcula o valor da QuantidadeRestante para o Tempo
dado.3 Retorna e mostra a QuantidadeRestante.
1 Refinamento do algoritmo ao detalhe necessário
João Miguel C. Sousa GCAR , DEM, IST 12
Abstracção e abordagem topo-base
1 Abstracção - Descrição de uma dada entidade descrevendo apenas os aspectos relevantes para o objectivo, desprezando os pormenores.
1 Abstracção procedimental - Agrupa uma sequência de instruções e dá-lhes um dado nome (procedimento). Para executar o procedimento basta evocar o seu nome, sem considerar as acções que o constituem.
1 Abstracção de dados - Associada à utilização de objectos. Separa a forma de utilizar da constituição do próprio objecto. Um objecto pode ser decompos-to em objectos mais simples. Ex: matriz, fichas.
1 Análise topo-base (top-down) - Consiste em dividir um problema complexo em sub-problemas mais simples. Estes sub-problemas têm um dado nome, e podem ser por sua vez divididos em sub-problemas mais simples até estes serem triviais e resolvidos facilmente.
4
João Miguel C. Sousa GCAR , DEM, IST 13
Programa: Radioactividade
Algoritmo para problema de radioactividade
1 Este algortimo calcula a radioactividade de uma substância após um dado tempo, dada a quantidade inicial e o tempo de metade da vida.
1 Entradas: Uma dada QuantidadeInicial da substância radioactiva, a sua MeiaVida, e o período de Tempo em dias.
1 Saída: QuantidadeRestante.
1 Recebe QuantidadeInicial , MeiaVida e Tempo.2 Calcula
QuantidadeRestante = QuantidadeInicial * (0.5) ** (Tempo / MeiaVida)
3 Retorna a QuantidadeRestante.
João Miguel C. Sousa GCAR , DEM, IST 14
Programa: Radioactividade (2)
3 Codificação do programa
PROGRAM Decaimento_Radioactivo!--------------------------------------------------------------! Este programa calcula a radioactividade de uma substancia! apos um dado tempo, dada a quantidade inicial e o tempo de! metade da vida radioactiva. Variaveis usadas:!! QuantidadeInicial : quantidade inicial da substancia (mg)! MeiaVida : tempo meia-vida da substancia (dias)! Tempo : tempo para o qual a quantidade! restante e calculada (dias)! QuantidadeRestante : quantidade da substancia restante(mg)!! Entradas: QuantidadeInicial, MeiaVida, Tempo! Saida: QuantidadeRestante!------------------------------------------------------------IMPLICIT NONE
REAL :: QuantidadeInicial, MeiaVida, Tempo, QuantidadeRestante
! Recebe valores para QuantidadeInicial, MeiaVida e Tempo.
PRINT *, ”Escreva o valor inicial da substancia (mg), a sua” PRINT *, ”meia-vida (dias) e o tempo para o qual se quer” PRINT *, ”determinar a quantidade restante:"READ *, QuantidadeInicial, MeiaVida, Tempo
! Calcula a quantidade restante para o tempo especificado. QuantidadeRestante = QuantidadeInicial * 0.5 ** (Tempo / MeiaVida)
! Mostra a QuantidadeRestante. PRINT *, " QuantidadeRestante =", QuantidadeRestante, "mg”
END PROGRAM Decaimento_Radioactivo
João Miguel C. Sousa GCAR , DEM, IST 15
Programa: Radioactividade (3)
1 Execução e testes - Verificar se o algoritmo e o programa estão correctos.
1 Fases de execução• Inicializar o computador
• Editar o programa num editor de texto
• Compilar o programa - produz objecto.
• Link - Ligar o programa; produz executável
• Correr o programa
1 Exemplos:
Escreva o valor inicial da substancia (mg), a suameia-vida (dias) e o tempo para o qual se querdeterminar a quantidade restante:2, 140, 140QuantidadeRestante = 1.0000000 mg
Escreva o valor inicial da substancia (mg), a suameia-vida (dias) e o tempo para o qual se querdeterminar a quantidade restante:10, 140, 180QuantidadeRestante = 4.1016769 mg
João Miguel C. Sousa GCAR , DEM, IST 16
Programação
1 Análise do problema2 Desenvolvimento da solução - projecto do
algoritmo3 Codificação do programa4 Execução e testes5 Manutenção
1 Análise do problema• Descrição das entradas
• Descrição das saídas
1 Desenvolvimento da solução• Elaboração do algortimo1 Selecção das estruturas de dados1 Descrição das acções a efectuar
• Sequenciação• Selecção• Repetição
5
João Miguel C. Sousa GCAR , DEM, IST 17
Programação (cont.)
1 Desenvolvimento da solução (cont.)• Análise topo-base - divisão do problema em
sub-problemas mais simples.
• Programa é dividido em módulos.
1 Codificação do programa• Desenvolvimento de código em Fortran 901 Variáveis - devem começar por uma letra e
seguidas por 30 letras, números ou underscores.1 Tipos - tipo de valores que as variáveis podem
ter. Ex: REAL, INTEGER, etc.1 Operações - *, /, **, etc.1 Atribuição - o sinal = atribui o valor da
expressão à variável que está à esquerda.1 Input/Output - READ, PRINT, WRITE, etc.1 Comentários - símbolo “!”
• Estilo de programação - programas devem ser correctos, legíveis e perceptíveis.
João Miguel C. Sousa GCAR , DEM, IST 18
Estilo de programação
1 Programas devem ser bem estruturados• Usar metodologia topo-base para desenvolver
um progama para problemas complexos.
• Simples e claro - evitar truques de programação que aumentam pouco a velocidade de execução.
1 Documentação cuidada• Documentação inicial
• Comentários para explicar partes importantes
• Identificadores com um significado claro
1 Estilo de formatação legível• Espaços entre items
• Inserir linha entre secções de um programa
• Alinhamento e identação
João Miguel C. Sousa GCAR , DEM, IST 19
Execução e testes
1 Programa deve ser correcto.
1 Sintaxe - define qual a linguagem correcta da linguagem.• Erros de sintaxe são detectados pelo compilador
sendo relativamente fáceis de corrigir.
1 Semântica - define o significado do código implementado.• Erros de semântica- Programador não
especificou correctamente a sequência de instruções. Difíceis de detectar.
' Exemplo:
• Depuração (debugging) - técnicas que permitem minimizar os erros.
QuantidadeRestante = QuantidadeInicial * 0.5 ** (Tempo / MeiaVida)
QuantidadeRestante = QuantidadeInicial * 0.5 * (Tempo / MeiaVida)
João Miguel C. Sousa GCAR , DEM, IST 20
Manutenção
1 Modificações necessárias ao fim de um certo tempo tais como:• Aumentar capacidade do programa com novas
funções• Melhorar o desempenho do programa• Mudanças de sistema operativo, etc.
' Exemplo: Fortran PowerStation, versão 4.0
1 Para isto é necessário efectuar a documentação externa, que contém:
• Documentação para utilizadores1 descrição do que o programa faz1 descrição do processo de utilização do programa1 descrição da informação produzida1 descrição das limitações do programa
• Documentação técnica1 descrição das estruturas de informação e das
principais variáveis e constantes1 descrição do algoritmo1 descrição da estrutura do programa incluindo os
principais sub-programas e sua interligação
6
João Miguel C. Sousa GCAR , DEM, IST 21
Introdução ao Fortran
1 Tipos de dados básicosintegerrealcomplexcharacterlogical
Programa em Fortran________________________________________________________
cabeçalho
zona de especificações
zona de instruções
zona de sub-programasEND PROGRAM nome_de_programa
João Miguel C. Sousa GCAR , DEM, IST 22
Tipos de dados
1 INTEGER• cadeia de dígitos que não contém vírgulas ou
pontos.
& Exemplos:0
137-2516
+145354
1 REAL• cadeia de dígitos em forma decimal ou
exponencial.
& Exemplos:1.234
-0.01234+5632.3.374E30.3374E43374E0
João Miguel C. Sousa GCAR , DEM, IST 23
Tipos de dados e Identificadores
1 CHARACTER• cadeia de caracteres dentro dos seguintes:• 0,…9 A,…Z a,…,z ’ ” ( ) * + - / branco : = ! & $ ; < > % ? , .
& Exemplos:“PDQ123-A”“Miguel C. Silva”‘Miguel C. Silva’“Don’t”‘Don’’t’
1 Identificadores• nomes dados aos programas, constantes,
variáveis, etc. Devem começar por uma letra, e serem seguidos por quaisquer 30 digitos, letras ou “_” (sublinhado, underscore).
& Exemplos:MassaVelocidadeVelocidade_da_luz
João Miguel C. Sousa GCAR , DEM, IST 24
Variáveis
1 Compilador associa cada variável a um endereço em memória. Nomes das variáveis são identificadores.
Declaração de variáveis________________________________________________________
especificação_do_tipo :: lista
1 especificação_do_tipo pode ser dada por:REAL :: listaINTEGER :: listaCHARACTER(LEN = n) :: listaCHARACTER(n) :: listaCOMPLEXLOGICAL
& Exemplos:REAL :: Massa, Velocidade, AceleracaoINTEGER :: Soma, NumeroValoresCHARACTER(LEN = 15) :: Nome, ApelidoCHARACTER(15) :: Apelido*20, Inicial*1
7
João Miguel C. Sousa GCAR , DEM, IST 25
Variáveis (cont.)
1 Instrução IMPLICIT NONE• Cancela a convenção implícita do Fortran e
deve ser sempre incluída na zona de especificações.
1 Inicialização de variáveis na declaração• Quando são declaradas, as variáveis em Fortran
não têm um valor inicial.
Inicialização na declaração de variáveis______________________________________________________________
especificação_do_tipo :: lista
• Onde lista é dada por uma série de atribuições separadas por vírgulas do tipo:
Variavel = ExpressaoConstante
& Exemplo:REAL :: X = 1.0, Y = 2.5, Z = -2.9
João Miguel C. Sousa GCAR , DEM, IST 26
Constantes
1 Atributo PARAMETER• Constantes que aparecem repetidas vezes num
programa, tal como “pi”.
Declaração de constantes____________________________________________________________________
especificação_do_tipo, PARAMETER :: lista
1 Onde lista é dada por uma série de atribuições separadas por vírgulas do tipo:
Identificador = ExpressaoConstante
& Exemplos:INTEGER, PARAMETER :: Limite = 50REAL, PARAMETER :: Pi = 3.141593CHARACTER(2), PARAMETER :: Units = ‘cm’CHARACTER(*), PARAMETER :: Units = ‘cm’
CoordenadaX = Rate * COS(Pi * Time)
João Miguel C. Sousa GCAR , DEM, IST 27
Operadores aritméticos
1 Exemplos:+ Adição- Subtracção* Multiplicação / Divisão** Exponenciação
9.0 / 4.0→ 2.25
9 / 4→ 2
1 Combinação de reais e inteiros é possível, mas não deve ser utilizada! É um exemplo típico de mau estilo de programação!
3.0 + 8 / 5 → 3.0 + 1 → 3.0 + 1.0 → 4.0
3 + 8.0 / 5 → 3 + 8.0 / 5.0 → 3 + 1.6 →→ 3.0 + 1.6 → 4.6
João Miguel C. Sousa GCAR , DEM, IST 28
Operadores aritméticos (cont.)
1 Exponenciação2.0 ** 3 → 2.0 * 2.0 * 2.0 → 8.0
(-4.0) ** 2 → (-4.0) * (-4.0) → 16.0
2.0 ** 3.0 é avaliado como e3.0 ln(2.0), logo:(-4.0) ** 2.0 é indefinido!
• Devem-se assim evitar os expoentes reais, quando desnecessário
1 Regras de prioridade em operadores1 As exponenciações são efectuadas em primeiro
lugar da direita para a esquerda.
2 Multiplicações e divisões são efectuadas em seguida da esquerda para a direita.
3 Adições e subtrações são efectuadas por último também da esquerda para a direita.
8
João Miguel C. Sousa GCAR , DEM, IST 29
Funções intrínsecas
1 O Fortran tem algumas funções pré-definidas, tal como a raíz quadrada: SQRT
SQRT(argumento)
• A variável argumento deverá ser do tipo REAL. Se for INTEGER, dever-se-á calcular a raíz quadrada da seguinte forma:
• SQRT(REAL(NumeroInteiro))
1 Outras funções: ABS, SIN, COS, EXP, INT, FLOOR, LOG, REAL, INT, etc.
João Miguel C. Sousa GCAR , DEM, IST 30
Instrução de atribuição
variavel = expressao
1 O sinal “=” indica que o valor da expressao é atribuído a variavel.
& Exemplo:REAL :: CoordenadaX, CoordenadaYINTEGER :: Numero, Termo
CoordenadaX = 5.23CoordenadaY = SQRT(25.0)Numero = 17Termo = Numero / 3 + 2
CoordenadaX ?CoordenadaY ?
Numero ?Termo ?
João Miguel C. Sousa GCAR , DEM, IST 31
Atribuição (cont.)
CoordenadaX = 2.0 * CoordenadaX
1 Como se pode verificar, a memória foi actualizada com o novo valor atribuído a CoordenadaX. O valor antes atribuído perdeu-se!
Inteiro = Real / 2.0 → Má programação!Inteiro = INT(Real / 2.0)
CoordenadaX 5.23CoordenadaY 5.0
Numero 17Termo 7
CoordenadaX 10.46CoordenadaY 5.0
Numero 17Termo 7
João Miguel C. Sousa GCAR , DEM, IST 32
Atribuição de cadeia de caracteres
& Exemplo:
CHARACTER(5) :: String, Aumentada*10, Cortada
String = “alpha“
Aumentada = “particula“
Cortada = “temperatura“
1 Atribuição pelo Fortran:
1 A = B é equivalente a
1 B = A ?
String alphaAumentada particula_Cortada tempe
9
João Miguel C. Sousa GCAR , DEM, IST 33
Troca e somatório
1 Troca de valor entre duas variáveis
INTEGER :: Valor1, Valor2, Auxiliar…
Auxiliar = Valor1
Valor1 = Valor2
Valor2 = Auxiliar
1 Somatório
REAL :: Somatorio, Real…
Somatorio = Somatorio + Real
João Miguel C. Sousa GCAR , DEM, IST 34
Operações de Entrada e Saída
1 Fortran tem duas formas de Input/Output• Formato especificado pelo programador.• Formatos normalizados pré-determinados; são
formatos direccionados para listas.
Instruções simples de Saída_____________________________________________________
Formas:PRINT *, lista_de_saidaWRITE (*, *) lista_de_saida
& Exemplo:WRITE (*, *) “No tempo “, Tempo, “segundos“WRITE (*, *) “a velocidade vertical e“, &
Velocidade, “m/s“WRITE (*, *) “e a altitude e“, Altitude, “m“
1 Resultado obtido:No tempo 4.50000000 segundosa velocidade vertical e 45.8700752 m/se a altitude e 4.0570767E+02 m
João Miguel C. Sousa GCAR , DEM, IST 35
Operações de Entrada
Instruções simples de Entrada_____________________________________________________
Formas:
READ *, lista_de_dados
READ (*, *) lista_de_dados
• É processada uma linha de dados para cada instrução READ
• Variáveis são lidas até atingir o número de variáveis na lista_de_dados.
• Se existirem mais entradas do que na lista_de_dados, as restantes são ignoradas.
• As variáveis escritas devem ser constantes, e do tipo a ser atribuidas.
• Entradas consecutivas são separadas por uma vírgula ou um espaço em branco.
João Miguel C. Sousa GCAR , DEM, IST 36
Operações de Entrada (cont.)
& Exemplo numérico:READ (*, *) AltitudeInicial, Tempo
100.0, 4.5100.0 4.5
1 As variáveis do tipo carácter devem estar entre aspas se:• Ultrapassam uma linha• O valor contém brancos, “,” ou “/”.• O carácter começa com um apóstrofo, aspas ou
uma cadeia de digitos seguidos de um “*”.
& Exemplo com caracteres:CHARACTER(8) :: Unidade_1, Unidade_2...READ (*, *) Unidade_1, Unidade_2
metro, centimetro
10
João Miguel C. Sousa GCAR , DEM, IST 37
Programa Projectil
PROGRAM Projectil!------------------------------------------------------------! Este programa calcula a velocidade e a altitude de um! projectil, dados a altitude inicial, a velocidade inicial ! e a aceleração da gravidade. Variaveis usadas:! AltitudeInicial : altitude inicial do projectil (m)! Altitude : altitude para um dado tempo (m)! VelocidadeInicial : velocidade inicial do projectil(m/s)! Velocidade : velocidade vertical (m/s)! Aceleracao : aceleracao vertical (m/s2)! Tempo : tempo desde o lancamento (s)!! Entradas: AltitudeInicial, VelocidadeInicial, Tempo! Saidas: Altitude, Velocidade!---------------------------------------------------------IMPLICIT NONE REAL :: AltitudeInicial, VelocidadeInicial, Tempo, &
Altitude, Velocidade, Aceleracao = -9.80665
! Recebe valores AltitudeInicial, VelocidadeInicial, TempoWRITE (*, *) ”Escreva a altitude inicial(m) e a &
& velocidade(m/s):”READ (*, *) AltitudeInicial, VelocidadeInicial WRITE (*, *) ”Escreva o valor do tempo(s) pretendido:”READ (*, *) Tempo
! Calcula a quantidade restante para o tempo especificado. Altitude = 0.5 * Aceleracao * Tempo ** 2 &
+ VelocidadeInicial * Tempo + AltitudeInicialVelocidade = Aceleracao * Tempo + VelocidadeInicial
! Mostra Velocidade e AltitudeWRITE (*, *) ”No tempo ", Tempo, ”segundos”WRITE (*, *) ”a velocidade vertical e de”, Velocidade, "m/s”WRITE (*, *) ”e a altitude e de", Altitude, "metros”
STOPEND PROGRAM Projectil
João Miguel C. Sousa GCAR , DEM, IST 38
Resultados obtidos
Escreva a altitude inicial(m) e a velocidade(m/s):100.0 90.0 Escreva o valor do tempo(s) pretendido:4.5No tempo 4.5000000 segundosa velocidade vertical e de 45.8700752 m/se a altitude e de 4.050767E+2 metros
Escreva a altitude inicial(m) e a velocidade(m/s):150.0 100.0 Escreva o valor do tempo(s) pretendido:5.0No tempo 5.0000000 segundosa velocidade vertical e de 50.9667511 m/se a altitude e de 5.2741687E+2 metros
Escreva a altitude inicial(m) e a velocidade(m/s):150.0 100.0 Escreva o valor do tempo(s) pretendido:0No tempo 0.0000000E+00 segundosa velocidade vertical e de 1.0000000E+2 m/se a altitude e de 1.5000000E+2 metros
João Miguel C. Sousa GCAR , DEM, IST 39
Entrada/Saída com ficheiros
1 Entradas e saídas podem ser efectuadas para um ficheiro no disco
& Exemplo de um ficheiro dados.dat:
100.0 90.0 4.5
& Exemplo de um ficheiro result.dat:
No tempo 4.5000000 segundosa velocidade vertical e de 45.8700752 m/se a altitude e de 4.050767E+2 metros
OPEN (UNIT = numero_unidade, FILE = & nome_ficheiro, STATUS = estado)
& Exemplos anterioresOPEN (UNIT = 12, FILE = “dados.dat“, STATUS = “OLD“)OPEN (UNIT = 13, FILE = “result.dat“, STATUS = “NEW“)
READ (num_unidade, *) lista_dadosWRITE (num_unidade, *) lista_resultados
João Miguel C. Sousa GCAR , DEM, IST 40
Erros Aritméticos
1 Números reais são guardados em memória com mantissa e expoente:• mantissa: 24 bits
• expoente: 8 bits
• Quantidade de números finita
• Nem todos os números são representados
1 Erros de overflow e underflow• Para 8 bits no expoente os números
representados estão entre -1038 e 1038.
• Para números pequenos este intervalo varia entre -10-38 e 10-38.
m e
11
João Miguel C. Sousa GCAR , DEM, IST 41
Erros de arredondamento
1 Representação de números é aproximada• Reais não são representados exactamente
& Exemplo: equação que retorna sempre 1:
PROGRAM Demo_1
IMPLICIT NONEREAL :: A, B, C
READ (*, *) A, B, CC = ((A + B)**2 - 2.0*A*B - B**2) / A**2WRITE (*,*) C
END PROGRAM Demo_1
& Resultados obtidos num dado sistema:
A B C0.5 888.0 1.00000000.1 888.0 -6.24999950.05 888.0 -24.99999810.03 888.0 69.44444270.02 888.0 1.5625000E+02
A B AB BA
AA
+ − −= =
a f2 2
2
2
2
21
João Miguel C. Sousa GCAR , DEM, IST 42
Estruturas de Selecção
1 Estruturação de controlo em programação
• Sequenciação
• Selecção
• Repetição
1 Sequenciação
…
João Miguel C. Sousa GCAR , DEM, IST 43
Exemplos simples
& Exemplo 1: Índice de poluiçãoSe índice de poluição é maior do que 50,
Informar que a poluição é elevada;
Caso contrário,
Informar que as condições são seguras.
& Exemplo 2: Tipo de fluido num tuboSe número de Reynolds menor que x1,
Escoamento é laminar;
Se número de Reynolds se encotra entre x1 e x2,
Escoamento é instável;
Se número de Reynolds maior que x2,,
Escoamento é turbulento.
João Miguel C. Sousa GCAR , DEM, IST 44
Expressões lógicas
1 Podem ser simples ou compostas
1 Expressões simples:• constantes lógicas (.TRUE. e .FALSE.)
• variáveis lógicas (a ver mais à frente)
• expressões relacionais:
expressao_1 op_relacional expressao_2
1 Operadores relacionais
& Exemplos.TRUE.Numero == -999B ** 2 >= 4.0 * A * C
Símbolo Significado< ou .LT. Menor que> ou .GT. Maior que== ou .EQ. Igual a<= ou .LE. Menor ou igual a>= ou .GE. Maior ou igual a/= ou .NE. Diferente de
12
João Miguel C. Sousa GCAR , DEM, IST 45
Expressões lógicas (cont.)
1 Avaliação de caracteres• Cada carácter tem um número de ordem asso-
ciado dados por um código (ASCII, EBCDIC)1 Letras por ordem alfabética
1 Dígitos por ordem numérica
caracteres_1 < caracteres_2
& Exemplos“gato“ < “vaca“
“Junho“ > “Julho“
“cal“ > “calado“
“caløøø “ > “calado“
1 Expressões lógicas compostasOperador lógico Expressão lógica.NOT. .NOT. p.AND. p .AND. q.OR. p .OR. q.EQV. p .EQV. q.NEQV. p .NEQV. q
João Miguel C. Sousa GCAR , DEM, IST 46
Estruturas de selecção
Construção IF (forma simples)_____________________________________________________
Forma:
IF (expressao_logica) THEN
sequencia_instrucoes
END IF
• A sequencia_instrucoes só é executada se a expressao_logica for verdadeira.
& ExemploIF (X >= 0) THEN
Y = Z * X
Z = SQRT(X)
END IF
Instrução IF_____________________________________________________
IF (expressao_logica) THEN instrucao
João Miguel C. Sousa GCAR , DEM, IST 47
Construção IF
Construção IF (forma geral)_____________________________________________________
Forma:
IF (expressao_logica) THEN
sequencia_instrucoes1
ELSE
sequencia_instrucoes2
END IF
• A sequencia_instrucoes1 é avaliada se a expressao_logica for verdadeira.
• Caso contrário, são avaliadas as instruções em sequencia_instrucoes2
João Miguel C. Sousa GCAR , DEM, IST 48
Exemplo: Equações Quadráticas
Algoritmo1 Este algoritmo resolve uma equação quadrática do tipo
Ax2+Bx+C = 0. Se o discriminante B2-4AC é não negativo, as raízes reais Raiz_1 e Raiz_2 são calculadas. Caso contrário, é enviada uma mensagem indicando que não existem raízes reais.
1 Entradas: Os coeficientes A, B e C.
1 Saídas: As raízes da equação ou uma mensagem indicando que não existem raízes reais e o discriminante.
1 Recebe A, B e C.2 Calcula Discriminante = B ** 2 - 4 A * C3 Se Discriminante >= 0 faz o seguinte:
a) Calcula Discriminante = SQRT(Discriminante).
b) Calcula Raiz_1 = (- B + Discriminante)/(2*A).
c) Calcula Raiz_2 = (- B - Discriminante)/(2*A).
d) Mostra Raiz_1 e Raiz_2 ao utilizador.
4 Caso contrário faz o seguinte:
a) Mostra o Discriminante.
b) Envia mensagem de que não existem reaízes reais.
13
João Miguel C. Sousa GCAR , DEM, IST 49
Programa: Equações quadráticas (1)
PROGRAM Equacoes_Quadraticas!------------------------------------------------------------! Programa para resolver equacoes quadraticas usando a ! formula quadratica. Variaveis usadas:!! A, B, C : coeficientes da equacao quadratica! Discriminante : o discriminante B**2 - 4.0*A*C! Raiz_1, Raiz_2 : duas raizes da equacao!! Entradas: Coeficientes A, B, C! Saidas: As duas raizes ou o discriminante negativo e uma! mensagem indicando que nao ha raizes reais.!------------------------------------------------------------IMPLICIT NONE
REAL :: A, B, C, Discriminante, Raiz_1, Raiz_2
! Recebe os valores dos coeficientesWRITE (*, *) ”Escreva os coeficientes da equacao quadratica:”READ (*, *) A, B, C
! Calcula o discriminante Discriminante = B**2 - 4.0*A*C
João Miguel C. Sousa GCAR , DEM, IST 50
Programa: Equações quadráticas (2)
! Verifica se o discriminante e nao negativo. Se for calcula! as raizes e mostra o resultado. Caso contrário, mostra o! valor do discriminante e envia uma mensagem indicado que! nao existem raizes reaisIF (Discriminante >= 0) THEN
Discriminante = SQRT(Discriminante)Raiz_1 = (-B + Discriminante) / (2.0 * A)Raiz_2 = (-B - Discriminante) / (2.0 * A)WRITE (*, *) "As raizes sao", Raiz_1, Raiz_2
ELSEWRITE (*, *) ”O discriminante tem o valor”, DiscriminanteWRITE (*, *) ”Nao ha raizes reais”
END IF
END PROGRAM Equacoes_quadraticas
1 Exemplos de execução:Escreva os coeficientes da equacao quadratica:1, -5, 6As raizes sao 3.0000000 2.0000000
Escreva os coeficientes da equacao quadratica:1, 0, -4As raizes sao 2.0000000 -2.0000000
Escreva os coeficientes da equacao quadratica:1, 0, 4O discriminante tem o valor -16.0000000Nao ha raizes reais
João Miguel C. Sousa GCAR , DEM, IST 51
Construção de IFs encadeados
& Exemplo
1 Pode ser programado com dois IF encadeados:
IF (X <= 0) THENValorFuncao = -X
ELSEIF (X < 1.0) THEN
ValorFuncao = X ** 2ELSE
ValorFuncao = 1.0END IF
END IF
≥<<
≤−=
1x
10
0
,1
,
,
)( 2 x
x
x
x
xf
João Miguel C. Sousa GCAR , DEM, IST 52
Construção IF-ELSE IF
1 No caso de haver mais alternativas, existe uma estrutura própria para estes casos:
Construção IF-ELSE IF____________________________________________________________________
Forma:
IF (expressao_logica1) THEN
sequencia_instrucoes_1
ELSE IF (expressao_logica2) THEN
sequencia_instrucoes_2
ELSE IF (expressao_logica3) THEN
sequencia_instrucoes_3. . .ELSE
sequencia_instrucoes_n
END IF
14
João Miguel C. Sousa GCAR , DEM, IST 53
Exemplo: Índice de poluição
Algoritmo1 Este algoritmo lê três níveis de poluição e calcula um
índice de poluição em função desta leitura. Se o índice é inferior a um dado nível é enviada uma mensagem indicando que o ar é de boa qualidade; se está entre dois valores limites é enviada uma mensagem indicando que o ar é de qualidade razoável; e se o índice está acima do limite máximo é enviada uma mensagem indicando que o ar é de pobre qualidade.
1 Entradas: Os níveis Nivel_1, Nivel_2 e Nivel_3.
1 Constantes: Os limites LimiteInferior e Limite Superior.
1 Saídas: O Indice de poluição indicado numa mensagem.
1 Recebe Nivel_1, Nivel_2 e Nivel_3.2 Calcula Indice = (Nivel_1 + Nivel_2 + Nivel_3) / 3.3 Se Indice < LimiteInferior ,
Envia mensagem de “Boa qualidade do ar”Caso contrário se Indice < LimiteInferior ,
Envia mensagem de “Qualidade de ar razoável”.Caso contrário
Envia mensagem de “Qualidade de ar pobre”.
João Miguel C. Sousa GCAR , DEM, IST 54
Programa: Índice de poluição 1 (1)
PROGRAM Indice_Poluicao1!-----------------------------------------------------------! Programa que le 3 niveis de poluicao, calcula o indice de ! pooluicao com a sua media, e retorna a qualidade de ar ! Respectiva. Identificadores usados:! Nivel_1, Nivel_2, Nivel_3 : 3 valores de poluicao! LimiteInferior, LimiteSuperior : limites de poluicao! Indice : indice medio de poluicao!! Entradas: Os 3 niveis de poluicao! Constantes: Os limites de poluicao! Saidas: O indice de poluicao e a qualidade do ar. Sera! “boa” se indice for menor que LimiteInferior,! “razoavel” se indice estiver entre os dois! Limites e “pobre” caso contrario.!----------------------------------------------------------IMPLICIT NONE INTEGER :: Nivel_1, Nivel_2, Nivel_3, IndiceINTEGER, PARAMETER :: LimiteInferior = 25, LimiteSuperior =50
! Recebe os valores dos 3 niveis de poluicaoWRITE (*, *) ”Escreva as tres leituras de nivel de poluicao:”READ (*, *) Nivel_1, Nivel_2, Nivel_3
! Calcula o indice de poluicaoIndice = (Nivel_1 + Nivel_2 + Nivel_3) / 3
João Miguel C. Sousa GCAR , DEM, IST 55
Programa: Índice de poluição 1 (2)
! Classifica o indice de poluicao e retorna uma mensagem! indicando a qualidade do ar. IF (Indice < LimiteInferior) THEN
WRITE (*, *) ”Boa qualidade de ar"ELSE IF (Indice < LimiteSuperior) THEN
WRITE (*, *) ”Ar de qualidade razoavel"ELSE
WRITE (*, *) ”Ar de qualidade pobre"END IF
END PROGRAM Indice_Poluicao1
1 Exemplos de execução:Escreva as tres leituras de nivel de poluicao:30, 40, 50
Ar de qualidade razoavel
Escreva as tres leituras de nivel de poluicao:50, 60, 70
Ar de qualidade pobre
Escreva as tres leituras de nivel de poluicao:20, 21, 24
Boa qualidade de ar
João Miguel C. Sousa GCAR , DEM, IST 56
Construção CASE
Construção CASE____________________________________________________________________
Forma:
SELECT CASE (selector)CASE (lista_marcas_1)sequencia_instrucoes_1
CASE (lista_marcas_2)sequencia_instrucoes_2
. . .CASE (lista_marcas_n)
sequencia_instrucoes_nEND SELECT
1 Cada lista lista_marcas_i pode ter as formas:valorvalor_1 : valor_2valor_1 :: valor_2
1 Pode incluir-se o caso CASE DEFAULT
15
João Miguel C. Sousa GCAR , DEM, IST 57
Exemplo CASE
1 Pretende-se informar a classe (Infantil, Iniciado, Júnior, Sénior) consoante o número associado (1, 2, 3, 4).
SELECT CASE (CodigoClasse)CASE (1)
WRITE (*, *) “Infantil”CASE (2)
WRITE (*, *) “Iniciado”CASE (3)
WRITE (*, *) “Junior”CASE (4)
WRITE (*, *) “Senior”CASE DEFAULT
WRITE (*, *) “Codigo invalido”,& CodigoClasse
END SELECT
João Miguel C. Sousa GCAR , DEM, IST 58
Programa: Índice de poluição 2 (1)
PROGRAM Indice_Poluicao2!-----------------------------------------------------------! Programa que le 3 niveis de poluicao, calcula o indice de ! pooluicao com a sua media, e retorna a qualidade de ar ! Respectiva. Identificadores usados:! Nivel_1, Nivel_2, Nivel_3 : 3 valores de poluicao! LimiteInferior, LimiteSuperior : limites de poluicao! Indice : indice medio de poluicao!! Entradas: Os 3 niveis de poluicao! Constantes: Os limites de poluicao! Saidas: O indice de poluicao e a qualidade do ar. Sera! “boa” se indice for menor que LimiteInferior,! “razoavel” se indice estiver entre os dois! Limites e “pobre” caso contrario.!----------------------------------------------------------IMPLICIT NONE INTEGER :: Nivel_1, Nivel_2, Nivel_3, IndiceINTEGER, PARAMETER :: LimiteInferior = 25, LimiteSuperior =50
! Recebe os valores dos 3 niveis de poluicaoWRITE (*, *) ”Escreva as tres leituras de nivel de poluicao:”READ (*, *) Nivel_1, Nivel_2, Nivel_3
! Calcula o indice de poluicaoIndice = (Nivel_1 + Nivel_2 + Nivel_3) / 3
João Miguel C. Sousa GCAR , DEM, IST 59
Programa: Índice de poluição 2 (2)
! Classifica o indice de poluicao e retorna uma mensagem! Indicando a qualidade do ar. SELECT CASE (Indice)
CASE (:LimiteInferior - 1)WRITE (*, *) ”Boa qualidade de ar”
CASE (LimiteInferior : LimiteSuperior - 1)WRITE (*, *) ”Ar de qualidade razoavel"
CASE (LimiteSuperior:)WRITE (*, *) ”Ar de qualidade pobre"
END SELECT
END PROGRAM Indice_Poluicao2
1 Os resultados são exactamente os mesmos.
João Miguel C. Sousa GCAR , DEM, IST 60
Dados do tipo LOGICAL
1 Constantes do tipo lógico em Fortran:.TRUE.
.FALSE.
1 Especificação do tipo lógicoLOGICAL :: lista
variavel_logica = expressao_logica
& ExemplosExisteRaiz = Discriminante >= 0
WRITE (*, *) A, B, C, .TRUE., .FALSE.
• Produz:
_T_ F_F_T_F
onde “_” representa um espaço em branco.
16
João Miguel C. Sousa GCAR , DEM, IST 61
Estruturas de Repetição
1 Ciclos (loops)• Repetição controlada por contador
• Repetição controlada por expressão lógica
Ciclo DO controlado por contador____________________________________________________________________
Forma:
DO variavel_controlo = &
valor_inicial, limite, passo
sequencia_instrucoes
END DO
• Este ciclo implementa repetições onde o número desejado é conhecido antecipadamente.
João Miguel C. Sousa GCAR , DEM, IST 62
Ciclo DO controlado por contador
• Execução efectuada da seguinte forma:1. Atribuído valor inicial a variavel_controlo
2. A variavel_controlo é comparada com o limite onde é verificado se é:
a) menor ou igual a limite para um passopositivo;
b) maior ou igual a limite para um passonegativo.
3. Caso a) ou b) se verifique, o corpo do ciclo (a sequencia_instrucoes) é executado. O passo é somado à variavel_controlo e o ponto 2 é repetido. Caso contrário o ciclo termina.
& Exemplo 1DO Numero = 1, 7
WRITE (*, *) Numero, Numero ** 2END DO
João Miguel C. Sousa GCAR , DEM, IST 63
Exemplos ciclo DO com contador
• Saída do exemplo 1:1 12 43 94 165 256 367 49
& Exemplo 2DO Numero = 7, 1, -1
WRITE (*, *) Numero, Numero ** 2END DO
• Saída do exemplo 2:7 496 365 254 153 92 41 1
João Miguel C. Sousa GCAR , DEM, IST 64
Programa: Soma de inteiros
PROGRAM Soma_de_Inteiros!-----------------------------------------------------------! Programa que calcula a soma de um dado numero de ! numeros inteiros. Variaveis usadas:! Numero : o ultimo inteiro a ser somado! Soma : a soma 1 + 2 + ... + Numero! i : indice do ciclo DO!! Entrada: Numero! Saidas: Numero e Soma!----------------------------------------------------------IMPLICIT NONE INTEGER :: Numero, i, Soma = 0
WRITE (*, *) ”Este programa calcula a soma 1 + 2 + ... + &&Numero.”
WRITE (*, *) ”Escreva o numero inteiro:”READ (*, *) Numero
DO i = 1, NumeroSoma = Soma + i
END DO
WRITE (*, *) ”1 + 2 + ... +”, Numero, ”=”, Soma
END PROGRAM Soma_de_Inteiros
& Exemplo de execução:Este programa calcula a soma 1 + 2 + ... + Numero.Escreva o numero inteiro:101 + 2 + ... + 10 = 55
17
João Miguel C. Sousa GCAR , DEM, IST 65
Programa: Tabela de multiplicação
PROGRAM Tabela_de_Multiplicacao!-----------------------------------------------------------! Programa que calcula e mostra a lista do produto de dois! numeros. Variaveis usadas:! m, n : os dois numeros a ser multiplicados! Produto : o produto de m e n! Ultimo_m, Ultimo_n : ultimos valores a atribuir a m e n!! Entradas: Ultimo_m, Ultimo_n ! Saidas: Lista dos produtos m * n!----------------------------------------------------------IMPLICIT NONE INTEGER :: m, n, Produto, Ultimo_m, Ultimo_n
WRITE (*, *) ”Insira os ultimos valores dos dois numeros:”READ (*, *) Ultimo_m, Ultimo_nWRITE (*, *) ”m n m * n”WRITE (*, *) ”===========”DO m = 1, Ultimo_m
DO n = 1, Ultimo_nProduto = m * nWRITE (*, *) m, ” ”, n, ” ”, Produto
END DO END DO
END PROGRAM Tabela_de_Multiplicacao
João Miguel C. Sousa GCAR , DEM, IST 66
Tabela de multiplicação: resultados
& Resultado obtido:
Insira os ultimos valores dos dois numeros:4, 4m n m * n===========1 1 11 2 21 3 31 4 42 1 22 2 42 3 62 4 83 1 33 2 63 3 93 4 124 1 44 2 84 3 124 4 16
João Miguel C. Sousa GCAR , DEM, IST 67
Construção DO-EXIT
Ciclo DO-EXIT____________________________________________________________________
Forma:DO
sequencia_instrucoes_1IF (expressao_logica) EXITsequencia_instrucoes_2
END DO
q Tanto sequencia_instrucoes_1 comosequencia_instrucoes_2 podem ser omitidas.
q Número de repetições não é conhecido antecipadamente. Ciclo é repetido até a expressao_logica ser verdadeira.
q NOTA: Se a expressao_logica nunca for verdadeira, temos um ciclo infinito!
João Miguel C. Sousa GCAR , DEM, IST 68
Exemplo: Somatório
Algoritmo
1 Algoritmo para encontrar o Numero inteiro positivo mais pequeno para o qual a soma 1 + 2 + … + Numero é maior que um dado valor Limite especificado.
1 Entradas: Um valor inteiro Limite.
1 Saídas: O Numero e a Soma.
1 Recebe Limite.
2 Atribui 0 (zero) ao Numero.
3 Atribui 0 (zero) à Soma.
4 Repete o seguinte:
a) Se Soma > Limite termina a repetição; caso contrário continua com o seguinte.
b) Incremeta Numero de uma unidade.
c) Soma Numero e Soma.
5 Retorna Numero e Soma.
18
João Miguel C. Sousa GCAR , DEM, IST 69
Programa: Somatório
PROGRAM Soma_de_Inteiros!------------------------------------------------------------! Programa que encontra o Numero inteiro positivo mais ! pequeno para o qual a soma 1 + 2 + … + Numero, e maior que ! um dado valor Limite especificado. Variaveis usadas:! Numero : o numero corrente a ser adicionado! Soma : a soma 1 + 2 + … + Numero! Limite : valor limite especificado!! Entrada: Valor Limite inteiro! Saidas: Numero e o valor da Soma.!------------------------------------------------------------IMPLICIT NONE INTEGER :: Numero, Soma, Limite
! Recebe o valor do Limite, e inicializa Numero e SomaWRITE (*, *) ”Escreva o valor que excede a soma 1 + 2 +…+ ?:”READ (*, *) LimiteNumero = 0Soma = 0
! Repete ate a Soma exceder o LimiteDO
IF (Soma > Limite) EXIT ! termina repeticao! caso contrario continua com o seguinte:Numero = Numero + 1Soma = Soma + Numero
END DO
! Imprime os resultadosWRITE (*, *) ”1 + … +”, Numero, ”=”, Soma, ”>”, Limite
END PROGRAM Soma_Inteiros
João Miguel C. Sousa GCAR , DEM, IST 70
Somatório: Resultados
& Exemplos de execução:Escreva o valor que excede a soma 1 + 2 + … + ?:101 + … + 5 = 15 > 10
Escreva o valor que excede a soma 1 + 2 + … + ?:100001 + … + 141 = 10011 > 10000
Escreva o valor que excede a soma 1 + 2 + … + ?:-11 + … + 0 = 0 > -1
Numero Soma Soma < Limite Acção0 0 .TRUE. Executa corpo do ciclo1 1 .TRUE. Executa corpo do ciclo2 3 .TRUE. Executa corpo do ciclo3 6 .TRUE. Executa corpo do ciclo4 10 .TRUE. Executa corpo do ciclo5 15 .FALSE. Termina repetição
João Miguel C. Sousa GCAR , DEM, IST 71
Ciclos de entrada de dados
1 Teste no meio do ciclo repete o seguinte:1 Lê um dado valor de entrada.
2 Se o fim dos dados for encontrado, termina a re-petição; caso contrário é executado o seguinte:
3 Processa o valor recebido.
1 Para saber que os dados acabaram usam-se marcas (flag) ou IOSTAT=.
1 Os testes podem igualmente ser efectuados apenas no fim fo ciclo, garantindo que este é executado pelo menos uma vez.
João Miguel C. Sousa GCAR , DEM, IST 72
Ex: Conversão de Temperaturas
Algoritmo
1 Este algoritmo converte temperaturas de graus Celsius para a temperatura corrspondente em Fahrenheit. Os valores são processados até o utilizador indicar que não existem mais dados (temperaturas a converter).
1 Entradas: Temperaturas em Celsius.Resposta do utlizador
1 Saídas: Temperaturas em graus Fahrenheit.
1 Repetir o seguinte:
1 Lê a temperatura Celsius.
2 Calcula Fahrenheit = 1.8 * Celsius + 32.
3 Mostra a temperatura Fahrenheit.
4 Pergunta ao utlizador se existem mais temperaturas para converter.
5 Lê a resposta do utilizador (S ou N).
5 Se Resposta = “N”, termina a repetição
19
João Miguel C. Sousa GCAR , DEM, IST 73
Prog: Conversão Temperaturas (1)
PROGRAM Conversao_de_Temperatura!------------------------------------------------------------! Programa que converte temperaturas de graus Celsius para a! temperatura correspondente em Fahrenheit. Os valores são! processados até o utilizador indicar que não existem mais ! temperaturas a converter. Variaveis usadas:! Celsius : temperatura em graus Celsius! Fahrenheit : temperatura em graus Fahrenheit! Resposta : resposta do utilizador!! Entradas: Celsius, Resposta! Saida: Fahrenheit!------------------------------------------------------------IMPLICIT NONE REAL :: Celsius, FahrenheitCHARACTER (1) :: Resposta
! Ciclo-questionario que processa temperaturasDO
! Le temperatura em graus CelsiusWRITE (*, *) ”Escreva a temperatura em graus Celsius:”READ (*, *) Celsius
! Calcula a temperatura em graus Fahrenheit correspondenteFahrenheit = 1.8 * Celsius + 32
! Mostra valor da temperatura convertidoWRITE (*, *) Celsius, ”graus Celsius =”, &
Fahrenheit, ”graus Fahrenheit”
João Miguel C. Sousa GCAR , DEM, IST 74
Prog: Conversão Temperaturas (2)
! Pergunta ao utilizador se existem mais dadosWRITE (*, *)WRITE (*, *) ”Existem mais temperaturas a converter (S &
&ou N)?”READ (*, *) RespostaIF (Resposta == ”N”) EXIT
END DO
END PROGRAM Conversao_de_Temperatura
& Exemplos de execução:Escreva a temperatura em graus Celsius:0
0.0000000e+00 graus Celsius = 32.0000000 graus Fahrenheit
Existem mais temperaturas a converter (S ou N)?YEscreva a temperatura em graus Celsius:11.193
11.1929998 graus Celsius = 52.1473999 graus Fahrenheit
Existem mais temperaturas a converter (S ou N)?GdfffEscreva a temperatura em graus Celsius:-17.728
-17.7280006 graus Celsius = 8.9599609E-02 graus Fahrenheit
Existem mais temperaturas a converter (S ou N)?N
João Miguel C. Sousa GCAR , DEM, IST 75
Instrução CYCLE
1 Quando a condição do IF é satisfeita, mas não se pretende terminar o ciclo, como o faz a instrução EXIT, usa-se CYCLE. Esta instrução deve ser evitada!
& Exemplo no programa anterior:DO
! Le temperatura em graus CelsiusWRITE (*, *) ”Escreva a temperatura em graus Celsius:”READ (*, *) CelsiusIF (Celsius < 0.0)
WRITE (*, *) ”Temperatura deve ser maior ou &&igual a zero!”
CYCLEEND IF
! Calcula a temperatura em graus Fahrenheit correspondenteFahrenheit = 1.8 * Celsius + 32
! Mostra valor da temperatura convertidoWRITE (*, *) Celsius, ”graus Celsius =”, &
Fahrenheit, ”graus Fahrenheit”! Pergunta ao utilizador se existem mais dadosWRITE (*, *)WRITE (*, *), ”Existem temperaturas a converter (S ou N)?”READ (*, *) RespostaIF (Resposta == ”N”) EXIT
END DO
João Miguel C. Sousa GCAR , DEM, IST 76
Entrada / Saída
1 Tipos de entrada/saída em Fortran• direccionado para listas
• formatada
Instrução PRINT___________________________________________________________________
Forma:
PRINT especificacao_formato, lista_saida
1 Onde a especificacao _formato pode ser:1 * (um asterisco)
2 um carácter constante ou variável, expressão ou cadeia, cujo valor especifica o formato de saída
3 o rótulo de uma instruçao FORMAT.
1 A lista_saida é uma expressão separada por vírgulas, ou é vazia.
20
João Miguel C. Sousa GCAR , DEM, IST 77
Formatação de saída
Instrução FORMAT___________________________________________________________________
Forma:
rotulo FORMAT (lista_descritores)
1 O rotulo é dado por um inteiro de 1 a 99999.
& Exemplo:PRINT *, Numero, Temperatura
PRINT ‘(1X, I5, F8.2)’, Numero, Temperatura
PRINT 20, Numero, Temperatura
• Onde 20 é um rótulo com a segunte instrução:
20 FORMAT (1X, I5, F8.2)
1 Estas instruções imprimem as variáveis Numero e Temperatura da seguinte forma:
17 10.25000---------------
17 10.25--------------
João Miguel C. Sousa GCAR , DEM, IST 78
Descritores de formato
1 Caracteres de controlo
• Não serão assumidos como activos daqui em diante.
• Para os exemplos correrem em qualquer sistema, usar-se-á sempre um deles no início de cada especificação do formato de saída.
1 Saídas do tipo inteiro - Descritor IFormas:
rIw ou rIw.m onde:
I - dados do tipo inteirow - constante inteira indicando a largura do campor - indicador de repetiçãom - número mínimo de dígitos a serem impressos
Carácter decontrolo
Efeito
1X ou “ ” Espaçamento normal: avança para nova linha antes deimprimir
0 Espaçamento duplo: salta uma linha antes de imprimir1 Posiona-se no início de nova página antes de imprimir+ Reimprime sobre a última linha impressa
João Miguel C. Sousa GCAR , DEM, IST 79
Formatação de inteiros
& Exemplo 1:INTEGER :: Numero = 3, L = 5378, Kapa = -12345! (...)PRINT ‘(1X, 2I5.2, I7, I10.7)’, Numero, &
Numero - 3, L, KapaPRINT ‘(1X, 2I5.0, I7, I10)’, Numero, &
Numero - 3, L, Kapa
ouPRINT 31, Numero, Numero - 3, L, KapaPRINT 32, Numero, Numero - 3, L, Kapa31 FORMAT (1X, 2I5.2, I7, I10.7)32 FORMAT (1X, 2I5.0, I7, I10)
1 produz o seguinte:03 00 5378 -0012345
----------------------------3 5378 -12345
----------------------------
& Exemplo 2:PRINT ‘(1X, 4I3)’, Numero, Numero - 3, L, Kapa
1 retorna:03 0******
----------------
João Miguel C. Sousa GCAR , DEM, IST 80
Formatação de reais
1 Saídas do tipo real - Descritor FFormas:
rFw.d onde:
F - dados do tipo real (floating point)w - constante inteira indicando a largura do campod - número de dígitos à direita do ponto decimalr - indicador de repetição (constante do tipo inteiro)
& Exemplos:INTEGER :: Entrada = 625, Saida = -19REAL :: A = 7.5, B = .182, C = 625.327! (...)PRINT ‘(1X, 2I4, 2F6.3, F8.3)’, Entrada,Saida,A,B,C
ouPRINT 50, Entrada, Saida, A, B, C
50 FORMAT (1X, 2I4, 2F6.3, F8.3)
1 produz o seguinte:625 -19 7.500 0.182 625.327
-----------------------------
se (1X, 2I10, 3F10.2);625 -19 7.50 0.18 625.33
---------------------------------------------------
21
João Miguel C. Sousa GCAR , DEM, IST 81
Formatação de reais (cont.)
1 Saídas do tipo real - Descritor EFormas:
rEw.d ou rEw.dEe onde:
E - dados de saída do tipo exponencialw - constante inteira indicando a largura do campod - número digitos à direita do ponto decimalr - indicador de repetição (constante do tipo inteiro)e - número de posições usadas para o expoente
& Exemplo:REAL :: A = .12345E8, B = .0237, C = 4.6E-12, &
D = -76.1684E12 ! (...)PRINT ‘(1X, 2E13.5, E12.4, E13.4)’, A, B, C, D
1 produz o seguinte:
0.12345E+08 0.23700E-01 0.4600E-11 -0.7617E+14----------------------------------------------------
João Miguel C. Sousa GCAR , DEM, IST 82
Formatação de reais (concl.)
1 Saídas do tipo real - Descritores ES e ENFormas:
rESw.d ou rESw.dEe
rENw.d ou rENw.dEe, onde:
ES - descritor científico (scientific)1 mantissa entre 1 e 10
EN - descritor usado em engenharia1 mantissa entre 1 e 1000
& Exemplos:PRINT ‘(1X, 2ES13.5, ES12.4, ES13.4)’, A, B, C, D
1 produz:
1.23450E+07 2.37000E-02 4.6000E-12 -7.6168E+13----------------------------------------------------
PRINT ‘(1X, 2EN13.4, EN12.4, EN13.4)’, A, B, C, D
1 produz:
12.3450E+06 23.7000E-03 4.6000E-12 -76.1684E+12----------------------------------------------------
João Miguel C. Sousa GCAR , DEM, IST 83
Saídas com caracteres
Formas:rA ou rAw onde:
A - indica o tipo carácterw - constante inteira indicando a largura do campor - indicador de repetição
& Exemplo 1:REAL :: X = 0.3, Y = 7.9! (...)PRINT ‘(1X, “X =”, F6.2, “Y =”, F6.2)’, X, Y
ouPRINT 70, X, Y70 FORMAT (1X, “X =”, F6.2, “Y =”, F6.2)
ouPRINT ‘(1X, A, F6.2, A, F6.2)’, “X =”, X, “Y =”, Y
ouPRINT 71, “X =”, X, “Y =”, Y71 FORMAT (1X, A, F6.2, A, F6.2)
1 produz:X = 0.30 Y = 7.90--------------------
& Exemplo 2:PRINT 71, “Media e igual a”, Media_X, &
“e tem a variancia”, Variancia
João Miguel C. Sousa GCAR , DEM, IST 84
Descritores de posição X e T
Formas:
nX - onde n especifica o número de brancos a inserir
Tc - c indica o número do espaço na linha a escrever
& Exemplo:INTEGER :: Numero = 141! (...)PRINT 75, “Jose S. Silva”, “QED”, Numero
75 FORMAT (1X, A13, 3X, A3, 2X, I3)
ou75 FORMAT (1X, A13, T18, A3, 2X, I3)
1 produzem ambos:
Jose S. Silva QED 141-------------------------
& Outro FORMAT que produz a mesma saída:
75 FORMAT (1X, A13, 3X, A3, I5)
22
João Miguel C. Sousa GCAR , DEM, IST 85
Repetição e descritor “/”
1 Os parêntesis, tal como r, são indicadores de repetição1 A especificação de formato:‘(1X, A, F6.2, A, F6.2)´
• pode ser escrita de forma mais compacta:‘(1X, 2(A, F6.2))´
1 Descritor “/” - é usado para imprimir em várias linhas com diferentes formatos
& Exemplo:INTEGER :: N = 5173, M = 7623REAL :: A = 617.2, B = 29.25! (...)PRINT 88, “Valores”, N, A, M, B88 FORMAT (1X, A, 2/, 1X, 2(I10 F10.2))
1 produz:Valores-----------------------------------------
-----------------------------------------5173 617.20 7623 29.25
-----------------------------------------
João Miguel C. Sousa GCAR , DEM, IST 86
Formatação de entrada
Instrução READ___________________________________________________________________
Forma:
READ especificacao_formato, lista_entrada
1 Onde a especificacao _formato pode ser:
1 * (um asterisco)
2 um carácter constante ou variável, expressão ou cadeia, cujo valor especifica o formato de saída
3 o rótulo de uma instruçao FORMAT.
1 A lista_entrada é uma expressão separada por vírgulas, ou é vazia.
1 No tipo de saída 2 a cadeia de caracteres é dada por:• ‘lista_descritores_formato’,
• “lista_descritores_formato”, ou
• FORMAT (lista_descritores_formato)
João Miguel C. Sousa GCAR , DEM, IST 87
Descritores do formato de entrada
1 São essencialmente os mesmos dos de saída, com as nuances:• Entradas não podem ter caracteres constantes
• As vírgulas não são consideradas relevantes, excepto para o tipo carácter.
1 Leitura de inteiros com rIw• Os brancos são ignorados na leitura, excepto
quando o descritor BZ é utilizado.
• O número de posições w deve ser respeitado.
1 Leitura de reais com rFw.d ou E,EN,ES• Números podem ser dados sem pontos decimais
• Ponto decimal faz parte do número
1 Leitura de caracteres com rA e rAw• Quando READ contém uma cadeia de
caracteres, todos os caracteres no campo associado ao descritor A são lidos.
João Miguel C. Sousa GCAR , DEM, IST 88
Forma geral de saída
Instrução WRITE___________________________________________________________________
Forma:
WRITE (lista_controlo) lista_saida
1 Onde
• a lista_saida tem a mesma sintaxe da instrução PRINT.
• a lista_controlo deve incluir um especifi-cador de unidade de saída e um dos items:
1 um especificador de formato,2 uma instrução ADVANCE = ,
3 outros items para processamento de ficheiros.
1 Imprime os valores na lista_saida usando as especificações dadas na lista_controlo.
1 Especificação de unidade é definida como:• UNIT = especificador_unidade, ou
• especificador_unidade
23
João Miguel C. Sousa GCAR , DEM, IST 89
Instrução WRITE (concl.)
1 Especificação de formato é definido como:• FMT = especificador_formato, ou
• especificador_formato
1 A instrução ADVANCE = tem a forma:• ADVANCE = expressao_caracteres
& Exemplos:WRITE (6, *) Gravidade, Peso
WRITE (6, FMT = *) Gravidade, Peso
WRITE (UNIT = 6, FMT = *) Gravidade, Peso
WRITE (Unidade_Saida, *) Gravidade, Peso
WRITE (UNIT = Unidade_saida, FMT = *) &
Gravidade, Peso
!(...)
WRITE (6, ‘(1X, 2F10.2)’) Gravidade, Peso
WRITE (6, 30) Gravidade, Peso30 FORMAT (1X, 2F10.2)
João Miguel C. Sousa GCAR , DEM, IST 90
Forma geral de entrada
Instrução READ generalizada___________________________________________________________________
Forma:
READ (lista_controlo) lista_entrada
• a lista_entrada é uma variável, ou uma lista de variáveis separadas por vírgulas.
• a lista_controlo deve incluir um especifi-cador de unidade de saída e um dos items:
1 um especificador de formato,2 uma instrução ADVANCE = ,
3 uma instrução IOSTAT = ou uma instrução END = para detectar um erro de entrada ou um EOF (fim de ficheiro),
4 outros items para processamento de ficheiros.1 Lê os valores da lista_entrada usando as
especificações dadas na lista_controlo. 1 A especificação de unidade, a especificação de
formato e a instrução ADVANCE = são iguais às definidas em WRITE.
João Miguel C. Sousa GCAR , DEM, IST 91
Processamento de ficheiros
• Para grande quantidade de dados de entrada/saída.
1 Abertura de ficheiros
Instrução OPEN___________________________________________________________________
Forma:
OPEN (lista_abertura)
• a lista_abertura pode incluir:1 um especificador de unidade do tipo inteiro,2 instrução FILE = , fornece o nome do ficheiro a
abrir,3 instrução STATUS = , especifica o estado do
ficheiro,4 instrução ACTION = , especifica se o ficheiro é
de leitura, escrita, ou ambos,5 instrução POSITION = , posiciona o ficheiro,6 instrução IOSTAT = , indicando se o ficheiro
foi ou não aberto, etc.
João Miguel C. Sousa GCAR , DEM, IST 92
Instrução OPEN
1 Abre um ficheiro associado a um dado número de unidade, para operações de entrada/saída.
• A instrução FILE = tem a forma:1 FILE = expressao_caracteres
• STATUS = expressao_caracteres, pode ser dada por:
• “OLD”• “NEW”• “REPLACE”
• ACTION = accao_entrada-saida, pode ser dada por:
• “READ”• “WRITE”• “READWRITE”
• POSITION = expressao_caracteres, pode ser dada por:
• “REWIND”• “APPEND”• “ASIS”
• IOSTAT = estado_variável
24
João Miguel C. Sousa GCAR , DEM, IST 93
Exemplos da instrução OPEN
1 Ficheiro de entradaOPEN (UNIT = 12, FILE = “INFO.DAT”, STATUS = “OLD”, &ACTION = “READ”, POSITION = “REWIND”, &IOSTAT = EstadoAbertura)
CHARACTER(12) :: NomeFicheiro
WRITE (*, ‘(1X, A)’, ADVANCE = “NO”) &“Nome do ficheiro de entrada: ”
READ *, NomeFicheiro
OPEN (UNIT=12, FILE = NomeFicheiro, STATUS = “OLD”, &ACTION = “READ”, POSITION = “REWIND”, &IOSTAT = EstadoAbertura)
1 Ficheiro de saídaOPEN (UNIT = 13, FILE = “REPORT”, STATUS = “NEW”, &ACTION = “WRITE”, IOSTAT = EstadoAbertura)
WRITE (13, ‘(1X, I3, F7.0, F10.2)’) Codigo, &Temperatura, Pressao
João Miguel C. Sousa GCAR , DEM, IST 94
Fechar ficheiros
Instrução CLOSE___________________________________________________________________
Forma:CLOSE (lista_fecho)
• a lista_fecho pode incluir um especificador de unidade do tipo inteiro, podendo incluir outros items.
Instrução IOSTAT =___________________________________________________________________
Forma:IOSTAT = variavel_estado
• variavel_estado toma os valores:1 positivo, se ocorre um erro de leitura,2 negativo, se acabaram os dados de leitura,3 zero, caso contrário aos dois anteriores.
& Exemplo:DO
! Le os proximos valores de entradaREAD (12, *, IOSTAT = EstadoEntrada) Codigo, TempIF (EstadoEntrada < 0 ) EXIT ! Fim do ficheiro
! (...)END DO
João Miguel C. Sousa GCAR , DEM, IST 95
Outras instruções de Input/Output
Instrução END =___________________________________________________________________
Forma:
END = numero_instrucao
1 Posicionamento de instruções:
Instrução REWIND___________________________________________________________________
Forma:
REWIND unidade• Posiciona o ficheiro da unidade no seu início.
Instrução BACKSPACE___________________________________________________________________
Forma:
BACKSPACE unidade• Posiciona o ficheiro da unidade no início da linha
anterior à posição actual do cursor.
João Miguel C. Sousa GCAR , DEM, IST 96
Programação com Funções
1 Problemas complexos - divididos em subproblemas
1 Subprogramas• funções (function)
• subrotinas (subroutine)
1 Fortran contém funções intrínsecas, ou de biblioteca.1 Exemplos de funções intrínsecas: SQRT,ABS, SIN, EXP, INT, FLOOR, LOG, etc.
& ExemploINTEGER :: Numero_1, Numero_2, PequenoREAL :: Alfa, Beta, X
PRINT *, ABS(X)
Alfa = ANINT(100.0 * Beta) / 100.0
Pequeno = MIN (0, Numero_1, Numero_2)
25
João Miguel C. Sousa GCAR , DEM, IST 97
Subprogramas do tipo Função
1 O programador pode necessitar de definir funções (functions) em Fortran• As funções definidas pelo programador são
utilizadas da mesma forma que as funções pré-definidas.
Subprograma Função________________________________________________________
cabeçalho de funçãozona de especificaçõeszona de instruçõesEND FUNCTION nome_funcao
Cabeçalho de função_____________________________________________________________________
Forma:FUNCTION nome_funcao(lista_argumentos)
outipo FUNCTION nome_funcao(lista_argumentos)
João Miguel C. Sousa GCAR , DEM, IST 98
Cabeçalho de funções
1 Onde:• o nome_funcao pode ser qualquer
identificador válido em Fortran;• a lista_argumentos é um identificador ou
uma lista separada por vírgulas;• o tipo é um identificador opcional, que indica
o tipo dos argumentos retornados pela função.
1 Dá um nome à função e declara os seus argumentos.
1 A lista_argumentos é a lista dos parâmetros formais que servem para passar a informação do subprograma a outro programa.
João Miguel C. Sousa GCAR , DEM, IST 99
Definição de Funções
1 Zona de especificações dum subprograma é idêntica à zona de especificações de um programa, excepto:• Deve declarar o tipo da função, se este não tiver
sido declarado no cabeçalho;
• Deve declarar o tipo de cada um dos parâmetros formais. Deve igualmente conter um especificador INTENT.
1 Zona de instruções deve conter:nome_funcao = expressao
• onde expressao pode conter:1 qualquer expressão envolvendo constantes,
1 argumentos formais da função,
1 outras variáveis declaradas no subprograma,
1 referências para outras funções.
João Miguel C. Sousa GCAR , DEM, IST 100
Ex: Conversão de Temperaturas
1 Conversão graus Fahrenheit em Celsius:
Celsius = (Fahrenheit - 32) / 1.8
1 Cabeçalho:FUNCTION Fahr_em_Celsius(Temperatura)
1 Zona de especificações deve conter:REAL :: Fahr_em_Celsius
1 Outra possibilidade:REAL FUNCTION Fahr_em_Celsius(Temperatura)
1 A zona de declarações deve conter igualmente:REAL, INTENT(IN) :: Temperatura
26
João Miguel C. Sousa GCAR , DEM, IST 101
Conversão de Temperaturas (2)
!--Fahr_em_Celsius------------------------------! Funcao que converte uma temperatura em! graus Fahrenheit em graus Celsius!! Recebe: Temperatura em Fahrenheit ! Retorna: Temperatura em Celsius!------------------------------------------------
FUNCTION Fahr_em_Celsius(Temperatura)
REAL :: Fahr_em_CelsiusREAL, INTENT(IN) :: Temperatura
! Calcula a temperatura em graus CelsiusFahr_em_Celsius = (Temperatura - 32) / 1.8
END FUNCTION Fahr_em_Celsius
1 Formas de posicionar um subprograma:• antes de END PROGRAM , subprograma interno;
• num módulo, subprograma modular;• após END PROGRAM , subprograma externo.
João Miguel C. Sousa GCAR , DEM, IST 102
Secção de subprogramas
Secção de subprogramas________________________________________________________
Forma:CONTAINS
subprograma_1
subprograma_2
...
subprograma_n
1 onde cada subprograma_i é uma função ou subrotina que não contém subprogramas.
1 Com esta definição, os subprogramas são internos e podem ser apenas utilizados por este programa.
João Miguel C. Sousa GCAR , DEM, IST 103
Prog: Conversão Temperaturas (1)
PROGRAM Conversao_de_Temperatura1!------------------------------------------------------------! Programa que converte varias temperaturas de graus ! Fahrenheit na temperatura correspondente em Celsius.! A funcao Fahr_em_Celsius e utilizada para converter as! temperaturas. Identificadores usados:! Fahr_em_Celsius: funcao interna que converte ! temperaturas Fahrenheit em Celsius! TempFahrenheit: temperatura em Fahrenheit a converter! TempCelsius: temperatura em graus Celsius! Resposta: resposta do utilizador a pergunta! “Mais dados a converter?”!! Entradas: TempCelsius, Resposta! Saida: TempFahrenheit!------------------------------------------------------------IMPLICIT NONE REAL :: TempFahrenheit, TempCelsiusCHARACTER (1) :: Resposta
DO! Le temperatura em graus CelsiusWRITE (*, ‘(1X, A)’, ADVANCE = “NO”) “Escreva a &
& temperatura em graus Fahrenheit:”READ *, TempFahrenheit
! Usa a funcao Fahr_em_Celsius para converter temperaturaTempCelsius = Fahr_em_Celsius(TempFahrenheit)
! Mostra os resultadosPRINT ‘(1X, 2(F6.2, A))’, TempFahrenheit, & “em graus &
Fahrenheit e equivalente a ”, TempCelsius, “em Celsius”
João Miguel C. Sousa GCAR , DEM, IST 104
Prog: Conversão Temperaturas (1)
! Verifica se existem mais temperaturas a converterPRINT (*, ‘(/ 1X, A)’, ADVANCE = “NO”) &
”Existem mais temperaturas a converter (S ou N)?”READ *, RespostaIF (Resposta /= “S”) EXIT
END DO
CONTAINS
!--Fahr_em_Celsius--------------------------------! Funcao que converte graus Fahrenheit em Celsius!! Recebe: Temperatura em Fahrenheit ! Retorna: Temperatura em Celsius!-------------------------------------------------FUNCTION Fahr_em_Celsius(Temperatura)
REAL :: Fahr_em_CelsiusREAL, INTENT(IN) :: Temperatura
Fahr_em_Celsius = (Temperatura - 32.) / 1.8
END FUNCTION Fahr_em_Celsius
END PROGRAM Conversao_de_Temperatura1
& Exemplo de execução:Escreva a temperatura em graus Fahrenheit: 3232.00 em graus Fahrenheit e equivalente a 0.00 em Celsius
Existem mais temperaturas a converter (S ou N)? N
27
João Miguel C. Sousa GCAR , DEM, IST 105
Associação de argumentos
1 Referência a uma função:nome_funcao(lista_argumentos)
1 Inclusão de INTENT(IN)assegura que• o valor do argumento actual é passado ao
argumento formal;
• o valor do argumento formal não é alterado enquanto a função estiver a ser executada.
1 Se INTENT(IN) não é utilizado, uma alteração do argumento formal implica uma alteração do argumento actual!
1 O número e o tipo dos argumentos actuais devem corresponder aos dos argumentos formais.
João Miguel C. Sousa GCAR , DEM, IST 106
Função factorial
1 Esta função contém uma variável local
!--Factorial---------------------------------------! Funcao que calcula o factorial N! de N,! Que e 1 se N = 0, e 1 * 2 * … * N se N > 0.!! Recebe: Inteiro N! Retorna: Inteiro N!!! Nota : I e uma variavel interna do tipo! Inteiro, usada como contador!------------------------------------------------
FUNCTION Factorial(N)
INTEGER :: FactorialINTEGER, INTENT(IN) :: NINTEGER :: I
Factorial = 1DO I = 2, N
Factorial = Factorial * IEND DO
END FUNCTION Factorial
João Miguel C. Sousa GCAR , DEM, IST 107
Alcance
1 Entidades como variáveis, constantes, tipos e subprogramas podem ser declaradas em vários pontos.
1 As partes do programa onde esses items são visíveis constitui o seu alcance.
1 Princípio fundamental do alcance• Alcance de uma entidade é o programa ou
subprograma onde é declarado.
1 1ª regra do alcance• Items declarados em subprogramas não são
acessíveis fora deste; são items locais.
1 2ª regra do alcance• Items declarados no programa principal são
entidades globais, e são acessíveis em qualquer subprograma interno, excepto naqueles onde entidades locais tenham o mesmo nome.
João Miguel C. Sousa GCAR , DEM, IST 108
Módulos
1 Programação modular• Blocos principais são facilmente identificados,
colocados em subprogramas individualizados, e testados separadamente.
• Programas mais simples de desenvolver, testar, perceber e modificar.
Módulos (versão simplificada)____________________________________________________________
Forma:MODULE nome_moduloCONTAINS
subprograma_1
subprograma_2
...
subprograma_n
END MODULE nome_modulo
1 onde cada subprograma_i são subrotinas ou funções. São chamados subprogramas módulo.1 Conjunto de subprogramas constitui uma biblioteca
28
João Miguel C. Sousa GCAR , DEM, IST 109
Exemplo de biblioteca
1 Biblioteca de conversão de temperaturasMODULE Biblioteca_Temperatura!------------------------------------------------------------! Modulo que contem os seguintes subprogramas para! conversao de temperaturas:! Fahr_em_Celsius - conversao de Fahreneit em Celsius ! Celsius_em_Fahr - conversao de Celsius em Fahreneit !------------------------------------------------------------
IMPLICIT NONE
CONTAINS
!--Fahr_em_Celsius--------------------------------! Funcao que converte graus Fahrenheit em Celsius! Recebe: Temperatura em Fahrenheit ! Retorna: Temperatura em Celsius!-------------------------------------------------
FUNCTION Fahr_em_Celsius(Temperatura)
REAL :: Fahr_em_CelsiusREAL, INTENT(IN) :: Temperatura
Fahr_em_Celsius = (Temperatura - 32) / 1.8
END FUNCTION Fahr_em_Celsius
João Miguel C. Sousa GCAR , DEM, IST 110
Biblioteca temperaturas (concl.)
!--Celsius em_Fahr---------------------------------! Funcao que converte graus Celsius em Fahrenheit! Recebe: Temperatura em Celsius! Retorna: Temperatura em Fahrenheit!--------------------------------------------------
FUNCTION Celsius_em_Fahr(Temperatura)
REAL :: Celsius_em_FahrREAL, INTENT(IN) :: Temperatura
Celsius_em_Fahr = 1.8 * Temperatura + 32
END FUNCTION Celsius_em_Fahr
! Outras funcoes relacionadas com temperatura …
END MODULE Biblioteca_Temperatura
1 Utilização de módulos
Instrução USE______________________________________________________
Forma:USE nome_modulo
USE nome_modulo, ONLY: lista
João Miguel C. Sousa GCAR , DEM, IST 111
Compilação e ligação de módulos
1 Compilação - programa fonte convertido em linguagem-máquina. Cria os ficheiros objecto(.OBJ em DOS)
1 Ligação - funções contidas em módulos são ligadas ao programa principal, criando o programa executável, guardado num ficheiro executável(.EXE em DOS)
João Miguel C. Sousa GCAR , DEM, IST 112
Funções recursivas
1 Função recursiva - função que se chama a ela própria.
& Exemplo: função factorial
• 0! = 1
• n! = n (n - 1)! , se n > 0
1 Função definida recursivamente:1 Âncora, ou caso mais simples;
2 Passo recursivo, onde os valores são definidos com base nos anteriores.
& Exemplo para 4!
4! = 4 3!, etc.
×
×
29
João Miguel C. Sousa GCAR , DEM, IST 113
Definição de funções recursivas
1 Em Fortran são definidas com• RECURSIVE no cabeçalho• RESULT no fim do cabeçalho, indicando a
variável a retornar o valor da função, em vez da própria função. O tipo da função será o tipo desta variável.
& Função Fortran para factorial!--Factorial---------------------------------------! Funcao que calcula factoriais recursivamente!! Recebe: inteiro n >= 0! Retorna: n!!--------------------------------------------------
RECURSIVE FUNCTION Factorial(n) RESULT(Fact)
INTEGER :: Fact ! Variavel com resultadoINTEGER, INTENT(IN) :: n
IF (n == 0) THENFact = 1
ELSEFact = n * Factorial(n - 1)
END IF
END FUNCTION Factorial
João Miguel C. Sousa GCAR , DEM, IST 114
Programação com Subrotinas
1 Análise top-down: problemas complexos divididos em subproblemas
1 Diferenças entre funções e subrotinas• Subrotinas podem retornar mais de um ou
nenhum valor ao programa principal.
• As funções retornam valores através do nome; subrotinas retornam através de argumentos.
• Uma função é chamada pelo seu nome, enquanto uma subrotina usa instrução CALL
Subprograma Subrotina________________________________________________________
cabeçalho de subrotinazona de especificaçõeszona de instruçõesEND SUBROUTINE nome_subrotina
João Miguel C. Sousa GCAR , DEM, IST 115
Subrotinas - definições
Cabeçalho de subrotina_____________________________________________________________________
Forma:SUBROUTINE nome_subrotina(lista)
ouRECURSIVE SUBROUTINE nome_subrotina(lista)
1 Onde:• o nome_subrotina pode ser qualquer
identificador válido em Fortran;• a lista é um identificador ou uma lista
separada por vírgulas.
1 Dá um nome à subrotina e declara os seus argumentos.
1 A lista contém os parâmetros formais, que servem para passar a informação de e para a subrotina.
João Miguel C. Sousa GCAR , DEM, IST 116
Instrução CALL
Instrução CALL___________________________________________________________________
Forma:CALL nome_subrotina(lista)
1 Onde:• o nome_subrotina constitui o nome da
subrotina a ser chamada;• a lista contém as variáveis, constantes ou
expressões constituindo os parâmetros actuais. Os tipos dos parâmetros actuais e formais devem coincidir.
30
João Miguel C. Sousa GCAR , DEM, IST 117
Ex: Conversão coordenadas
& Conversão coordenadas polares em cartesianas
x = r cos θy = r sin θ
!--Converte_em_Cartesianas------------------------! Subrotina que converte coordenadas polares! em cartesianas.!! Recebe: Coordenadas polares R e Theta(radianos)! Retorna: Coordenadas cartesianas X e Y!-------------------------------------------------
SUBROUTINE Converte_em_Cartesianas(R, Theta, X, Y)
REAL, INTENT(IN) :: R, ThetaREAL, INTENT(OUT) :: X, Y
X = R * COS(Theta)Y = R * SIN(Theta)
END SUBROUTINE Converte_em_Cartesianas
João Miguel C. Sousa GCAR , DEM, IST 118
Prog: Conversão coordenadas (1)
PROGRAM Polar_em_Cartesianas!------------------------------------------------------------! Programa que aceita coordenadas polares num ponto, e mostra ! as coordenadas cartesianas correspondentes. A subrotina! interna Converte_em_Cartesianas e utilizada para a! conversao. Variaveis usadas:! CoordR, CoordT : coordenadas polares de um ponto ! CoordX, CoordY : coordenadas cartesianas de um ponto ! Resposta: : Se sim existem mais dados a converter!! Entradas: CoordR, CoordT, Resposta! Saidas: CoordX, CoordY !------------------------------------------------------------IMPLICIT NONE REAL :: CoordR, CoordT, CoordX, CoordY CHARACTER (1) :: Resposta
! Le e converte coordenadas até nao haver mais dadosDO
WRITE (*, ‘(1X, A)’, ADVANCE = “NO”) & “Escreva as cordenadas polares R e Theta(radianos):”
READ *, CoordR, CoordT
CALL Converte_em_Cartesianas(CoordR, CoordT, &CoordX, CoordY)
! Mostra os resultadosPRINT *, “Coordenadas cartesianas:”, CoordX, CoordYWRITE (*, ‘(1X, A)’, ADVANCE = “NO”) &
“Mais coordenadas a converter? (S ou N)?”READ *, ResponseIF (Response /= “S”) EXIT
END DO
João Miguel C. Sousa GCAR , DEM, IST 119
Prog: Conversão coordenadas (2)
CONTAINS
!--Converte_em_Cartesianas------------------------! Subrotina que converte coordenadas polares! em cartesianas.!! Recebe: Coordenadas polares R e Theta(radianos)! Retorna: Coordenadas cartesianas X e Y!-------------------------------------------------
SUBROUTINE Converte_em_Cartesianas(R, Theta, X, Y)
REAL, INTENT(IN) :: R, ThetaREAL, INTENT(OUT) :: X, Y
X = R * COS(Theta)Y = R * SIN(Theta)
END SUBROUTINE Converte_em_Cartesianas
END PROGRAM Polar_em_Cartesianas
& Exemplo de execução:Escreva as cordenadas polares R e Theta(radianos): 1.0, 0Coordenadas cartesianas: 1.0000000 0.0000000E+00
Mais coordenadas a converter? (S ou N)? SEscreva as cordenadas polares R e Theta(radianos): 1.0, 1.57Coordenadas cartesianas: 7.9627428E-04 0.9999997
Mais coordenadas a converter? (S ou N)? N
João Miguel C. Sousa GCAR , DEM, IST 120
Associação de argumentos
1 Quando a instrução CALL é executada:CALL Converte_em_Cartesianas(CoordR, CoordT, &
CoordX, CoordY)
1 Após a execução da subrotina:
1 Se os parâmetros formais forem declarados com INTENT(INOUT):
parâmetro_actual ← → parâmetro formal
ParâmetrosActuais
ParâmetrosFormais
CoordR → RCoordT → ThetaCoordX XCoordY Y
ParâmetrosActuais
ParâmetrosFormais
CoordR → RCoordT → ThetaCoordX ← XCoordY ← Y
31
João Miguel C. Sousa GCAR , DEM, IST 121
Números aleatórios
1 Gerador de números aleatórios• Não é possível em computador; geram-se assim
números pseudo-aleatórios.1 O valor inicial é dado por uma semente, dada
por RANDOM_SEED em Fortran 90.
1 Cada novo número aleatório obtido é utilizado no cálculo do seguinte. Operação efectuada pela subrotina RANDOM_NUMBER. Produz números aleatórios entre 0 e 1 com distribuição uniforme.
& Exemplo: Lançar dois dados
! Introduz um valor para a sementeCALL RANDOM_SEED!…CALL RANDOM_NUMBER(R1)CALL RANDOM_NUMBER(R2)Dado_1 = 1 + INT(6*R1)Dado_2 = 1 + INT(6*R2)Par = Dado_1 + Dado_2
1 Onde R1 e R2 são dois números aleatórios, e Par é a soma dos valores dos dois dados.
João Miguel C. Sousa GCAR , DEM, IST 122
Subprogramas como parâmetros
1 Subprogramas podem ser parâmetros• devem ser modulares, externos ou intrínsecos;
• Não podem usar o atributo INTENT
& Exemplo: Integral
PROGRAM Integral_Numerico!------------------------------------------------------------! Programa que aproxima o integral de uma função no! intervalo [A,B] usando o metodo de aproximacao trapezoidal, ! calculada pela subrotina Integral; o integrando e o # de ! subintervalos são passados como parametros para Integral. A ! funcao Integrando e importada do modulo Funcao_Integrando. ! Identificadores usados:! A, B : limites do intervalo de integracao! Integral: subrotina que aproxima o integral de F em[A,B]! Integrando: o integrando! Numero_subintervalos: # de subintervalos em que [A,B] e ! subdividido!! Entradas: A, B, , Numero_subintervalos! Saidas: Aproximacao do integral de F em [A,B] !------------------------------------------------------------
f x dxa
b
( )z
João Miguel C. Sousa GCAR , DEM, IST 123
Prog: Integral numérico (cont.)
USE Funcao_integrando ! Modulo contendo integrando
IMPLICIT NONE REAL :: A, BINTEGER :: Numero_subintervalos
WRITE (*, ‘(1X, A)’, ADVANCE = “NO”) & “Escreva os limites do intervalo e o # de subintervalos:”
READ *, A, B, Numero_subintervalos
CALL Integral(Integrando, A, B, Numero_subintervalos)
CONTAINS
!--Integral-----------------------------------------------! Subrotina que calcula a aproximacao trapezoidal! do integral da funcao F no intervalo [A,B] usando! N subintervalos. Variaveis locais:! I : contador! DeltaX : comprimento dos subintervalos! X : ponto de subdivisao! Y : valor da funcao no ponto X! Soma : soma aproximada!! Recebe: Funcao F, limites A, B e numero N subintervalos! Retorna: Valor aproximado do integral F em [A,B]!---------------------------------------------------------SUBROUTINE Integral (F, A, B, N)
REAL, INTENT(IN) :: A, BINTEGER, INTENT(IN) :: NREAL :: F, DeltaX, X, Y, SomaINTEGER :: I
João Miguel C. Sousa GCAR , DEM, IST 124
Prog: Integral numérico (concl.)
! Calcula comprimento dos subintervalos! e inicializa as aproximacoes Soma e XDeltaX = (B - A)/ REAL(N)X = ASoma = 0.0
! Calcula a soma aproximadaDO I = 1, N - 1
X = X + DeltaXY = F(X)Soma = Soma + X
END DOSoma = DeltaX * ((F(A) + F(B)) / 2.0 + SomaPRINT 10, Numero_subintervalos, Soma10 FORMAT (1X, “Aproximacao trapezoidal usando”, I4, &
“subintervalos e de”, F10.5)END SUBROUTINE Integral
END PROGRAM Integral_Numerico
!-----------------------------------------------------------
MODULE Funcao_integrando!------------------------------------------------------! Modulo contendo a funcao Integrando!------------------------------------------------------CONTAINS
FUNCTION Integrando(X)REAL :: IntegrandoREAL, INTENT(IN) :: XIntegrando = EXP(X**2)
END FUNCTION Integrando
END MODULE Funcao_integrando
32
João Miguel C. Sousa GCAR , DEM, IST 125
Subprogramas e parâmetros (concl.)
1 Subprogramas como parâmetros:• externos - declarados após END PROGRAM
• intrínsecos - funções pré-definidas em Fortran, como SIN
1 Fortran não controla directamente número de parâmetros de uma função. Para isso usam-se blocos INTERFACE contendo:• Tipo do valor retornado pela função
• Número de argumentos e tipo de cada um deles
& Exemplo com a função Integrando:
INTERFACEFUNCTION Integrando(X)REAL :: IntegrandoREAL, INTENT(IN) :: X
END FUNCTION IntegrandoEND INTERFACE
João Miguel C. Sousa GCAR , DEM, IST 126
Inteligência Artificial
1 Projecta sistemas computacionais com características associadas à inteligência humana, tais como:• aprendizagem
• raciocínio deductivo
• linguagem natural
• reconhecimento e processamento de imagens
1 Áreas da AI• Sistemas periciais (controlo, consultadoria, etc.)
• Reconhecimento de padrões (voz, escrita, etc.)
• Visão computacional
• Robótica (máquinas sensoriais)
• Técnicas de procura (procura na Internet)
• Jogos
1 Muitos destes problemas são recursivos
João Miguel C. Sousa GCAR , DEM, IST 127
Subrotinas recursivas
1 Problema: Torres de Hanoi
Figura da página 495!!
1 Pretende-se resolver o puzzle da figura, onde se devem mover os discos do poste da esquerda para a direita, seguindo as seguintes regras:1 Quando um disco é movido, deve ser
posicionado no topo de um dos postes.2 Só se pode mover um disco de cada vez, e este
deve ser o do topo de um dos postes.3 Um disco maior nunca pode estar situado em
cima de um mais pequeno.
1 Problema simples para um número pequeno de discos; torna-se difícil para mais discos (7, 8, etc.)
João Miguel C. Sousa GCAR , DEM, IST 128
Exemplo: Torres de Hanoi
Algoritmo1 Este algoritmo recursivo resolve o puzzle das Torres de
Hanoi.
1 Entradas: Número N de discos a mover.
1 Saídas: A sequência de movimentos a efectuar de forma a resolver o puzzle.
1 Recebe N.2 Se existe um disco:
Passo mais simples:Move o disco do poste A para C, resolvendo o puzzle.
4 Caso contrário faz o seguinte:
Passo recursivo:a) Move os N - 1 discos do poste A para o poste B,
usando o poste C como poste auxiliar.
b) Move o disco maior restante de A para C.c) Move os N - 1 discos do poste B para o poste C,
usando o poste A como poste auxiliar.
33
João Miguel C. Sousa GCAR , DEM, IST 129
Programa: Torres de Hanoi
PROGRAM Torres_de_Hanoi!----------------------------------------------------------! Programa que resolve o puzzle das Torres de Hanoi de uma! forma recursiva, usando a subrotina Move. Identificadores:! Poste_1, Poste_2, Poste_3 : marcas dos postes!! Numero_Discos : numero de discos! Move : Subrotina para mover os discos!! Entrada : Numero_Discos! Saidas : Sequencia de movimntos que resolve o puzzle!------------------------------------------------------------IMPLICIT NONE CHARACTER(*), PARAMETER :: Poste_1 = “A”, Poste_2 = “B”, &
Poste_3 = “C”, INTEGER :: Numero_discos
WRITE (*, ‘(1X, A)’, ADVANCE = “NO”) &“Escreva o numero de discos:”
READ *, Numero_discosPRINT *CALL Move(Numero_discos, Poste_1, Poste_2, Poste_3)
CONTAINS!--Move---------------------------------------------------! Subrotina recursiva que move N discos de PosteInicial ! para PosteFinal usando um poste auxiliar. Variaveis:! N : numero de discos! PosteInic : poste contendo os discos! PosteFin : poste onde ficarao os discos! PosteAux : poste auxiliar de armazenamento!! Recebe : N, PosteInic, PosteFin, PosteAux ! Retorna: Sequencia de movimentos a efectuar!---------------------------------------------------------
João Miguel C. Sousa GCAR , DEM, IST 130
Programa: Torres de Hanoi (concl.)
RECURSIVE SUBROUTINE Move(N, PosteInic, PosteAux, PosteFin)
INTEGER, INTENT(IN) :: NCHARACTER, INTENT(IN) :: PosteInic, PosteAux, PosteFin
IF (N == 1) THEN ! Caso mais simplesPRINT *, “Move disco de”, PosteInic, “para ”,PosteFin
ELSE ! Passo recursivo! Move n -1 discos de PosteInic para PosteAux! utilizando PosteFin como poste auxiliarCALL Move(N - 1, PosteInic, PosteFin, PosteAux)
! Move disco de PosteInic para PosteFinCALL Move(1, PosteInic, “ ”, PosteFin)
! Move n -1 discos de PosteAux para PosteFin! utilizando PosteInic como poste auxiliarCALL Move(N - 1, PosteAux, PosteInic, PosteFin)
END IF
END SUBROUTINE Move
END PROGRAM Torres_de_Hanoi
João Miguel C. Sousa GCAR , DEM, IST 131
Exemplo de execução
Escreva o numero de discos: 4
Move disco de A para BMove disco de A para CMove disco de B para CMove disco de A para BMove disco de C para AMove disco de C para BMove disco de A para BMove disco de A para CMove disco de B para CMove disco de B para AMove disco de C para AMove disco de B para CMove disco de A para BMove disco de A para CMove disco de B para C
João Miguel C. Sousa GCAR , DEM, IST 132
Tabelas unidimensionais
1 Tipos de dados simples:• real,
• inteiro,
• complexo, etc.
1 Necessidade de processamento de vários valores simultaneamente pode tornar-se muito moroso. Exemplos:• Lista de resultados
• Conjunto de medidas
• matrizes, etc.
1 Tipos de dados estruturados• Tabelas• Fichas
34
João Miguel C. Sousa GCAR , DEM, IST 133
Exemplo: Detecção de avarias
1 Este programa recebe os tempos de avaria de vários componentes e pretende-se saber como medida de fiabilidade o tempo médio de falha de cada um dos componentes. O programa deverá seguir os seguintes passos:
1 Calcular o tempo médio de avaria.
2 Imprimir a lista de avarias maior do que a média.
3 Ordenar os tempos de avaria de forma ascendente.
1 A lista de avarias é assim processada várias vezes. São propostas duas soluções:
• Utilizar uma variável para cada tempo de avaria
• Reler os dados sem atribuir um a cada variável
• Utilizar uma tabela unidimensional
João Miguel C. Sousa GCAR , DEM, IST 134
Programa: Tempos_de_avaria1 (1)
1 Esboço do programa:PROGRAM Tempos_de_avaria1!-----------------------------------------------------------! Descricao do programa e das variaveis utilizadas.!-----------------------------------------------------------IMPLICIT NONE
INTEGER :: EstadoAbertura, EstadoEntradaREAL :: TempoAvaria_1, TempoAvaria_2, TempoAvaria_3, &
TempoAvaria_4, TempoAvaria_5, TempoAvaria_6, & ! etc.
TempoAvaria_48, TempoAvaria_49, TempoAvaria_50, &Tempo_Medio_Avaria
! Le os tempos de avariaOPEN (UNIT = 10, FILE = “TEMP_IN.DAT”, STATUS = “OLD”, &
IOSTAT = EstadoAbertura)IF (EstadoAbertura > 0)
WRITE (*, *) “Ficheiro nao disponivel!”ELSE
READ (10, *, IOSTAT = EstadoEntrada) &TempoAvaria_1, TempoAvaria_2, TempoAvaria_3, &TempoAvaria_4, TempoAvaria_5, TempoAvaria_6, & ! etc. TempoAvaria_48, TempoAvaria_49, TempoAvaria_50, &
IF (EstadoEntrada > 0) WRITE(*, *) “Erro na entrada de dados”
ELSE IF (EstadoEntrada < 0) WRITE(*, *) “Dados insufucientes”
ELSE
João Miguel C. Sousa GCAR , DEM, IST 135
Programa: Tempos_de_avaria1 (2)
Tempo_Medio_Avaria = &(TempoAvaria_1 + TempoAvaria_2 + TempoAvaria_3 + &TempoAvaria_4 + TempoAvaria_5, TempoAvaria_6, & ! etc.TempoAvaria_46 + TempoAvaria_47 + TempoAvaria_48 + &TempoAvaria_49 + TempoAvaria_50) / 50.0
WRITE (*, *) “Tempo medio de avaria =”, & Tempo_Medio_Avaria
! Mostra tempos acima da médiaIF (TempoAvaria_1 > Tempo_Medio_Avaria) &
WRITE (*, *) TempoAvaria_1IF (TempoAvaria_2 > Tempo_Medio_Avaria) &
WRITE (*, *) TempoAvaria_2IF (TempoAvaria_3 > Tempo_Medio_Avaria) &
WRITE (*, *) TempoAvaria_3!! etc., etc., etc.!IF (TempoAvaria_50 > Tempo_Medio_Avaria) &
WRITE (*, *) TempoAvaria_50
! Apos 200 linhas de codigo, ordenar os valores?!!! Deve existir uma forma melhor de programar!!
END PROGRAM Tempos_de_avaria1
1 Outra solução:• Reler os dados várias vezes para cada um dos
cálculos necessários.
João Miguel C. Sousa GCAR , DEM, IST 136
Tabelas
1 As soluções propostas são ineficientes; é necessária uma estrutura de dados para:• armazenar
• organizar os dados de forma simples.
1 Estrutura de dados deve poder ser acedida de forma não sequencial, ou ter um acesso directo.
1 Estrutura pretendida: tabela (array).
1 Exemplo:
REAL, DIMENSION(50) :: TempoAvaria
1 O compilador cria uma tabela com o nome TempoAvaria, consistindo em 50 espaços em memória do tipo REAL. Exemplo:
TempoAvaria(34)
• o índice correspondendo ao elemento é 34.
35
João Miguel C. Sousa GCAR , DEM, IST 137
Tabelas (cont.)
1 Localização da tabela em memória:
1 Índice deve ser uma variável ou expressão do tipo inteiro.
1 Leitura de tabelas:READ (10, *) TempoAvaria
• é equivalente a:READ (10, *) TempoAvaria(1), ... &
TempoAvaria(50)
Memória
…
TempoAvaria(1) ← →
TempoAvaria(2) ← →
TempoAvaria(3) ← →
… …
TempoAvaria(50) ← →
…
João Miguel C. Sousa GCAR , DEM, IST 138
Programa: Tempos_de_avaria2 (1)
PROGRAM Tempos_de_avaria2!------------------------------------------------------------! Programa que le uma lista de tempos de avaria, calcula o! tempo medio de avaria, mostra uma lista de tempos de avaria! maiores que a media. Identificadores:! EstadoAbertura : estado da variavel para OPEN! EstadoEntrada : estado da variavel para READ! TempoAvaria : tabela unidimensional de tempos avaria! NumeroVezes : dimensao da tabela (constante)! I : indice! Soma : somados tempos de avaria! Tempo_Medio : media dos tempos de avaria!! Entradas: Lista com NumeroVezes de tempos de avaria! Saidas: Informacao sobre o estado do ficheiro de dados,! Tempo_Medio, e uma lista com tempos de avaria! maiores que Tempo_Medio!------------------------------------------------------------IMPLICIT NONEINTEGER, PARAMETER :: NumeroVezes = 50REAL, DIMENSION(NumeroVezes) :: TempoAvariaINTEGER :: EstadoAbertura, EstadoEntrada, IREAL :: Soma, TempoMedio
WRITE (*, *) “Programa le”, NumeroVezes, “tempos de avarias &&no ficheiro entrada.dat.”
OPEN (UNIT = 10, FILE = “entrada.dat”, STATUS = “OLD”, &IOSTAT = EstadoAbertura)
IF (EstadoAbertura > 0)WRITE (*, *) “*** Ficheiro nao disponivel! ***”
ELSE
João Miguel C. Sousa GCAR , DEM, IST 139
Programa: Tempos_de_avaria2 (2)
! Le os tempos de avaria e armazena-os em TempoAvariaREAD (10, *, IOSTAT = EstadoEntrada) TempoAvariaIF (EstadoEntrada > 0)
WRITE(*, *) “*** Erro na entrada de dados ***”ELSE IF (EstadoEntrada < 0)
WRITE(*, *) “*** Dados insufucientes ***”ELSE
! Calcula o tempo medio de avariaSoma = 0.0DO I = 1, NumeroVezes
Soma = Soma + TempoAvaria(I)END DOTempoMedio = Soma / REAL(NumeroVezes)WRITE (*, ‘(/ 1X, “Tempo medio de falha =”, F6.1)’,&
TempoMedio
! Mostra lista de tempos maiores que a mediaWRITE(*, *)WRITE(*, *) “Lista de tempos maiores que a media:”DO I = 1, NumeroVezes
IF (TempoAvaria(I) > TempoMedio) THENWRITE (*, ‘(1X, F9.1)’, TempoAvaria(I)
END IFEND DO
END IFEND IF
END PROGRAM Tempos_de_avaria2
João Miguel C. Sousa GCAR , DEM, IST 140
Tempos_de_avaria2 (execução)
1 Listagem do ficheiro entrada.dat:
99.5, 133.8, 84.2, 217.5, 188.8, 103.1, 93.9, 165.0, 68.3111.4, 88.8, 88.2, 90.1, 70.2, 150.5, 122.9, 138.8, 99.9111.6, 155.7, 133.4, 122.2, 93.4, 101.5, 109.9, 103.3, 177.7188.1, 99.8, 144.4, 87.5, 79.3, 190.2, 190.3, 170.1, 160.9121.1, 95.6, 140.5, 177.2, 150.1, 140.3, 139.2, 113.8, 155.9144.4, 88.3, 83.5, 101.1, 112.8
1 Exemplo de execuçãoPrograma le 50 tempos de avarias no ficheiro entrada.dat.
Tempo medio de falha = 126.0
Lista de tempos maiores que a media:133.8 217.5188.8165.0150.5138.8155.7133.4177.7188.1144.4190.2
36
João Miguel C. Sousa GCAR , DEM, IST 141
Leitura e escrita de tabelas
1 Exemplo de execução (concl.)190.3
170.1
160.9
140.5
177.2
150.1
140.3
139.2
155.9
144.4
1 Leitura e escrita de tabelas• Exemplo leitura:READ (10, ‘(5F6.1)’) TempoAvaria
12345678901234567890123456789012345678901234567890
99.5 133.8 84.2 217.5 188.8
103.1 93.9 165.0 68.3 111.4
etc.
• Exemplo escrita:WRITE (20, ‘(1X 5F10.1)’) TempoAvaria
João Miguel C. Sousa GCAR , DEM, IST 142
Ciclos DO implícitos
1 Definição:
(lista, var_controlo = inicial, limite, passo)
1 Onde lista corresponde à lista de variáveis, e var_controlo, inicial, limite e passo são as mesmas variáveis de um ciclo DO.
& Exemplo leitura:READ (10,*) (TempoAvaria(I), I=1, NumeroVezes)
& é equivalente a:READ (10,*) TempoAvaria(1), TempoAvaria(2),&
..., TempoAvaria(NumeroVezes)
& Exemplo escrita:WRITE (*,*) (TempoAvaria(I), I=1, NumeroVezes)
& é equivalente a:WRITE (*,*) TempoAvaria(1), TempoAvaria(2),&
..., TempoAvaria(NumeroVezes)
João Miguel C. Sousa GCAR , DEM, IST 143
Definição de tabelas
Definição de tabelas compiladas_____________________________________________________________________
Forma:tipo, DIMENSION(l:u) :: lista_nome_tabelas
outipo :: lista_especificadores_tabelas
1 Onde:• a lista_nome_tabelas é uma lista de nomes
de tabelas;• a lista_especificadores_tabelas é uma
lista de especificadores da forma:nome_tabela(l:u)
1 Cada um dos identificadores da lista é uma tabela, cuja memória é atribuída (alocada) aquando da compilação do programa.1 Os índices vão de l a u são quaisquer inteiros. Se l
é igual a 1, este valor pode ser omitido.
João Miguel C. Sousa GCAR , DEM, IST 144
Exemplos de tabelas
& Exemplo anterior (1):
REAL, DIMENSION(50) :: TempoAvaria
REAL, DIMENSION(1:50) :: TempoAvaria
REAL :: TempoAvaria(1:50)
REAL :: TempoAvaria(50)
& Exemplo 2:
INTEGER, PARAMETER :: LimInf_1 = -1, LimSup_1 = 3, &LimInf_2 = 0, LimSup_2 = 5
INTEGER, DIMENSION(LimInf_1:LimSup_1) :: GamaREAL, DIMENSION(LimInf_2:LimSup_2) :: Delta
1 Gama tem 5 elementos e Delta 6 elementos.
37
João Miguel C. Sousa GCAR , DEM, IST 145
Tabelas alocáveis
1 Na versão anterior, é associado um bloco de memória para toda a tabela, o qual não pode ser alterado. Problemas:• Se tamanho indicado é maior do que o
necessário, existe memória desperdiçada• Se tamanho indicado é menor do que o
necessário, há erro de overflow da tabela.
1 Fortran não permite alocar memória após a declaração da tabela1 Solução: alocar memória durante execução
Definição de tabelas alocáveis____________________________________________________________________
Forma:tipo, DIMENSION(:), ALLOCATABLE :: lista
outipo, DIMENSION(:) :: listaALLOCATABLE :: lista
João Miguel C. Sousa GCAR , DEM, IST 146
Tabelas alocáveis (cont.)
1 Onde:• a variável lista é uma lista de tabelas.
1 Declara que o tamanho de cada uma das tabelas em lista será especificado durante a execução.
& Exemplo:
REAL, DIMENSION(:), ALLOCATABLE :: A,B
• é uma tabela unidimensional a ser alocada.
1 Os limites da tabela alocada são especificados por:
Instrução ALLOCATE____________________________________________________________________
Forma:ALLOCATE(lista)
ouALLOCATE(lista, STAT = estado_variavel)
João Miguel C. Sousa GCAR , DEM, IST 147
Instrução ALLOCATE
1 Onde:• a variável lista é uma lista de especificações
de tabelas da forma:nome_tabela(l:u)
1 Atribui espaço em memória para cada uma das tabelas da lista. Todas as definições anteriores permancem válidas.1 Na segunda forma, à variável estado_variavel é
atribuído o valor zero se a alocação for bem sucedida. Se não existir mais memória ou a tabela já tiver sido previamente alocada, é atribuído um valor de erro dependendo do sistema.
1 Existe uma pilha de memória disponível quando o programa começa a ser executado. 1 Cada ALLOCATE vai utilizar espaço dessa
memória (alocá-lo).
João Miguel C. Sousa GCAR , DEM, IST 148
Instrução DEALLOCATE
1 Como a memória é limitada, dever-se-á libertar espaço em memória sempre que este não é necessário.
Instrução DEALLOCATE____________________________________________________________________
Forma:DEALLOCATE(lista)
ouDEALLOCATE(lista, STAT = estado_variavel)
1 Onde:• a variável lista é uma lista de tabelas
previamente alocadas.
1 Liberta a memória previamente utilizada. À variável estado_variavel é atribuído o valor zero se a dealocação for bem sucedida. A memória libertada passa a estar disponível.
38
João Miguel C. Sousa GCAR , DEM, IST 149
Programa: Tempos_de_avaria3 (1)
PROGRAM Tempos_de_avaria3!------------------------------------------------------------! Programa que le uma lista de tempos de avaria, calcula o! tempo medio de avaria e mostra uma lista de tempos de ! avaria maiores que a media. E utilizada uma tabela alocada! para guardar os tempos de avaria. Identificadores:! NomeFicheiro : nome do ficheiro de dados! EstadoAbertura : estado da variavel para OPEN! EstadoEntrada : estado da variavel para READ! EstadoAlocacao : estado da variavel para ALLOCATE! TempoAvaria : tabela unidimensional de tempos avaria! NumeroVezes : dimensao da tabela (variavel)! I : indice! Soma : somados tempos de avaria! Tempo_Medio : media dos tempos de avaria!! Entrada(teclado) : NomeFicheiro! Entrada(ficheiro): NumeroVezes e lista com NumeroVezes de! tempos de avaria! Saidas: Tempo_Medio e uma lista com tempos de avaria ! maiores que Tempo_Medio! Nota: Primeiro valor do ficheiro deve conter NumeroVezes!------------------------------------------------------------IMPLICIT NONECHARACTER(20) :: NomeFicheiroREAL, DIMENSION(:), ALLOCATABLE :: TempoAvariaINTEGER :: EstadoAbertura, EstadoEntrada, EstadoAlocacao, &
NumeroVezes, IREAL :: Soma, TempoMedio
! Le o nome do ficheiro de dados e abre-o para entradaWRITE (*, ‘(1X, A)’, ADVANCE = “NO”) “Escreva o nome do &
&ficheiro de dados: ”READ (*, *) NomeFicheiro
João Miguel C. Sousa GCAR , DEM, IST 150
Programa: Tempos_de_avaria3 (2)
OPEN (UNIT = 10, FILE = NomeFicheiro, STATUS = “OLD”, &IOSTAT = EstadoAbertura)
IF (EstadoAbertura > 0)WRITE (*, *) “*** Ficheiro nao disponivel! ***”
ELSE! Le o numero dos tempos de avaria e aloca uma tabela! Com o numero de elementos a guardar os tempos de avariaREAD (10, *, IOSTAT = EstadoEntrada) NumeroVezes IF (EstadoEntrada > 0)
WRITE(*, *) “*** Erro na entrada de dados ***”ELSE IF (EstadoEntrada < 0)
WRITE(*, *) “*** Dados insufucientes ***”ELSE
ALLOCATE(TempoAvaria(NumeroVezes), STAT = EstadoAlocacao)END IFIF (EstadoAlocacao /= 0)
WRITE(*, *) “*** Memoria Insuficiente ***”ELSE
! Le os tempos de avaria e armazena-os em TempoAvariaREAD (10, *, IOSTAT = EstadoEntrada) TempoAvariaIF (EstadoEntrada > 0)
WRITE(*, *) “*** Erro na entrada de dados ***”ELSE IF (EstadoEntrada < 0)
WRITE(*, *) “*** Dados insufucientes ***”ELSE
! Calcula o tempo medio de avariaSoma = 0.0DO I = 1, NumeroVezes
Soma = Soma + TempoAvaria(I)END DO
João Miguel C. Sousa GCAR , DEM, IST 151
Programa: Tempos_de_avaria3 (3)
TempoMedio = Soma / REAL(NumeroVezes)WRITE (*, ‘(/ 1X, “Para ”, I4, “tempos de avaria, ” &
&/ 1X, “o tempo medio de avaria =”, F6.1)’) &Numero Vezes, TempoMedio
! Mostra lista de tempos maiores que a mediaWRITE(*, *)WRITE(*, *) “Lista de tempos maiores que a media:”DO I = 1, NumeroVezes
IF (TempoAvaria(I) > TempoMedio) THENWRITE (*, ‘(1X, F9.1)’) TempoAvaria(I)
END IFEND DO
! Liberta espaco em memoria de TempoAvariaDEALLOCATE(TempoAvaria)
END IFEND IF
END IF
END PROGRAM Tempos_de_avaria3
1 Hipótese de verificação de alocação para libertar a memória correspondente a uma dada variável:
IF (ALLOCATED(TempoAvaria)) THENDEALLOCATE(TempoAvaria)
END IF
João Miguel C. Sousa GCAR , DEM, IST 152
Processamento de tabelas
1 As tabelas constantes são uma lista de valores entre (/ e /).
(/ valor_1, valor_2, ..., valor_k /)
& Exemplo 1:
(/ 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 /)
1 Podem ser dadas por um DO-implícito:
(/ valor-lista, controlo-DO-implícito /)
& Exemplo 2:
(/ (2*I, I = 1, 10) /)
39
João Miguel C. Sousa GCAR , DEM, IST 153
Expressões e atribuições
1 Operadores e funções são aplicáveis a ta-belas com o mesmo número de elementos.& Exemplos:
INTEGER, DIMENSION(4) :: A, BINTEGER, DIMENSION(0:3) :: CINTEGER, DIMENSION(6:9) :: DINTEGER, DIMENSION(4) :: P
A = (/ 1, 2, 3, 4 /)B = (/ 5, 6, 7, 8 /)A = A + BC = (/ -1, -3, -5, 7 /)D = 2 * ABS(C) + 1P = (C > 0) .AND. (MOD(B, 3) == 0)
1 Atribuiçõesvariavel_tipo_tabela = expressao
• Valores da expressão atribuída podem ser:1 Uma tabela do mesmo tamanho da variável.
2 Um valor simples. Neste caso o valor é atribuído a todos os elementos da tabela.
João Miguel C. Sousa GCAR , DEM, IST 154
Sub-tabelas
1 Definição:nome_tabela(inferior:superior:passo)
ounome_tabela(vector_indices)
& Exemplo 1:INTEGER, DIMENSION(8) :: AINTEGER, DIMENSION(4) :: BINTEGER :: J
& SeA = (/ 11, 22, 33, 44, 55, 66, 77, 88 /)
& então:B = A(2:8:2)
& é a parte de A com os elementos 22, 44, 66 e 88.
& Exemplo 2:I = (/ 6, 5, 3, 8, 1 /)
B = A(I)
& atribui a B os elementos 66, 55, 33, 88 e 11.B = A((/ 5, 3, 3, 4, 3/))
& atribui a B os elementos 55, 33, 33, 44, 33.
João Miguel C. Sousa GCAR , DEM, IST 155
A construção WHERE
Construção WHERE____________________________________________________________________
Forma:WHERE (exp_log_tab) var_tab_1 = exp_tab_1
ouWHERE (expressao_logica_tabela)
var_tabela_1 = expressao_tabela_1...var_tabela_m = expressao_tabela_m
ELSEWHEREvar_tabela_m+1 = expressao_tabela_m+1...var_tabela_n = expressao_tabela_n
END WHERE
1 Onde:• a variável expressao_logica_tabela é uma
tabela de expressões de valores lógicos;• cada var_tabela_i tem a mesma dimensão
de expressao_logica_tabela;• na segunda forma ELSEWHERE é opcional.
João Miguel C. Sousa GCAR , DEM, IST 156
Tabelas como argumentos
& Exemplo com construção WHERE:
INTEGER, DIMENSION(5) :: A = (/ 0, 2, 5, 0, 10/)REAL, DIMENSION(5) :: B
WHERE (A > 0)B = 1.0 / REAL(A)
ELSEWHEREB = -1.0
END WHERE
& Atribui a B a sequência -1.0, 0.5, 0.2, -1.0, 0.1.
1 Tabelas como argumentos• Subprogramas com processamento de tabelas
intrínseco. Exemplos:ALLOCATED(A)MAXVAL(A)MAXLOC(A)PRODUCT(A)SIZE(A)SUM(A)
40
João Miguel C. Sousa GCAR , DEM, IST 157
Subprogramas com tabelas
1 Subprogramas definidos pelo programador• O argumento tipo tabela deve ser definido na
unidade que chama o subprograma.• O argumento formal do tipo tabela deve ser
declarado dentro do subprograma.
& Programa exemplo: Media_de_uma_lista_1PROGRAM Media_de_uma_Lista_1!------------------------------------------------------------! Programa que le uma lista de numeros Item(1), Item(2), …,! Item(NumItems) e calcula a sua media usando a funcao Media. ! Os identificadores sao:! Item : tabela uni-dimensional de numeros! NumItems : numero de items (constante)! Media : funcao que calcula a media de um conjunto de! numeros!! Entradas : NumItems e a lista de numeros reais! Saida : A media dos numeros!------------------------------------------------------------
IMPLICIT NONEINTEGER, PARAMETER :: NumItems = 10REAL, DIMENSION(NumItems) :: Item
WRITE (*, *) “Insira”, NumItems, “numeros reais:”READ (*, *) ItemWRITE (*, ‘(1X, “Media de ”, I3, “numeros e:”, F6.2)’) &
NumItems, Media(Item)
João Miguel C. Sousa GCAR , DEM, IST 158
Media_de_uma_lista_1 (concl.)
CONTAINS
!-Media---------------------------------------------------! Funcao que calcula a media de elementos de uma tabela X ! Identificadores locais:! NumElementos: numero de elementos em X (constante)!! Recebe : Tabela X! Retorna : A media dos valores guardados em X!---------------------------------------------------------
FUNCTION Media(X)
INTEGER, PARAMETER :: NumElementos = 10REAL, DIMENSION(NumElementos), INTENT(IN) :: XREAL :: Media
Media = SUM(X) / REAL(NumElementos)
END FUNCTION Media
STOPEND PROGRAM Media_de_uma_Lista_1
& Exemplo de execução:
Insira 10 numero reais:55, 88.5, 90, 71.5, 100, 66.5, 70.3, 81.2, 93.7, 41Media de 10 numeros e 75.77
João Miguel C. Sousa GCAR , DEM, IST 159
Programa: Media_de_uma_lista_2
PROGRAM Media_de_uma_Lista_2!------------------------------------------------------------! Programa que le uma lista de numeros Item(1), Item(2), …,! Item(NumItems) e calcula a sua media usando a funcao Media. ! Os identificadores sao:! Item : tabela uni-dimensional de numeros! NumItems : numero de items (constante)! Media : funcao que calcula a media de um conjunto de! numeros!! Entradas : NumItems e a lista de numeros reais! Saida : A media dos numeros!------------------------------------------------------------
IMPLICIT NONEINTEGER, PARAMETER :: NumItems = 10REAL, DIMENSION(NumItems) :: Item
WRITE (*, *) “Insira”, NumItems, “numeros reais:”READ (*, *) ItemWRITE (*, ‘(1X, “Media de ”, I3, “numeros e:”, F6.2)’) &
NumItems, Media(Item, NumItems)
CONTAINS
!-Media---------------------------------------------------! Funcao que calcula a media de NumElementos de uma tabela ! X. O tamanho da tabela X (NumElementos) é passado como ! argumento.!! Recebe : Tabela X e NumElementos! Retorna : A media dos valores guardados em X!---------------------------------------------------------
João Miguel C. Sousa GCAR , DEM, IST 160
Media_de_uma_lista_2 (concl.)
FUNCTION Media(X, NumElementos)
INTEGER, INTENT(IN) :: NumElementosREAL, DIMENSION(NumElementos), INTENT(IN) :: XREAL :: Media
Media = SUM(X) / REAL(NumElementos)
END FUNCTION Media
STOPEND PROGRAM Media_de_uma_Lista_2
1 A tabela Item poderia ser alocada:INTEGER :: NumItems, EstadoAlocacaoREAL, DIMENSION(:), ALLOCATABLE :: ItemREAL :: Media
WRITE (*, ‘(1X, A)’, ADVANCE = “NO”) &“Quantos elementos existem no conjunto de dados? ”
READ (*, *) NumItemsALLOCATE(Item(NumItems), STAT = EstadoAlocacao)IF (EstadoAlocacao /= 0) THEN
WRITE (*, *) “*** Memoria insuficiente ***”ELSE
WRITE (*, *) “Insira”, NumItems, “numeros reais:”READ (*, *) ItemWRITE (*, ‘(1X, “Media de ”, I3, “numeros e:”, F6.2)’) &
NumItems, Media(Item, NumItems)END IF
41
João Miguel C. Sousa GCAR , DEM, IST 161
Tabelas de dimensão pré-definida
1 A dimensão da tabela actual é a dimensão da tabela formal (no subprograma)
Declaração:DIMENSION(:)
ou
DIMENSION(limite_inferior:)
• Onde limite_inferior especifica o limite inferior dos índices da tabela formal.
& Exemplo: No programa Media_de_uma_lista_2, a função média seria dada por:
! (...)
FUNCTION Media(X)
REAL, DIMENSION(:), INTENT(IN) :: XREAL :: Media
Media = SUM(X) / REAL(SIZE(X))
END FUNCTION Media
João Miguel C. Sousa GCAR , DEM, IST 162
Tabelas automáticas
1 Um subprograma com tabelas de dimensão pré-definida pode necessitar de variáveis locais do tipo tabela.
1 Usam-se tabelas automáticas neste caso, onde o seu tamanho varia com a chamada.1 A função SIZE dimensiona estas tabelas.
& Exemplo:!-Troca----------------------------------------------------! Esta subrotina troca duas tabelas de dimensão pre-! assumida. Tabela local utilizada:! Temp : Tabela automatica utilizada para trocar A e B!! Aceita: Tabelas A e B! Retorna: A e B com elementos trocados!----------------------------------------------------------
SUBROUTINE Troca(A, B)
REAL, DIMENSION(:), INTENT(INOUT) :: A, BREAL, DIMENSION(SIZE(A)) :: Temp
Temp = AA = BB = Temp
END SUBROUTINE Troca
João Miguel C. Sousa GCAR , DEM, IST 163
Funções que retornam tabelas
& Exemplo: Inversão de valores duma tabelaPROGRAM Inversao_de_uma_Lista!------------------------------------------------------------! Programa que testa a funcao Inverte. Le uma lista de ! numeros Item(1), Item(2), …, Item(NumItems), chama a funcao! Inverte, constroi uma lista na ordem inversa e mostra-a.! Os identificadores sao:! Item : tabela unidimensional de numeros! NumItems : numero de items (constante)! Inverte : funcao que inverte a tabela!! Entradas : NumItems e a lista de numeros inteiros! Saida : A lista invertida!------------------------------------------------------------
IMPLICIT NONEINTEGER, PARAMETER :: NumItems = 10REAL, DIMENSION(NumItems) :: Item
WRITE (*, ‘(1X, A, I3, A)’, ADVANCE = “NO”) &“Insira”, NumItems, “numeros inteiros: ”
READ (*, *) ItemWRITE (*, *) “A lista por ordem inversa e dada por:”WRITE (*, *) Inverte(Item)
CONTAINS!-Inverte-------------------------------------------------! Funcao que inverte uma tabela X. Variaveis locais:! NumElementos : numero de elementos em X! I : indice!! Recebe : Tabela X de dimensão predefinida! Retorna : A tabela X invertida!---------------------------------------------------------
João Miguel C. Sousa GCAR , DEM, IST 164
Inversao_de_uma_lista (concl.)
FUNCTION Inverte(X)
INTEGER, DIMENSION(:), INTENT(IN) :: XINTEGER, DIMENSION(SIZE(x)) :: InverteINTEGER :: NumElementos, I
NumElementos = SIZE(X)DO I = 1, NumElementos
Inverte(I) = X(NumElementos - I + 1)END DO
END FUNCTION Inverte
STOP
END PROGRAM Inversao_de_uma_Lista
& Exemplo de execução:
Insira 10 numero inteiros: 1 2 3 4 5 6 7 8 9 10A lista por ordem inversa e dada por:10 9 8 7 6 5 4 3 2 1
1 Em funções externas que retornam tabelas, o programa principal deverá conter um bloco de interface para essa função.
42
João Miguel C. Sousa GCAR , DEM, IST 165
Algoritmos de ordenação
1 Arranjo dos elementos de uma tabela de forma ascendente ou descendente.• Selecção simples• Ordenação rápida
1 Ordenação por selecção simples• Verifica a lista várias vezes, e de cada vez
selecciona um elemento da lista colocando-o na posição correcta.
& Exemplo: ordenar de forma ascendente67, 33, 21, 84, 49, 50, 75
1 Localizar o elemento mais pequeno:67, 33, 21, 84, 49, 50, 75
2 Trocá-lo com o primeiro:21, 33, 67, 84, 49, 50, 75
3 Localizar o 2º elemento mais pequeno e ordená-lo (já se encontra na posição correcta neste caso):
21, 33, 67, 84, 49, 50, 75(...) Repetem-se os passos até se obter a lista ordenada:
21, 33, 49, 50, 67, 75, 84
João Miguel C. Sousa GCAR , DEM, IST 166
Ordenação por selecção simples
Algoritmo1 Algoritmo para ordenar uma lista de items X(1), X(2), …,
X(N) de forma ascendente. Para ordenar de forma descendente procura o maior item em vez do menor de cada vez que a tabela é percorrida.
1 Entrada: Lista X(1), X(2), …, X(N).
1 Saída: Lista X(1), X(2), …, X(N) modificada ; os elementos estão na lista de forma ascendente.
Para I variando de 1 a N - 1, faz o seguinte:
1 Na Iésima passagem, procura o ItemMaisPequeno na sublista X(I), …, X(N), e a sua respectiva posição LocalizacaoMaisPequeno.
2 Troca ItemMaisPequeno com o item no princípio da lista.
3 Atribui X(LocalizacaoMaisPequeno) o valor de X(I).
4 Atribui X(I) o valor de X(LocalizacaoMaisPequeno).
João Miguel C. Sousa GCAR , DEM, IST 167
Subrotina: Ordenacao_por_seleccao
!-Ordenacao_por_Seleccao-----------------------------------! Esta subrotina ordena a tabela Item em ordem ascendente! usando o algoritmo de ordenacao por seleccao simples. ! Para ordenar em ordem descendente dever-se-a trocar ! MINVAL por MAXVAL e MINLOC por MAXLOC. Variaveis locais:! NumItems : numero de elementos na tabela Item! ItemMaisPequeno : item mais pequeno da sublista actual! MINLOC_tabela : tabela de um elemento dada por MINLOC! LocalMaisPequeno: localizacao de ItemMaisPequeno! I : índice!! Aceita: Tabela de Items! Retorna: Tabela com items ordenados de forma ascendente!----------------------------------------------------------SUBROUTINE Ordenacao_por_Seleccao(Item)
INTEGER, DIMENSION(:), INTENT(INOUT) :: ItemINTEGER :: NumItems, ItemMaisPequeno, LocalMaisPequeno, IINTEGER, DIMENSION(1) :: MINLOC_tabela
NumItems = SIZE(Item)DO I = 1, NumItems - 1
! Encontra o item mais pequeno na sublista! Item(I), …,Item(NumItems)ItemMaisPequeno = MINVAL(Item(I:NumItems))MINLOC_tabela = MINLOC(Item(I:NumItems))LocalMaisPequeno = (I - 1) + MINLOC_tabela(1)
! Troca ItemMaisPequeno com Item(I) no inicio sublistaItem(LocalMaisPequeno) = Item(I)Item(I) = ItemMaisPequeno
END DO
END SUBROUTINE Ordenacao_por_Seleccao
João Miguel C. Sousa GCAR , DEM, IST 168
Ordenação rápida
1 Escolhe-se um pivot, e trocam-se todos os elementos inferiores para um lado e todos os superiores para outro.1 Lista é dividida em duas mais pequenas e o
procedimento é repetido.1 Esta estratégia de dividir-para-reinar é
implementada recursivamente de forma natural.1 Método mais eficiente; é um dos mais rápidos.& Exemplo: ordenar de forma ascendente
50, 30, 20, 80, 90, 70, 95, 85, 10, 15, 75, 251 O elemento pivot é o 50. Elementos maiores que 50
passam para a sua direita e inferiores para a esquerda10, 30, 20, 25,15, 50, 95, 85, 70, 90, 75, 80
2 A lista é dividida em duas sublistas a ser ordenadas:10, 30, 20, 25,15 e95, 85, 70, 90, 75, 80
3 Os passos 1 e 2 podem ser aplicado a cada uma das duas sublistas mais pequenas de forma recursiva. O caso âncora (caso mais simples) ocorre quando a lista é vazia ou tem apenas um elemento.
43
João Miguel C. Sousa GCAR , DEM, IST 169
Ordenação rápida (concl.)
1 O caso indutivo ocorre quando uma lista contém mais do que um elemento, onde:1 A lista é separada em duas sublistas.2 A sublista esquerda é ordenada recursivamente.3 A sublista direita é ordenada recursivamente.
& Subrotina: Ordenacao_Rapida!------------------------------------------------------------! Nota: Nas subrotinas seguintes Item e uma tabela de ! tamanho predefinido; o programa principal deve:
! 1. conter uma subrotina como um subprograma interno,
! 2. importar a subrotina de um módulo, ou
! 3. conter um bloco de interface para esta subrotina.!------------------------------------------------------------
!-Ordenacao_Rapida-------------------------------------------! Subrotina que ordena tabela usando o metodo de ordenacao! rapida. Chama-a com Primeiro = limite inferior dos indices! da tabela e Ultimo = limite superior.! Variaveis locais:! Media: ponto de separacao da tabela! ! Aceita: Tabela Item! Retorna: Tabela Item ordenada de forma ascendente!------------------------------------------------------------
João Miguel C. Sousa GCAR , DEM, IST 170
Subrotina: Ordenacao_Rapida
RECURSIVE SUBROUTINE Ordenacao_Rapida(Item, Primeiro, Ultimo)
INTEGER, DIMENSION(:), INTENT(INOUT) :: ItemINTEGER, INTENT(IN) :: Primeiro, UltimoINTEGER :: Medio
IF (Primeiro < Ultimo) THEN !Se tamanho lista >= 2CALL Divide(Item, Primeiro, Ultimo, Medio) !Divide-aCALL Ordenacao_Rapida(Item,Primeiro,Medio-1) !Ordena esqCALL Ordenacao_Rapida(Item,Medio+1,Ultimo) !Ordena dir
END IF
END SUBROUTINE Ordenacao_Rapida
!-Divide-----------------------------------------------------! Subrotina que divide uma lista em duas sublistas, usando o ! primeiro elemento como pivot, e retorna a posicao do ! elemento onde a lista e dividida. Variaveis locais:! Esquerdo: posicao do primeiro elemento! Direito : posicao do ultimo elemento! Pivot : elemento pivot! Troca : usado para trocar dois elementos! ! Aceita: Tabela Item e posicoes Baixo e Alto do primeiro e! do ultimo elementos.! Retorna: Tabela Item ordenada de forma ascendente!------------------------------------------------------------SUBROUTINE Divide(Item, Baixo, Alto, Medio)
INTEGER, DIMENSION(:), INTENT(INOUT) :: ItemINTEGER, INTENT(IN) :: Baixo, AltoINTEGER, INTENT(OUT) :: MedioINTEGER :: Esquerdo, Direito, Pivot, Troca
João Miguel C. Sousa GCAR , DEM, IST 171
Subrotina: Divide
Esquerdo = BaixoDireito = AltoPivot = Item(Baixo)
! Repete enquanto Esquerdo e Direito nao se encontraremDO
IF (Esquerdo >= Direito) EXIT! Procura da direita para a esquerda elemento < pivotDO
IF (Esquerdo>=Direito .OR. Item(Direito)<Pivot) EXITDireito = Direito - 1
END DO
! Procura da esquerda para a direita elemento > pivotDO
IF (Item(Esquerdo) > Pivot) EXITEsquerdo = Esquerdo + 1
END DO
! Se Esquerdo e Direito nao se encontraram, troca itemsIF (Esquerdo < Direito) THEN
Troca = Item(Esquerdo)Item(Esquerdo) = Item(Direito)Item(Direito) = Troca
END IFEND DO
! Troca elemento na posicao de separacao com pivotItem(Baixo) = Item(Direito)Item(Direito) = PivotMedio = Direito
END SUBROUTINE Divide
João Miguel C. Sousa GCAR , DEM, IST 172
Algoritmos de procura
1 Consideram-se dois tipos:• Procura linear• Procura binária
1 Procura linear• Começa no primeiro item da lista, e procura
sequencialmente até o elemento ou o fim da lista serem encontrados.
Algoritmo1 Algoritmo de procura linear que encontra ItemProcurado
na lista X(1), X(2), …, X(N). À variável Encontrado é atribuído o valor de verdadeiro e a Localizacao é atribuí-da a posição de ItemProcurado quando a procura é bem sucedida; caso contrário Encontrado tem o valor falso.
1 Recebe: Lista X(1), X(2), …, X(N) e ItemProcurado.1 Retorna:
Se ItemProcurado é encontrado na lista:Encontrado = verdadeiro, eLocalizacao = posição de ItemProcurado.
Se ItemProcurado não é encontrado na lista:Encontrado = falso (e Localizacao = N + 1)
44
João Miguel C. Sousa GCAR , DEM, IST 173
Procura linear
1 Inicializa Localizacao a 1 e Encontrado a falso.
2 Enquanto Localizacao <= N e Encontrado é falso:
Se ItemProcurado = X(Localizacao) entãoAtribui a Encontrado o valor verdadeiro.
Caso contrário:Incrementa Localizacao de uma unidade.
& Exemplo: Procura numa cadeia de caracteres.
!-Procura_Linear---------------------------------------------! Subrotina que procura na lista Item o ItemProcurado usando! o metodo de procura linear. Se ItemProcurado for encontrado! na lista, sao retornados: Encontrado com o valor de! verdadeiro e a Localizacao do item; caso contrario ! Encontrado tem o valor de falso.! ! Aceita: Tabela Item e ItemProcurado! Retorna: Se ItemProcurado é encontrado na lista:! Encontrado = verdadeiro e! Localizacao = posição de ItemProcurado! Caso contrario:! Encontrado = falso ! (Localizacao = ultima posicao examinada)!------------------------------------------------------------
SUBROUTINE Procura_Linear(Item, ItemProcurado, Encontrado, &Localizacao)
João Miguel C. Sousa GCAR , DEM, IST 174
Subrotina: Procura_Linear
CHARACTER(*), DIMENSION(:), INTENT(IN) :: ItemCHARACTER(*), INTENT(IN) :: ItemProcuradoLOGICAL, INTENT(OUT) :: EncontradoINTEGER, INTENT(OUT) :: LocalizacaoINTEGER :: NumeroItems
NumItems = SIZE(Item)Localizacao = 1Encontrado = .FALSE.
! Enquanto Localizacao <= NumeroItems e Encontrado falso:DO
IF ((Localizacao > NumeroItems) .OR. Encontrado) EXIT ! Se fim da lista ou item encontrado, termina procura
! Caso contrario testa o proximo elemento da listaIF (ItemProcurado == Item(Localizacao)) THEN
Encontrado = .TRUE.ELSE
Localizacao = Localizacao + 1END IF
END DO
END SUBROUTINE Procura_Linear
João Miguel C. Sousa GCAR , DEM, IST 175
Procura binária
1 Procura que divide lista em 2 sublistas, escolhendo a que tem o item procurado.• A procura linear requer n comparações,
enquanto a procura binária requer log2n.& Exemplo: lista com 1024 (=210) elementos& Procura binária: máximo 10 comparações.& Procura linear: máximo 1024 comparações.
Algoritmo1 Algoritmo de procura binária na lista X(1), X(2), …, X(N)
ordenada de forma ascendente. À variável Encontrado é atribuído o valor de verdadeiro e a Localizacao é atribuí-da a posição de ItemProcurado quando a procura é bem sucedida; caso contrário Encontrado tem o valor falso.
1 Recebe: Lista X(1), X(2), …, X(N) e ItemProcurado.1 Retorna:
Se ItemProcurado é encontrado na lista:Encontrado = verdadeiro, eLocalizacao = posição de ItemProcurado.
Se ItemProcurado não é encontrado na lista:Encontrado = falso
João Miguel C. Sousa GCAR , DEM, IST 176
Algoritmo de procura binária
1 Inicializa Primeiro a 1 e Ultimo a n. Estes valores repre-sentam as posições do primeiro e do último items da sublista onde a procura está a ser efectuada.
2 Inicializa Encontrado com o valor lógico falso.
3 Enquanto Primeiro <= Ultimo e Encontrado é falso:
a) Encontra a posicao do meio na sublista, atribuindo a Meio o valor inteiro de (Primeiro + Ultimo) / 2.
b) Compara ItemProcurado com X(Meio). Existem três possibilidades:
i) ItemProcurado < X(Meio): ItemProcurado está na primeira metade da sublista. Atribui a Ultimoo valor Meio - 1.
ii) ItemProcurado > X(Meio): ItemProcurado está na segunda metade da sublista. Atribui a Primeiro o valor Meio + 1.
iii) ItemProcurado = X(Meio): ItemProcurado foi encontrado. Atribui a Localizacao o valor Meioe a Encontrado o valor verdadeiro.
& Exemplo: Procura numa cadeia de caracteres.
45
João Miguel C. Sousa GCAR , DEM, IST 177
Subrotina: Procura_Binaria (1)
!-Procura_Binaria--------------------------------------------! Subrotina que procura na lista Item o ItemProcurado usando! o metodo de procura binaria. Se ItemProcurado e encontrado! na lista sao retornados: Encontrado com o valor de! verdadeiro e a Localizacao do item; caso contrario ! Encontrado e falso. Esta subrotina e aplicada a cadeias de ! caracteres. Variaveis locais usadas:! Primeiro : primeiro item a (sub)lista sob procura! Ultimo : ultimo item a (sub)lista sob procura! Meio : item do meio na (sub)lista sob procura! ! Aceita: Tabela Item e ItemProcurado! Retorna: Se ItemProcurado é encontrado na lista:! Encontrado = verdadeiro e! Localizacao = posição de ItemProcurado! Caso contrario:! Encontrado = falso ! (e Localizacao = ultima posicao examinada)!------------------------------------------------------------
SUBROUTINE Procura_Binaria(Item, ItemProcurado, Encontrado, &Localizacao)
CHARACTER(*), DIMENSION(:), INTENT(IN) :: ItemCHARACTER(*), INTENT(IN) :: ItemProcuradoLOGICAL, INTENT(OUT) :: EncontradoINTEGER, INTENT(OUT) :: LocalizacaoINTEGER :: Primeiro, Ultimo, Meio
Primeiro = 1Ultimo = SIZE(Item)Encontrado = .FALSE.
João Miguel C. Sousa GCAR , DEM, IST 178
Subrotina: Procura_Binaria (2)
! Enquanto Primeiro <= Ultimo e Encontrado falso faz:DO
IF ((Primeiro > Ultimo) .OR. Encontrado) EXIT ! Se fim da lista ou item encontrado, termina procura
! Caso contrario continua com o seguinte procedimento:Meio = (Primeiro + Ultimo) / 2IF (ItemProcurado < Item(Meio)) THEN
Ultimo = Meio - 1ELSE IF (ItemProcurado > Item(Meio)) THEN
Primeiro = Meio + 1ELSE
Encontrado = .TRUE.Localizacao = Meio
END IFEND DO
END SUBROUTINE Procura_Binaria
& Exercício: Desenvolver o mesmo algoritmo de forma recursiva.
João Miguel C. Sousa GCAR , DEM, IST 179
Tabelas multidimensionais
1 Tabelas podem ser ordenadas por linhas, colunas, etc. Para isso são necessárias tabelas multi-dimensionais.
& Exemplo: tabela com temperaturas em 3 locais diferentes a 4 horas do dia:
& Declaração:
REAL, DIMENSION(4, 3) :: Temperatura
ou:REAL, DIMENSION(1:4, 1:3) :: Temperatura
• reserva 12 espaços em memória para a tabela.Temperatura(2,3)
1 refere-se ao elemento da 2ª linha e 3ª coluna.
LocalizaçãoTempo 1 2 3
1 65.5 68.7 62.02 68.8 68.9 64.53 70.4 69.4 66.34 68.5 69.1 65.8
João Miguel C. Sousa GCAR , DEM, IST 180
Declaração de tabelas genéricas
Declaração de tabelas compiladas_____________________________________________________________________
Forma:tipo, DIMENSION(l1:u1, l2:u2,..., lk:uk) :: &
lista_nome_tabelas
outipo :: lista_especificadores_tabelas
1 Onde:• a lista_nome_tabelas é uma lista de nomes
de tabelas separadas por vírgulas;• a lista_especificadores_tabelas é uma
lista de especificadores da forma:nome_tabela(l1:u1, l2:u2,..., lk:uk)
1 O número k de dimensões (rank) é no máximo sete.1 Cada par li:ui deve ser um parte de constantes
inteiras especificando os limites dos valores do índice i de li a ui; li pode ser omitido se o seu valor é 1.
46
João Miguel C. Sousa GCAR , DEM, IST 181
Tabelas n-dimensionais: exemplos
1 Cada um dos identificadores da lista é uma tabela k-dimensional, cuja memória é atribuída (alocada) aquando da compilação do programa.
& Exemplos:
REAL, DIMENSION(1:2, -1:3) :: Gamma
REAL, DIMENSION(0:2, 0:3, 1:2) :: Beta
INTEGER, DIMENSION(5:12) :: Kappa
ouREAL :: Gamma(1:2,-1:3), Beta(0:2,0:3,1:2)
INTEGER :: Kappa(5:12)
• tabela Gamma bidimensional 2 × 5, com o primeiro índice de 1 a 2 e o segundo de -1 a 3
• tabela Beta tridimensional 3 × 4 × 2• tabela Kappa unidimensional com índices de 5 a 12
João Miguel C. Sousa GCAR , DEM, IST 182
Tabelas n-dimensionais alocáveis
Definição de tabelas alocadas____________________________________________________________________
Forma:tipo, DIMENSION(:, …,:), ALLOCATABLE :: lista
outipo, DIMENSION(:, …,:) :: listaALLOCATABLE :: lista
1 Onde:• a variável lista é uma lista de tabelas;
• a dimensão k (rank) é no máximo sete.
1 Declara que o tamanho de cada uma das tabelas em lista é k-dimensional, onde k é o número de “:” na especificação de DIMENSION. O número de índices em cada dimensão, chamada a extensão da tabela, será especificado durante a execução.
& Exemplos:REAL, DIMENSION(:, :, :), ALLOCATABLE :: BetaREAL, DIMENSION(:,:), ALLOCATABLE :: Gamma
João Miguel C. Sousa GCAR , DEM, IST 183
Alocação n-dimensional
Instrução ALLOCATE____________________________________________________________________
Forma:ALLOCATE(lista)
ouALLOCATE(lista, STAT = estado_variavel)
1 Onde:• a variável lista é dada por:
nome_tabela(l1:u1, l2:u2, …, lk:uk)
1 Atribui espaço em memória para cada uma das k-dimensionais tabelas da lista. Todas as definições anteriores permancem válidas.1 À variável estado_variavel é atribuído o valor
zero se a alocação for bem sucedida. Se não existir mais memória ou a tabela já tiver sido previamente alocada, é atribuído um valor de erro.
& Exemplo:ALLOCATE(Beta(0:2, 0:3, 1:2), Gamma(1:N,-1:3), &
STAT = EstadoAlocacao)
João Miguel C. Sousa GCAR , DEM, IST 184
Entrada/Saída de tabelas
1 Processamento elemento a elemento• tabelas unidimensionais: ordem sequencial
• tabelas bidimensionais:1 por linha - 1ª linha processada em 1º lugar,
seguida pelas linhas seguintes.& Exemplo: A(1:2, 1:3)A(1, 1)A(1, 2)A(1, 3) A(2, 1)A(2, 2)A(2, 3)
1 por coluna - 1ª coluna processada em 1º lugar& Exemplo: A(1:2, 1:3)A(1, 1)A(2, 1)A(1, 2) A(2, 2)A(1, 3)A(2, 3)
1 O Fortran processa as tabelas por colunapor defeito (primeiros índices são percor-ridos primeiro).
47
João Miguel C. Sousa GCAR , DEM, IST 185
Entrada/Saída de tabelas (cont.)
1 Tabelas multidimensionais: usam ordem por elemento de tabela.
1 Tipos de Entrada/Saída com tabelas:• Utilizando um ciclo DO
• Utilizando o nome da tabela• Utilizando um DO implícito
• Utilizando uma secção da tabela
1 E/S com ciclos DO• utilizam-se ciclos DO encadeados& Exemplo: ler a tabela A declarada por:
INTEGER, DIMENSION(3, 4) :: Tabela
e que é dada por:
As intruções seguintes lêem a tabela:
33788948
461001099
25325677
João Miguel C. Sousa GCAR , DEM, IST 186
E/S com ciclos DO
DO Linha = 1, 3DO Coluna = 1, 4
READ (*, *) Tabela(Linha, Coluna)END DO
END DO
1 Lê a primeira linha em primeiro lugar, etc.
• Para ler por colunas:DO Coluna = 1, 4
DO Linha = 1, 3READ (*, *) Tabela(Linha, Coluna)
END DOEND DO
1 E/S utilizando o nome da tabela& Exemplo:READ (*, *) Tabela
• lê por colunas. Se os dados de entrada forem:77, 99, 48, 56, 10, 8932, 100, 78, 25, 46, 33
• o valor atribuído a Tabela será a matriz dada na página anterior.
João Miguel C. Sousa GCAR , DEM, IST 187
Saída com nome de tabela
& Exemplo escrita:WRITE (*, ‘(1X, 4I5/)’) Tabela
• coloca os elementos por colunas, produzindo a seguinte saída:
77 99 48 56---------------------
---------------------10 89 32 100
---------------------
---------------------78 25 46 33
---------------------
---------------------
• É de notar que a disposição dos elementos é diferente da matriz da página 180!
João Miguel C. Sousa GCAR , DEM, IST 188
Ciclos DO implícitos
1 Definição:
(lista, var_controlo = inicial, limite, passo)
1 Onde lista corresponde à lista de variáveis de entrada/saída, e var_controlo, inicial, limite e passo são as mesmas variáveis de um ciclo DO.
1 Podem ser utilizados ciclos DO implícitos dentro de outros ciclos DO ímplicitos.
& Exemplo leitura:READ(*,*) ((Tabela(Linha,Col), Col=1,4), Linha=1,3)
& é equivalente a:READ(*,*) (Tabela(Linha,1),Tabela(Linha,2), &
Tabela(Linha,3),Tabela(Linha,4), Linha=1,3)
& e a:READ(*,*) &(Tabela(1,1),Tabela(1,2),Tabela(1,3),Tabela(1,4), &(Tabela(2,1),Tabela(2,2),Tabela(2,3),Tabela(2,4), &(Tabela(3,1),Tabela(3,2),Tabela(3,3),Tabela(3,4)
48
João Miguel C. Sousa GCAR , DEM, IST 189
Ciclos DO implícitos (concl.)
& A leitura por colunas é dada por:READ(*,*) ((Tabela(Linha,Col), Linha=1,3), Col=1,4)
WRITE (*, ‘(1X 4I5/)’) Tabela
• Uso de parêntesis e vírgulas são importantes para definir os ciclos a executar primeiro.
• READ é executado só uma vez; as variáveis podem ser inseridas numa linha ou várias, é indiferente.
1 Escrita com ciclos DO• Combinam-se os DO com os DO ímplicitos
& Exemplo:DO Linha = 1, 3
WRITE(*, ‘(1X, 4I5)’) (Tabela(Linha,Col), Col=1,4)
END DO
& produz:77 56 32 25
---------------------99 10 100 46
---------------------48 89 78 33
---------------------
João Miguel C. Sousa GCAR , DEM, IST 190
Processamento tabelas
1 Tabelas constantes• Tabelas unidimensionais podem ser redimensio-
nadas para tabelas multidimensionais:
RESHAPE(tabela_fonte,forma,preenche,ordem)
• Retorna tabela derivada de tabela_fonte, com a forma especificada, seguida por elemen-tos da tabela preenche, se necessário. A tabela ordem especifica a ordem variação dos índices.
• Argumentos preenche e ordem são opcionais.
& Exemplo 1:A = RESHAPE((/ 11,22,33,44,55,66 /), (/2, 3/))
ouA = RESHAPE((/ 11*N, N = 1, 6 /), (/2, 3/))
atribui a A a matriz 2 × 3:
664422
553311
João Miguel C. Sousa GCAR , DEM, IST 191
Tabelas constantes (exemplo)
& Exemplo 2:A = RESHAPE((/ 11,22,33,44,55,66 /), (/2, 3/), &
ORDER = (/2, 1/))
atribui a A a matriz:
& Exemplo 3:A = RESHAPE((/ 11,22,33,44 /), (/2, 3/), &
PAD = (/0 , 0/), ORDER = (/2, 1/))
ouA = RESHAPE((/ 11,22,33,44 /), (/2, 3/), &
(/0 , 0/), (/2, 1/))
atribui a A a matriz:
1 Instrução SHAPE(tabela)
665544
332211
0044
332211
João Miguel C. Sousa GCAR , DEM, IST 192
Expressões e sub-tabelas
1 Expressões com tabelas& Exemplo:
INTEGER, DIMENSION(2,2) :: A,B
sendo A uma matriz de 2 × 2 dada por:
a instruçãoB = 2*A + 1
atribui a B a matriz
1 Sub-tabelas são definidas como:nome_tabela(seccao_sub-indices)
• onde cada item na seccao_sub-indices é um índice, ou um vector de índices.
−
−
10
128
−
−
11
2515
49
João Miguel C. Sousa GCAR , DEM, IST 193
Sub-tabelas (exemplos)
& Exemplo:INTEGER, DIMENSION(2,3) :: A
com os valores dados no Exemplo 3 da pág. 186. & Exemplo sub-tabela 1:
A(1:2:1, 2:3:1)
A(:, 2:3)
é a tabela de 2 × 2 dada pelas 2 últimas colunas de A:
& Exemplo sub-tabela 2:A(2, 1:3:1)
A(2, :)
é a tabela unidimensional dada pela última linha de A:
& Exemplo sub-tabela 3:A((/ 2, 1 /), 2:3)
6655
3322
[ ]665544
3322
6655
João Miguel C. Sousa GCAR , DEM, IST 194
Atribuição a tabelas n-dimensionais
1 Atribuição de tabelasvariavel_tabela = expressao
• onde expressao pode ser:1 uma tabela da mesma dimensão1 um valor simples
& Exemplo 1:INTEGER, DIMENSION(2,3) :: AINTEGER, DIMENSION(3,2) :: B
& Instrução 1:A = 0
retorna A:
& Instrução 2:B = RESHAPE(A, (/3 ,2/))
retorna tabela B:
000
000
00
00
00
João Miguel C. Sousa GCAR , DEM, IST 195
Atribuição a tabelas (exemplos)
& Instrução 3:A(:, 2:3) = RESHAPE((/ I**2, I=1,4) /), (/2,3/))
muda A para:
& Exemplo 2:REAL, DIMENSION(2,3) :: Alfa, Beta
& Alfa é dado por:
& Exemplo com a instrução WHERE :WHERE (Alfa /= 0)
Beta = 1.0 / REAL(Alfa)ELSEWHERE
Beta = 0.0END WHERE
retorna tabela Beta:
1640
910
0.50.100.0
0.00.20.1
2.01.00.0
0.05.00.1
João Miguel C. Sousa GCAR , DEM, IST 196
Funções com tabelas n-dimensionais
1 Funções intrínsecas - mais usadas:• ALLOCATED(A)
• MATMUL(A, B)
• MAXVAL(A, D)
• MAXLOC(A)
• MINVAL(A, D)
• MINLOC(A)
• PRODUCT(A, D)
• RESHAPE(A, S, P, O)
• SHAPE(A)
• SUM(A, D)
• SPREAD(A, D, N)
• TRANSPOSE(A)
50
João Miguel C. Sousa GCAR , DEM, IST 197
Tabelas definidas pelo programador
1 Os parâmetros actuais e formais do tipo tabela devem ter o mesmo tipo e formato.
1 Existem 3 formas de definir tabelas dentro de subprogramas.1 Tabela definida explicitamente em dimensão e
extensão no subprograma.
2 Subprograma recebe a extensão das dimensões da tabela como argumentos.
3 Tabela recebe uma tabela de dimensões pré-assumidas.
• Estas três formas são extrapolações das definições para tabelas unidimensionais
João Miguel C. Sousa GCAR , DEM, IST 198
Processamento de matrizes
1 Matriz: tabela bidimensional de m × n.
1 Operações em Fortran são efectuadas elemento a elemento:• Soma:
A + B
• Subtracção:A - B
• Multiplicação:A * B
1 A multiplicação uma matriz A de m × n por outra B de n × p, é dada por:
MATMUL(A, B)
1 Outras operações como a transposta são dadas por funções intrínsecas.
João Miguel C. Sousa GCAR , DEM, IST 199
Tipos de dados estruturados
1 Tipos de dados intrínsecos em Fortran• INTEGER
• REAL
• COMPLEX
• CHARACTER
• LOGICAL
1 É possível definir tipos (estruturas) ou fichas.
1 Ficha - armazena elementos de tipos diferentes
& Exemplo: ficha de aluno de IP contém:& Nome (cadeia de caracteres)
& Número (inteiro)
& Nota exame (real)
& Nota projecto (real)
& Nota final (inteiro)
João Miguel C. Sousa GCAR , DEM, IST 200
Tipos estruturados
Definição de tipos estruturados (fichas)____________________________________________________________________
Forma:TYPE, nome_tipo
declaracao1declaracao2...
declaracaokEND TYPE nome_tipo
1 Onde:• o nome_tipo é um identificador em Fortran;
• cada declaracaoi declara um ou mais componentes da estrutura deste tipo.
1 Objectivo: declara tipo estruturado (ficha) cujos componentes são declarados em declaracao1, …,declaracaok. Estas definições são efectuadas na zona de especificações do programa.
51
João Miguel C. Sousa GCAR , DEM, IST 201
Exemplos de fichas
& Exemplo 1: ficha de alunoTYPE Ficha_Aluno
CHARACTER(20) :: NomeINTEGER :: NumeroREAL :: Exame, ProjectoINTEGER :: NotaFinal
END TYPE Ficha_Aluno
& Exemplo 2: ponto no espaço 2-DTYPE Ponto2D
REAL :: X, YEND TYPE Ponto2D
Aluno1 Aluno2 Nome Nome Numero Numero Exame Exame Projecto Projecto NotaFinal NotaFinal
João Miguel C. Sousa GCAR , DEM, IST 202
Declaração de estruturas
Declaração de estruturas____________________________________________________________________
Forma:TYPE(nome_tipo) :: lista_identificadores
1 Objectivo: declara os identificadores que serão os nomes das estruturas cujos componentes são declarados na definição do tipo nome_tipo .
& Exemplo: estruturas dos tipos definidos no Ex. 1 e no Ex. 2 anteriores:
TYPE(Ficha_Aluno) :: Aluno1, Aluno2TYPE(Ficha_Aluno), DIMENSION(50) :: Alunosou:TYPE(Ficha_Aluno):: Alunos(50)
TYPE(Ponto2D) :: Ponto1, Ponto2
João Miguel C. Sousa GCAR , DEM, IST 203
Construtores de fichas
Forma:nome_tipo(lista_componentes)
& Exemplo 1:Ponto2D(2.5, 3.2)
• é um valor do tipo Ponto2D e pode ser atribuida a P:P = Ponto2D(2.5, 3.2)
• Declaração da constante Centro:TYPE(Ponto2D), PARAMETER :: Centro = &
Ponto2D(2.5, 3.2)
• Declaração da constante Centro:TYPE(Ponto2D), PARAMETER :: Centro = &
Ponto2D(2.5, 3.2)
A = 1.1
P = Ponto2D(A, 2*A)
& Exemplo 2:Aluno1 = Ficha_Aluno(“J.Silva”, 10000, &
15., 17., 16)Alunos(1) = Aluno1
João Miguel C. Sousa GCAR , DEM, IST 204
Acesso a componentes de fichas
1 Componentes individuais são acedidos por variáveis qualificadas dadas por:• Nome da estrutura e
• Nome do componente,• juntos pelo selector de componente: “%”:
nome_estrutura%nome_componente
& Exemplos:• P%X é o primeiro componente da estrutura P do tipo
Ponto2D, e P%Y é o segundo componente.
• Alunos(1)%Nome é o primeiro componente da estrutura Alunos(1) do tipo Ficha_Aluno, etc.
Aluno1%Nome = “Jose Silva”
READ(*, *) Aluno1%Nome
PRINT(*, *) Aluno1%Nome
Aluno1%Nome(1:1) = “J”
52
João Miguel C. Sousa GCAR , DEM, IST 205
Estruturas encadeadas
1 Os componentes de um tipo podem ser de qualquer tipo; mesmo de outra estrutura.& Exemplo:
TYPE Ponto2DREAL :: X, Y
END TYPE Ponto2D
TYPE CirculoTYPE(Ponto2D) :: CentroREAL :: Raio
END TYPE Circulo
TYPE(Circulo) :: C• declara C que é uma variável do tipo Circulo e tem
dois componentes, onde o primeiro é do tipo Ponto2D, e o segundo do tipo REAL.
C = Circulo(Ponto2D(2.5, 3.2), 10.0)
• representa um círculo de raio 10.0 e centrado em (2.5, 3.2).
• O valor de C%Centro%X é de 2.5.
João Miguel C. Sousa GCAR , DEM, IST 206
Processamento e atribuições
1 E/S de estruturas tem de ser efectuada componente a componente
& Exemplos: leitura e escrita da variável Aluno do tipo Ficha_Aluno, e atribuição por componentes.
READ(*, *) Aluno%Nome, Aluno%Numero, Aluno%Exame, &Aluno%Projecto, Aluno%NotaFinal
WRITE(*, ‘(1X, “Nome: ”, A)’) Aluno%NomeWRITE(*, ‘(1X, “Numero: ”, I5)’) Aluno%NumeroWRITE(*, ‘(1X, “Exame: ”, F6.1)’) Aluno%ExameWRITE(*, ‘(1X, “Projecto: ”, F6.1)’) Aluno%ProjectoWRITE(*, ‘(1X, “Nota Final: ”, I4)’) Aluno%NotaFinal
Aluno2%Nome = Aluno%NomeAluno2%Numero = Aluno%NumeroAluno2%Exame = Aluno%ExameAluno2%Projecto = Aluno%ProjectoAluno2%NotaFinal = Aluno%NotaFinal
1 Atribuiçãovariavel_estrutura = expressao_estrutura
& Exemplo:Aluno2 = Aluno
João Miguel C. Sousa GCAR , DEM, IST 207
Estruturas como argumentos
1 As estruturas podem ser usadas como argumentos de sub-programas.
1 Os parâmetros actuais e formais devem ser do mesmo tipo!
& Exemplo: programa que dados dois pontos calcula a distância entre eles e a recta que passa pelos dois.
• Distância entre 2 pontos P1 com coordenadas (x1, y1) e P2 com coordenadas (x2, y2):
• Recta que passa nos pontos P1 e P2:
onde;
212
212 )()( yyxx −+−
bmxy +=
12
12
xxyy
m−
−=
11 xmyb −=
João Miguel C. Sousa GCAR , DEM, IST 208
Programa: Pontos e linhas (1)
PROGRAM Pontos_e_Linhas!------------------------------------------------------------! Programa que le dois pontos P1 e P2 representados como ! estruturas, calcula a distancie entre P1 e P2 e calcula a ! equacao da recta unindo os dois pontos. ! Identificadores usados:! Ponto : ficha representada em 2 dimensoes! P1, P2 : dois pontos a ser processados! Distancia : funcao que calcula distancia entre pontos! EquacaoRecta : subrotina que calcula a equacao duma recta! Resposta : resposta do utilizador!! Entradas: Coordenadas dos pontos P1 e P2! Saidas: distancia entre 2 pontos e recta entre eles!------------------------------------------------------------IMPLICIT NONE TYPE Ponto
REAL :: X, YEND TYPE Ponto
TYPE(Ponto) :: P1, P2CHARACTER(1) :: Resposta
DOWRITE(*, ‘(1X, A)’, ADVANCE = “NO”) &
“ Introduza as coordenadas dos pontos P1 e P2: ”READ (*, *) P1%X, P1%Y, P2%X, P2%YWRITE(*,‘(1X,2(A,“(”,F5.2,“,”,F5.2,“)”), “ e ”, F5.2)’) &
“Distancia entre ”, P1%X, P1%Y, “ e ”, P2%X, P2%Y, &Distancia(P1, P2)
CALL EquacaoRecta(P1, P2)WRITE(*, ‘(/ 1X, A)’, ADVANCE = “NO”) &
“Mais pontos (S ou N)? ”
53
João Miguel C. Sousa GCAR , DEM, IST 209
Programa: Pontos e linhas (2)
READ(*, *) RespostaIF (Resposta /= “S”) EXIT
END DO
CONTAINS
!--Distancia-----------------------------------------------! Funcao que calcula a distancia entre os pontos P1 e P2!! Aceita: Estruturas P1 e P2 do tipo Ponto! Retorna: Distancia entre P1 e P2!----------------------------------------------------------FUNCTION Distancia(P1, P2)
TYPE(Ponto), INTENT(IN) :: P1, P2REAL :: Distancia
Distancia = SQRT((P2%X - P1%X)**2 + (P2%Y - P1%Y)**2)
END FUNCTION Distancia
!--EquacaoRecta--------------------------------------------! Subrotina que calcula a equacao da recta y = mx + b da! linha que passa nos pontos P1 e P2. Variaveis locais:! M : declive da recta! B : interseccao da recta com o eixo dos yy! Aceita: Estruturas P1 e P2 do tipo Ponto! Retorna: Escreve equacao da recta que passa em P1 e P2!----------------------------------------------------------SUBROUTINE EquacaoRecta(P1, P2)
TYPE(Ponto), INTENT(IN) :: P1, P2REAL :: M, B
João Miguel C. Sousa GCAR , DEM, IST 210
Programa: Pontos e linhas (3)
IF (P1%X == P2%X) THENWRITE (*, ‘(1X, A, F5.2)’) “Linha vertical x = ”, P1%X
ELSEM = (P2%Y - P1%Y) / (P2%X - P1%X)B = P1%Y - M * P1%XWRITE (*, ‘(1X, 2(A, F5.2))’) &
“Equacao da recta e y = ”, M, “x + ”, BEND IF
END SUBROUTINE EquacaoRecta
END PROGRAM Pontos_e_Linhas
& Exemplo de execução:Introduza as coordenadas dos pontos P1 e P2: 0,0 1,1Distancia entre ( 0.00, 0.00) e ( 1.00, 1.00) e 1.41Equacao da recta e y = 1.00x + 0.00
Mais pontos (S ou N)? SIntroduza as coordenadas dos pontos P1 e P2: 1,1 1,5Distancia entre ( 1.00, 1.00) e ( 1.00, 5.00) e 4.00Linha vertical x = 1.00
Mais pontos (S ou N)? SIntroduza as coordenadas dos pontos P1 e P2: 3.1,4.2 -5.3,7.2Distancia entre ( 3.10, 4.20) e (-5.30, 7.20) e 8.92Equacao da recta e y = -0.36x + 5.31
Mais pontos (S ou N)? N
João Miguel C. Sousa GCAR , DEM, IST 211
Exemplo: Tabela de utilizadores
1 Pretende-se procurar um utilizador numa base de dados, e verificar a utilização dos seus recursos computacionais. • Um dado ficheiro deverá conter o apelido,
nome, número de identificação, recursos disponíveis e recursos utilizados, i.e.:
Babbage Charles 10101 ADA 7503 8081
Newton Isaac 10102 APPLE 6505 9884
Leibnitz Gottfried 10103 CALC 2501 9374
Fahreneit Freda 10104 FRZ32 2501 7793
Celsius Christine 10105 FRZ0 8501 9191
Tower Lean 10106 PISA 3502 2395
VanderVan Henry 10107 VAN 7501 6859
Yale Harvard 20125 IVY 1501 2770
• Dado um número de utilizador, pretende-se que o programa indique o seu nome, apelido e a percentagem dos recursos disponíveis já utilizados.
João Miguel C. Sousa GCAR , DEM, IST 212
Ex: Registo Utiliz. Computadores
PROGRAM Registos_Utilizacao_Computadores!-----------------------------------------------------------! Este programa le numeros de identificacao do teclado,! e procura numa base de dados se esse numero existe, e! nesse caso retorna informacao sobre esse utilizador.! Os identificadores usados sao os seguintes:! ! Tp_Registo_Utilizacao : nome do tipo com informacao! Nome_Ficheiro : nome do ficheiro com dados! Estado_Abertura : variavel de estado para OPEN! Estado_Leitura : variavel de estado para READ! Utilizadores : tabela do Tp_Registo_Utilizacao! Num_Utilizadores : numero de utilizadores! Numero_Procurado : numero de id a procurar! Localizacao : indice do utilizador procurado! Encontrado : indica se a id procurada foi! : ou nao encontrada! Entradas : Numero_Procurado(teclado), Utilizadores(fich.)! Saidas : Numero, nome e % de recursos computacionais! utilizados, ou uma mensagem indicando que o numero! nao foi encontrado.!------------------------------------------------------------IMPLICIT NONE
TYPE Tp_Registo_UtilizacaoCHARACTER(15) :: Nome, ApelidoINTEGER :: Numero_IdentificacaoCHARACTER(6) :: Palavra_chaveREAL :: Recursos_Usados, Limite_Recursos
END TYPE Tp_Registo_Utilizacao
CHARACTER(20) :: Nome_FicheiroTYPE(Tp_Registo_Utilizacao), DIMENSION(20) :: UtilizadoresINTEGER :: Estado_Abertura, Estado_Leitura, iINTEGER :: Num_Utilizadores, Numero_Procurado, LocalizacaoLOGICAL :: Encontrado
54
João Miguel C. Sousa GCAR , DEM, IST 213
Registo Utiliz. Computadores (2)
! Le o nome do ficheiro com os registos e abre-oWRITE(*,'(1X, A)',ADVANCE="NO") "Escreva o nome do ficheiro:"READ (*, *) Nome_FicheiroOPEN (10, FILE = Nome_Ficheiro, STATUS = "OLD", &
IOSTAT = Estado_Abertura)IF (Estado_abertura <= 0) THEN
i = 0DO
i = i+1READ(10,*,IOSTAT=Estado_Leitura) Utilizadores(i)%Apelido,&
Utilizadores(i)%Nome, &Utilizadores(i)%Numero_Identificacao, &Utilizadores(i)%Palavra_chave, &Utilizadores(i)%Recursos_Usados, &Utilizadores(i)%Limite_Recursos
IF (Estado_Leitura<0) EXIT ! Fim do fiheiroEND DONum_Utilizadores = i-1
DO ! Procura numero identificacaoWRITE(*,*)WRITE(*,'(1X,A)',ADVANCE="NO") "Escreva o numero de &
&utilizador (0 para parar): "READ (*,*) Numero_ProcuradoIF (Numero_Procurado /= 0) THEN
CALL Procura_Numero(Utilizadores(1:Num_Utilizadores), &Numero_Procurado,Encontrado,Localizacao)
IF (Encontrado) THENWRITE(*,'(1X, I5, 1X, 2A)') &
Utilizadores(Localizacao)%Numero_Identificacao, &Utilizadores(Localizacao)%Nome, & Utilizadores(Localizacao)%Apelido
WRITE(*,'(1X, "utilizou", F5.1, "% de recursos")') & 100.0 * Utilizadores(Localizacao)%Recursos_Usados &/ Utilizadores(Localizacao)%Limite_Recursos
João Miguel C. Sousa GCAR , DEM, IST 214
Registo Utiliz. Computadores (3)
ELSEWRITE(*,*) Numero_Procurado, " nao encontrado."
END IFEND IF
! Se utilizador indicar, acaba o ciclo.IF (Numero_Procurado == 0) EXIT
END DOELSE
WRITE(*,*) "Erro na abertura de ficheiro!!"PAUSE
END IF
CONTAINS!-Procura_Numero—(...)------------------------------------SUBROUTINE Procura_Numero(Utilizadores,NumProcurado,&
Encontrado,Local) TYPE(Tp_Registo_Utilizacao), DIMENSION(:) :: UtilizadoresINTEGER,INTENT(IN) :: NumProcurado INTEGER,INTENT(OUT) :: LocalLOGICAL,INTENT(OUT) :: EncontradoINTEGER :: NumUtilizadores
NumUtilizadores = SIZE(Utilizadores)Local = 1Encontrado = .FALSE.DOIF ((Local > NumUtilizadores) .OR. Encontrado) EXIT
IF (NumProcurado== &Utilizadores(Local)%Numero_Identificacao) THENEncontrado = .TRUE.
ELSELocal = Local + 1
END IFEND DO
END SUBROUTINE Procura_NumeroEND PROGRAM Registos_Utilizacao_Computadores
João Miguel C. Sousa GCAR , DEM, IST 215
Exemplo de execução
Escreva o nome do ficheiro: dados.dat
Escreva o numero de utilizador (0 para parar): 1010110101 Charles Babbageutilizou 92.8% de recursos
Escreva o numero de utilizador (0 para parar): 1010310103 Gottfried Leibnitzutilizou 26.7% de recursos
Escreva o numero de utilizador (0 para parar): 2012520125 Harvard Yaleutilizou 54.2% de recursos
Escreva o numero de utilizador (0 para parar): 1020010200 nao encontrado
Escreva o numero de utilizador (0 para parar): 1010210102 Isaac Newtonutilizou 65.8% de recursos
Escreva o numero de utilizador (0 para parar): 0
João Miguel C. Sousa GCAR , DEM, IST 216
Outros tipos de dados
1 Tipos de dados parametrizados• Inteiros em Fortran: 32 bits de -2 147 483 648
a +2 147 483 647
• Reais em Fortran: 32 bits -1038 a 1038 aprox. (precisão simples)
• Estes limites podem ser inadequados; podem ser necessária maior ou menor precisão.
• Estas alterações são dadas por tipos de dados parametrizados.
1 Tipo COMPLEX• a + bi, onde a e b são números reais e• i2 = -1
1 Tipo CHARACTER• processamento avançado de cadeias de
caracteres
55
João Miguel C. Sousa GCAR , DEM, IST 217
Tipos de dados parametrizados
1 Representação de números é aproximada• Reais não são representados exactamente
& Exemplo: equação que retorna sempre 1:
PROGRAM Demo_1
IMPLICIT NONEREAL :: A, B, C
READ (*, *) A, B, CC = ((A + B)**2 - 2.0*A*B - B**2) / A**2WRITE (*,*) C
END PROGRAM Demo_1
& Resultados obtidos num dado sistema:
A B AB BA
AA
+ − −= =
a f2 2
2
2
2
21
A B C0.5 888.0 1.00000000.1 888.0 -6.24999950.05 888.0 -24.99999810.03 888.0 69.44444270.02 888.0 1.5625000E+02
João Miguel C. Sousa GCAR , DEM, IST 218
Declaração de tipos parametrizados
Tipos parametrizados____________________________________________________________________
Forma:especificador_tipo(KIND = numero-tipo) &
atributos :: lista
ouespecificador_tipo(numero-tipo) &
atributos :: lista
onde:• o especificador_tipo é em geral:
INTEGERREALCOMPLEXLOGICAL
• o numero-tipo é um inteiro positivo (constante) com valor positivo;
• os atributos são atributos opcionais;• a lista é uma lista de identificadores.
1 Declara que os identificadores na lista têm o tipo e o numero-tipo especificado.
João Miguel C. Sousa GCAR , DEM, IST 219
Tipos parametrizados (concl.)
1 Os números-tipo dependem da máquina e do compilador. Reais mais utilizados:
& Exemplo:REAL(KIND = 2) :: Z
REAL(KIND = 2), DIMENSION(5,5) :: Beta
1 Inteiros mais utilizados:
Tipo NúmeroTipo DescriçãoREAL 1 Valores com precisão simples com aproximadamente
7 dígitos significativos; armazanados em 32 bitsREAL 2 Valores com precisão dupla com aproximadamente
14 dígitos significativos; armazanados em 64 bits
Tipo NúmeroTipo DescriçãoINTEGER 1 Inteiros de 8 bits: -27 até 27 - 1INTEGER 2 Inteiros de 16 bits: -215 até 215 - 1INTEGER 3 Inteiros de 32 bits: -231 até 231 - 1INTEGER 4 Inteiros de 64 bits: -263 até 263 - 1
João Miguel C. Sousa GCAR , DEM, IST 220
Tipo de dados COMPLEX
1 Tipo COMPLEX• a + bi, onde a e b são reais. Em Fortran:
(a, b)
1 Declarações de complexosCOMPLEX :: A, B
COMPLEX, DIMENSION(10,10) :: Rho
1 Operações com complexos
• Soma
• Subtração
• Produto
• Divisão
z a bi w c di= + = +e
z w a c b d i+ = + + +( ) ( )
z w a c b d i− = − + −( ) ( )
z w ac bd ad bc i⋅ = − + +( ) ( )
zw
ac bdc d
bc adc d
i=+
++
−
+2 2 2 2
56
João Miguel C. Sousa GCAR , DEM, IST 221
Tipo complexo (exemplos)
& Exemplo de operações (C e Z variáveis complexas):
C = (6.2, 2.4)
Z = 4.0 * C / 2
& retorna para Z o valor:
(12.4, 4.8)
& Se for atribuída a X do tipo real: X = 4.0 * C/2, retorna o valor 12.4
& Se for atribuída a N do tipo inteiro: N = 4.0 * C/2, retorna o valor 12
1 Funções complexas intrínsecas:• ABS(z)
• CONJG(z)
• EXP(z)
• AIMAG(z)
• CMPLX(x, y)
• REAL(z)
João Miguel C. Sousa GCAR , DEM, IST 222
Entrada e saída de complexos
1 Lidos como um par de reais ou 2 reaisPROGRAM Demo_2
IMPLICIT NONECOMPLEX :: X, Y, W, Z, A
READ(*, *) X, YREAD(*, ‘(2F2.0)’) WWRITE(*, *) X, YWRITE(*, *) WWRITE(*, 10) X, Y, W10 FORMAT(1X, F5.2, “ +”, F8.2, “I”)Z = (X + Y) / (1.0, 2.2)A = X * YWRITE(*, 10) Z, A
END PROGRAM Demo_2
1 Entrada de dados:
(3,4), (0.75, -2.23)5 7
1 Saída produzida:
( 3.0000000, 4.0000000) ( 0.7500000, -2.2300000)( 5.0000000, 7.0000000)
3.00 + 4.00I0.75 + -2.23I5.00 + 7.00I1.31 + -1.11I
11.17 + -3.69I
João Miguel C. Sousa GCAR , DEM, IST 223
O tipo CHARACTER
1 Cadeia de caracteres vazia• “” ou ‘’
1 Compilador associa cada variável a um endereço em memória. Nomes das variáveis são identificadores.
Declaração de cadeias de caracteres___________________________________________________________
CHARACTER(LEN = n) :: listaou
CHARACTER(n) :: lista
& Exemplo:CHARACTER(LEN = 15) :: Nome, ApelidoCHARACTER(15) :: Nome
1 Em subprogramas os argumentos formais podem ser pré-definidos:CHARACTER(*) :: lista_identificadores
João Miguel C. Sousa GCAR , DEM, IST 224
Operacões com caracteres
1 Caracteres podem ser parametrizados:CHARACTER(LEN=n, KIND=num_tipo) :: listaCHARACTER(n, KIND=num_tipo) :: listaCHARACTER(n, num_tipo) :: listaCHARACTER(KIND=num_tipo, LEN=n) :: listaCHARACTER(KIND=num_tipo) :: lista
• onde o num_tipo especifica o esquema de codificação (ASCII, EBCDIC, etc.) e/ou o tipo de caracteres (Inglês, Português, Russo, etc.)
1 Operacões com caracteres• Concatenação: operador binário dado por //& Exemplo 1“centi” // “metros” produz:“centimetros”
& Exemplo 2CHARACTER(7) :: UnidadeQuadradaUnidadeQuadrada = “ quadrados”“centi” // “metros” // UnidadeQuadradaproduz:“centimetros quadrados”
57
João Miguel C. Sousa GCAR , DEM, IST 225
Subcadeias de caracteres
& Exemplo: subcadeia dos caracteres 6 a 10 deUnidade = “centimetros”
é dada por:Unidade(6:10) e tem o valor: “metro”
1 As primeiras e últimas posições não necessitam de ser especificadas.
& Exemplo:CHARACTER(15) :: Curso, Nome*20Curso = “Engenharia”
Curso(:3) tem o valor “Eng” eCurso(8:) tem o valor “riaBBBBB”, onde B corresponde a um espaço em branco.
1 A primeira posição deve ser positiva, e a última >=que a primeira, mas não maior que o comprimento da cadeia de caracteres.
1 Podem ser efectuadas atribuições a sub-cadeias, modificando parte de uma cadeia de caracteres.
João Miguel C. Sousa GCAR , DEM, IST 226
Funções com caracteres
1 Funções de cadeias para cadeias:• ADJUSTL(cad_caracteres)
• ADJUSTR(cad_caracteres)
• REPEAT(cad_caracteres, n)
• TRIM(cad_caracteres)
& Exemplo:CHARACTER(10) :: Cadeia = “ ABCDE”
A saída produzida por:WRITE(*, *) “***”, Cadeia, “***”WRITE(*, *) “***”, ADJUSTL(Cadeia), “***”WRITE(*, *) “***”, ADJUSTR(Cadeia), “***”WRITE(*, *) “***”, TRIM(Cadeia), “***”WRITE(*, *) “***”, REPEAT(Cadeia,3), “***”
é a seguinte:*** ABCDE ******ABCDE ****** ABCDE****** ABCDE****** ABCDE ****** ABCDE ABCDE ABCDE ***
João Miguel C. Sousa GCAR , DEM, IST 227
Funções com caracteres (cont.)
1 Funções de comprimento:• LEN(cad_caracteres)
• LEN_TRIM(cad_caracteres)
& Exemplo:CHARACTER(10) :: Cadeia = “ ABCDE”
O valor retornado por:
LEN(Cadeia) retorna 10, eLEN_TRIM(Cadeia) retorna 6.
1 Funções de procura:• INDEX(cadeia1, cadeia2) ou
• INDEX(cadeia1, cadeia2, atras)
• SCAN(cadeia1, cadeia2) ou
• SCAN(cadeia1, cadeia2, atras)
• VERIFY(cadeia1, cadeia2) ou
• VERIFY(cadeia1, cadeia2, atras)
João Miguel C. Sousa GCAR , DEM, IST 228
Exemplo com funções de procura
& Exemplo:CHARACTER(25) :: Unidades = “centimetros e metros”
A saída produzida por:WRITE(*, *) INDEX(Unidades, “metros”)WRITE(*, *) INDEX(Unidades, “metros”, .FALSE.)WRITE(*, *) INDEX(Unidades, “metros”, .TRUE.)WRITE(*, *) INDEX(Unidades, “cents”)WRITE(*, *) SCAN(“kilometro”, Unidades)WRITE(*, *) SCAN(“kilometro”, Unidades, .FALSE.)WRITE(*, *) SCAN(“kilometro”, Unidades, .TRUE.)WRITE(*, *) SCAN(“flora”, Unidades)WRITE(*, *) VERIFY(“kilometro”, Unidades)WRITE(*, *) VERIFY(“kilometro”, Unidades, .FALSE.)WRITE(*, *) VERIFY(“kilometro”, Unidades, .TRUE.)WRITE(*, *) VERIFY(“tenis”, Unidades)
é a seguinte:6615022931130
58
João Miguel C. Sousa GCAR , DEM, IST 229
Gestão de memória em tabelas
1 Instruções ALLOCATE e DEALLOCATE utili-zam memória quando o programa corre.• permitem utilizar apenas a memória necessária
• evitam desperdício de memória
• eficientes para tabelas com tamanho constante
1 Para dados de diferentes tamanhos, quando se varia o tamanho da tabela efectuam-se as seguintes operações:• Uma nova tabela é alocada.
• Os elementos da tabela antiga são copiados para a tabela nova.
• Os novos elementos são introduzidos na nova tabela.
• A tabela antiga é apagada da memória.
1 Estas operações demoram bastante tempo!
João Miguel C. Sousa GCAR , DEM, IST 230
Ponteiros
1 As tabelas (mesmo alocadas) são estruturas de dados estáticas.
1 Estruturas de dados dinâmicas permitem expandir ou contrair a estrutura durante a execução.
• É constituída por uma colecção de elementos, chamados nós ligados entre si.
• Esta ligação associa a cada nó um ponteiropara o próximo nó da estrutura.
• Exige a necessidade de alocar e aceder à memória durante a execução dum programa.
• Variáveis que apontam para essas localizações em memória: ponteiros.
& Exemplo: Lista ligada
Prox Prox ProxDados Dados Dados
XXX YYY ZZZLista
João Miguel C. Sousa GCAR , DEM, IST 231
Listas implementadas em tabelas
1 Tabelas podem implementar listas. São no entanto ineficientes para:• tamanhos variáveis durante a execução,
• inserir e retirar elementos na lista.
1 Cada vez que elementos novos são inseri-dos dever-se-á mover elementos na tabela.
& Exemplo 1: Inserir 42 na lista 23, 25, 34, 48, 61, 89. Os elementos 4 a 6 devem ser deslocados para as posições 5 a 7, para o novo elemento ser introduzido em 4:
& Exemplo 2: Retirar 25 da lista:
23 25 34 48 61 89 ? ... ?
23 25 34 42 48 61 89 ... ?
23 34 42 48 61 89 ? ... ?
23 25 34 42 48 61 89 ... ?
João Miguel C. Sousa GCAR , DEM, IST 232
Listas ligadas
1 Contém uma colecção de elementos chamados nós, que contêm:1 um elemento da lista,
2 um ponteiro para o nó seguinte. O acesso ao nó inicial (1º elemento da lista) deve ser mantido.
& Exemplo: lista com nomes Silva, Fonseca e Castro
• A variável Lista aponta para o primeiro nó da lista, e o Prox aponta para o próximo nó.
• o símbolo “terra” não aponta para nada, indicando assim o fim da lista (ponteiro vazio ou null pointer).
Prox Prox ProxDados Dados Dados
Silva Fonseca CastroLista
59
João Miguel C. Sousa GCAR , DEM, IST 233
Inserção de elementos em listas
1 Nas listas ligadas não é necessário mover elementos quando se altera a lista.
1 Para inserir um novo elemento na lista:1 Criar um novo nó. Guardar o valor a inserir no
elemento do nó 0 (pressupõe-se que é possível obter nós duma
dada fonte, e que estão nós disponíveis)2 Ligar o novo nó à lista. Podem existir 2 casos:
1 o nó é acrescentado no início da lista;
2 o nó é inserido no meio da lista.
& Exemplo 1: inserir o nome Reis no início da lista
• Criar um nó com o nome Reis. O ponteiro NovoPont aponta para este nó.
Prox Prox ProxDados Dados Dados
Silva Fonseca CastroLista
ProxDados
ReisNovoPont
João Miguel C. Sousa GCAR , DEM, IST 234
Exemplo 1 inserção em listas
• O nó é inserido na lista, com a sua ligação a apontar para o primeiro nó na lista; o Prox de NovoPont aponta para o mesmo que Lista:
• Ao ponteiro Lista é atribuído NovoPont:
& Exemplo 2: inserir nome Ramos após Fonseca, onde PontPred é o ponteiro predecessor:
Prox Prox ProxDados Dados Dados
Silva Fonseca CastroLista
ProxDados
ReisNovoPont
Prox Prox ProxDados Dados Dados
Silva Fonseca CastroLista
ReisNovoPont
Prox Prox ProxDados Dados Dados
Silva Fonseca CastroLista
PontPred
João Miguel C. Sousa GCAR , DEM, IST 235
Exemplo 2 inserção em listas
• Criar um nó com o nome Ramos (como ant.):
• Prox de NovoPont igual a Prox de PontPred
• Prox de PontPred igual a NovoPont:
ProxDados
RamosNovoPont
Prox Prox ProxDados Dados Dados
Silva Fonseca CastroLista
PontPred
ProxDados
RamosNovoPont
Prox Prox ProxDados Dados Dados
Silva Fonseca CastroLista
PontPred
ProxDados
RamosNovoPont
Prox Prox ProxDados Dados Dados
Silva Fonseca CastroLista
PontPred
João Miguel C. Sousa GCAR , DEM, IST 236
Apagar elementos de listas
1 Tal como na inserção existem 2 casos:1 apagar o primeiro elemento da lista;2 apagar um elemento com um predecessor.
& Exemplo 1: para apagar o nome Silva no início da lista basta passar Lista para o segundo nó.
• Atribui a PontAux o ponteiro Lista.
• Atribui a Lista o Prox de PontAux.
• Ponteiro PontAux enviado para pilha de livres.
Prox Prox ProxDados Dados Dados
Silva Fonseca CastroLista
Prox Prox ProxDados Dados Dados
Silva Fonseca CastroLista
PontAux
Prox Prox ProxDados Dados Dados
Silva Fonseca CastroLista
PontAux
Prox ProxDados Dados
Fonseca CastroLista
PontAux
60
João Miguel C. Sousa GCAR , DEM, IST 237
Apagar elementos de listas (concl.)
& Exemplo 2: apagar o nome Fonseca da lista inicial.
• Atribui ao ponteiro PontAux o ponteiro Proxde PontPred.
• Atribui a Prox de PontPred o ponteiro Proxde PontAux.
• Coloca o ponteiro PontAux na pilha de ponteiros disponíveis.
Prox Prox ProxDados Dados Dados
Silva Fonseca CastroLista
PontPred PontAux
Prox Prox ProxDados Dados Dados
Silva Fonseca CastroLista
PontPred PontAux
Prox ProxDados Dados
Silva CastroLista
PontPred PontAux
João Miguel C. Sousa GCAR , DEM, IST 238
Ponteiros em Fortran
Variáveis do tipo ponteiro____________________________________________________________________
Forma:
tipo, lista-atributos, POINTER :: var_ponteiro
• Declara a variável var_ponteiro, usada para aceder a localizações em memória.
• A variável tem um dado tipo onde os atributos podem ser guardados.
& Exemplo 1: Um ponteiro para dados do tipo cadeia de caracteres é definido como:CHARACTER(10), POINTER :: PontCadeia
• Esta variável só pode ser utilizada para aceder a localizações em memória com 10 caracteres.
& Exemplo 2TYPE :: Info_InventarioINTEGER :: NumeroREAL :: Preco
END TYPE Info_Inventario
TYPE(Info_Inventario), POINTER :: PontInventario
João Miguel C. Sousa GCAR , DEM, IST 239
Criação de ponteiros
Instrução ALLOCATE____________________________________________________________________
Forma:ALLOCATE(ponteiro)
& Exemplo: ALLOCATE(PontCadeia)
• O ponteiro PontCadeia “aponta” para uma localização em memória, chamada alvo, com uma cadeia de caracteres (e.g. “computador”)
1 Estados de associação de ponteiros:1 Indefinido - estado inicial após declaração.
2 Associado - quando aponta para um alvo.
3 Vazio - null pointer; não aponta para nada.
PontCadeia Computador
ponteiro ?
ponteiro
João Miguel C. Sousa GCAR , DEM, IST 240
Associação de ponteiros
1 Função de teste ASSOCIATED
ASSOCIATED(ponteiro)
• Retorna .TRUE. se o ponteiro está associado e .FALSE. caso contrário. O ponteiro não pode estar indefinido.
1 Comando NULLIFY
NULLIFY(ponteiro)
• Torna o ponteiro vazio. A localização em memória não é acessível.
1 Programa dispõe de uma pilha de memória disponível. Instrução ALLOCATE executa:1 Retira um bloco de memória livre da pilha.
2 Aloca esse espaço ao programa executável.
1 Pilha de memória é limitada:ALLOCATE(lista, STAT = variavel-inteira)
DEALLOCATE(lista, STAT = variavel-inteira)
61
João Miguel C. Sousa GCAR , DEM, IST 241
Atribuição de ponteiros
Forma:ponteiro1 => ponteiro2• O ponteiro1 tem a mesma associação do
ponteiro2. O valor anterior de ponteiro1 não é acessível, a não ser que estivesse outro ponteiro a apontar para a mesma localização.
• Antes da atribuição:
• Após a atribuição ponteiro1 => ponteiro2:
& Exemplo:CHARACTER(8), POINTER :: PontCadeia, PontTemp
1 onde PontTemp aponta para “software” e PontCadeiaaponta para “hardware”. Qual o resultado da instrução:
PontTemp => PontCadeia ?
ponteiro1
ponteiro2
ponteiro1
ponteiro2
ponteiro3
ponteiro3
João Miguel C. Sousa GCAR , DEM, IST 242
Expressões com ponteiros
Regra básica:1 Quando um ponteiro associado aparece numa
expressão, é utilizado directamente o valor para o qual está a apontar.
& Exemplo:CHARACTER(10), POINTER :: PontCadeiaCHARACTER(10) :: Produto = “Computador”
PontCadeia = Produto ePontCadeia = “Computador”
retornam:
WRITE(*, *) PontCadeia eIF PontCadeia(4:6) == “put” THEN
WRITE(*, *) PontCadeiaEND IF
imprimem: Computador
PontTemp = PontCadeia
PontCadeia Computador
PontCadeia Computador
PontTemp Computador
João Miguel C. Sousa GCAR , DEM, IST 243
Implementação de listas ligadas
1 é definida como:TYPE Lista_NosINTEGER :: DadosTYPE(Lista_Nos), POINTER :: Proximo
END TYPE Lista_Nos
1 Construção de uma lista ligada
TYPE(Lista_Nos), POINTER :: ListaNumeros, PontTemp
ALLOCATE(PontTemp)PontTemp%Dados = 1550PontTemp%Proximo => ListaNumerosListaNumeros => PontTemp
• Para construir toda a lista, a primeira instrução seria:
NULLIFY(ListaNumeros)
Prox Prox ProxDados Dados Dados
1550 1723 1996ListaNumeros
João Miguel C. Sousa GCAR , DEM, IST 244
Listas ligadas (cont.)
1 Percorrer uma lista ligada, escrevendo todos os seus elementos
PontActual => ListaNumerosDO
IF (.NOT. ASSOCIATED(PontActual)) EXIT ! Fim da listaWRITE (*, *) PontActual%DadosPontActual => PontActual%Proximo
END DO
1 Inserir elemento no meio da listaALLOCATE(PontTemp, STAT = EstadoAlocacao)PontTemp%Dados = ElementoNovo
• Inserir elemento entre PontPred e PontActual:PontTemp%Proximo => PontActualPontPred%Proximo => PontTemp
1 Apagar elementos na lista• Apagar elementos no início da lista
PontActual => ListaLista => PontActual%ProximoDEALLOCATE(PontActual)
• Apagar o elemento apontado por PontActualprecedido por PontPred meio da lista
PontPred%Proximo => PontActual%ProximoDEALLOCATE(PontActual)
62
João Miguel C. Sousa GCAR , DEM, IST 245
Aplicação: Endereços Internet
1 Protocolos de comunicação• TCP (Transmission Control Protocol)
• IP (Internet Protocol)
1 TCP/IP identification endereços únicos na Internet. Exemplo:
dem.ist.utl.pt
• endereço do Dep. Eng. Mecânica do IST
1 Os 4 campos correspondem a:
host.subdomain.subdomain.rootdomain
1 Estes endereços são dados por inteiros:193.136.128.2
João Miguel C. Sousa GCAR , DEM, IST 246
Problema: Acesso à Internet
1 Uma porta de acesso é um sistema de ligação entre duas redes de computadores.• Exemplo: ligação de uma Universidade com a
Internet.
• Cada vez que um estudante acede à WWW o seu endereço TCP/IP é guardado num ficheiro.
1 Problema: O administrador do sistema pretende verificar periodicamente quem e quantas vezes acedeu à Internet.
1 Solução:• Entrada: O ficheiro contendo os endereços
TCP/IP
• Saída: Uma lista com os diferentes endereços e o número de vezes que aparecem no ficheiro
• Existem 232 possibilidades de endereços, logo uma estrutura estáctica, tal como uma tabela, não é eficiente.
João Miguel C. Sousa GCAR , DEM, IST 247
Algoritmo: Acesso à Internet
1 Identificadores• NomeFicheiro – nome do ficheiro• Endereco – o endereço TCP/IP• ListaEnderecos – lista ligada de endereços
Algoritmo1 Este algoritmo encontra endereços TCP/IP
gravados num ficheiro e o número de vezes que ocorrem.
1 Entrada: NomeFicheiro – ficheiro contendo os endereços TCP/IP.
1 Saída: Lista com os endereços e o número de vezes que aparecem no ficheiro.
1. Lê o nome do ficheiro e abre-o para leitura. Se o ficheiro não fôr aberto acaba o programa.
2. Inicializa a ListaEnderecos como lista vazia.
João Miguel C. Sousa GCAR , DEM, IST 248
Algoritmo: Acesso à Internet (2)
3. Repete o seguinte:a) Lê um endereço do ficheiro
b) Se existe erro de leitura escreve mensagem de erro.
c) Caso contrário:
d) Se não há mais endereços termina o ciclo.
e) Caso contrário:i. Procura na ListaEnderecos se Endereco está
contido na lista.
ii. Se endereço já existeIncrementa contador desse Endereco
Caso contrárioInsere novo endereço na lista, com contador a 1.
4. Atravessa Lista Enderecos e escreve cada TCP/IP e o valor do seu contador.
63
João Miguel C. Sousa GCAR , DEM, IST 249
Programa: Enderecos_Internet
PROGRAM Enderecos_Internet!-----------------------------------------------------------! Este programa le enderecos TCP/IP de um ficheiro e! Produz uma lista de enderecos distintos indicando quantas! Vezes esses enderecos aparecem no ficheiro.! Variáveis usadas:! ! Nome_Ficheiro : nome do ficheiro com enderecos! Estado_Abertura : variavel de estado para OPEN! Estado_Leitura : variavel de estado para READ! Endereco : endereco lido do ficheiro! ListaEnderecos : ponteiro para o primeiro no da! Lista de enderecos!! Subrotinas utilizadas para processar listas:! Adiciona_Lista, Procura, Enderecos_saida!! Entradas : NomeFicheiro(teclado), Enderecos (ficheiro)! Saidas : Lista com enderecos distintos e numero de ! ocorrencias.!------------------------------------------------------------IMPLICIT NONE
!Definicao do tipo no-enderecoTYPE Lista_No
CHARACTER(15) :: Endereco_TCP_IP !Dados enderecoINTEGER :: Contador !Contador desse enderecoTYPE(Lista_No), POINTER :: Prox !Ponteiro para prox. no
END TYPE Lista_No
CHARACTER(15) :: Endereco, Nome_Ficheiro*20INTEGER :: Estado_Abertura, Estado_LeituraTYPE(Lista_No), POINTER :: ListaEnderecos
João Miguel C. Sousa GCAR , DEM, IST 250
Programa: Enderecos_Internet (2)
! Le o nome do ficheiro com os registos e abre-oWRITE(*,'(1X, A)',ADVANCE="NO") "Escreva o nome do ficheiro:"READ (*, *) Nome_FicheiroOPEN (10, FILE = Nome_Ficheiro, STATUS = "OLD", &
IOSTAT = Estado_Abertura)IF (Estado_abertura > 0) THEN
WRITE(*, *) “*** Ficheiro de enderecos invalido ***”ELSE
!Cria uma lista de enderecos vaziaNULLIFY(ListaEnderecos)
!Le enderecos do ficheiro ate ao fim do ficheiroDO
READ(10,*,IOSTAT=Estado_Leitura) EnderecoIF (Estado_Leitura<0) EXIT ! Fim do ficheiro
CALL Adiciona_a_Lista(ListaEnderecos,Endereco)END DO
END IF
CALL Escreve_Enderecos(ListaEnderecos)
CONTAINS
!----------------------------------------------------------! Esta subrotina verifica se Endereco ja se encontra! na lista ligada (utilizando Procura). Se nao, Endereco! e acrescentado no inicio da lista. Se sim, o contador! e incrementado de 1 elemento. Variaveis locais:! EstadoAlocacao : estado da instrucao OPEN! PontLocal : pont. para o no com Endereco, ou vazio! Esta_na_Lista : indica se Endereco se encontra na! ListaEnderecos!! Recebe: ListaEnderecos e Endereco! Retorna: ListaEnderecos modificada!----------------------------------------------------------
João Miguel C. Sousa GCAR , DEM, IST 251
Subrotina: Adiciona_a_Lista
SUBROUTINE Adiciona_a_Lista(ListaEnderecos,Endereco)
TYPE(Lista_No), POINTER :: ListaEnderecosCHARACTER(*), INTENT(IN) :: EnderecoTYPE(Lista_No), POINTER :: PontLocalINTEGER :: EstadoAlocacaoLOGICAL :: Esta_na_Lista
IF (.NOT. ASSOCIATED(ListaEnderecos)) THEN !Lista vaziaALLOCATE(ListaEnderecos, STAT = EstadoAlocacao)IF (EstadoAlocacao /= 0) THEN
WRITE(*, *) “*** Nao ha memoria disponivel! ***”ELSE
ListaEnderecos%Endereco_TCP_IP = EnderecoListaEnderecos%Contador = 1NULLIFY(ListaEnderecos%Prox)
END IFELSE !Lista nao vaiza; determina se Endereco ja existe
CALL Procura_em_Lista(ListaEnderecos,Endereco, &PontLocal,Esta_na_Lista)
IF (Esta_na_Lista) THEN ! Incrementa contador de umPontLocal%Contador = PontLocal%Contador + 1
ELSE !Cria um novo no e insere-o no inicio da listaALLOCATE(PontLocal, STAT = EstadoAlocacao)IF (EstadoAlocacao /= 0) THEN
WRITE(*, *) “*** Nao ha memoria disponivel! ***”ELSE
PontLocal%Endereco_TCP_IP = EnderecoPontLocal%Contador = 1PontLocal%Prox => ListaEnderecosListaEnderecos => PontLocal
END IFENDIF
ENDIF
END SUBROUTINE Adiciona_a_Lista
João Miguel C. Sousa GCAR , DEM, IST 252
Subrotina: Procura_em_Lista
!----------------------------------------------------------! Esta subrotina procura na ListaEnderecos por um no! contendo Endereco. Se este endereco for encontrado, ! o ponteiro PontLocal aponta para o no com Enderec, e ! Esta_na_Lista retorna verdadeiro; caso contrario! PontLocal e vazio (NULL) e Esta_na_Lista falso.!! Recebe: ListaEnderecos e Endereco! Retorna: PontLocal, Esta_na_Lista!----------------------------------------------------------
SUBROUTINE Procura_em_Lista(ListaEnderecos, Endereco, &PontLocal, Esta_na_Lista)
TYPE(Lista_No), POINTER :: ListaEnderecos, PontLocalCHARACTER(*), INTENT(IN) :: EnderecoLOGICAL, INTENT(OUT) :: Esta_na_Lista
PontLocal => ListaEnderecosEsta_na_Lista = .FALSE.
! Percorre a lista ate encontrar endereco ou ate ao fimDO
IF(Esta_na_Lista .OR. .NOT. ASSOCIATED(PontLocal)) EXIT! Endereco nao encontrado ou fim da lista termina ciclo
IF (PontLocal%Endereco_TCP_IP == Endereco) THENEsta_na_Lista = .TRUE.
ELSE ! Procura no proximo elementoPontLocal => PontLocal%Prox
END IFEND DO
END SUBROUTINE Procura_em_Lista
64
João Miguel C. Sousa GCAR , DEM, IST 253
Subrotina: Enderecos_Saida
!----------------------------------------------------------! Esta subrotina escreve o conteudo da lista ligada! Apontada por ListaEnderecos. Imprime o endereco e o ! contador de cada no. ! Variveis locais:! PontAux : ponteiro que percorre a lista!! Recebe: ListaEnderecos! Saida: Escreve endrecos e contador nos nos!----------------------------------------------------------
SUBROUTINE Escreve_Enderecos(ListaEnderecos)
TYPE(Lista_No), POINTER :: ListaEnderecos, PontAux
PontAux => ListaEnderecos
WRITE(*, *) WRITE(*, *) "Enderecos de Internet"WRITE(*, *) WRITE(*, *) " Endereco Contador "WRITE(*, *) "------------------------------"
! Escreve informacao nos nos ate ao fim da listaDO
IF (.NOT. ASSOCIATED(PontAux)) EXIT
WRITE(*,‘1X, A, 4X, I4’) PontAux%Endereco_TCP_IP, &PontAux%Contador
PontAux => PontAux%Prox END DO
END SUBROUTINE Escreve_Enderecos
END PROGRAM Enderecos_Internet
João Miguel C. Sousa GCAR , DEM, IST 254
Resultados
1 Ficheiro exfic.dat:128.159.4.20
123.111.222.33
100.1.4.31
34.56.78.90
120.120.120.120
128.159.4.20
123.111.222.33
123.111.222.33
77.66.55.44
100.1.4.31
123.111.222.33
128.159.4.20
1 Exemplo de execução:Escreva o nome do ficheiro: exfic.dat
Endereco Contador---------------------------
77.66.55.44 1
120.120.120.120 1
34.56.78.90 1
100.1.4.31 2
123.111.222.33 4
128.159.4.20 3