Upload
vuhanh
View
213
Download
0
Embed Size (px)
Citation preview
Programação de Computadores
Instituto de Computação UFFDepartamento de Ciência da Computação
Otton Teixeira da Silveira Filho
Conteúdo
● Alguns Conceitos sobre Linguagens
● Conceito de Algoritmo
● Pseudocódigo
● Tipos de Variáveis
● Operadores
● Estruturas de Controle
● Estruturas de Dados
● Subprogramação
Estrutura de um programa em FORTRAN
Estrutura geral
PROGRAM nome
declaração 1
declaração 2
…
comando 1
comando 2
STOP
END
Funções implícitas
O FORTRAN contém funções pré-definidas que correspondem em certo sentido a algumas funções matemáticas
Veremos mais tarde que o conceito de funções em linguagens de programação não correspondem totalmente ao que é chamado de função na matemática
Funções implícitas
Vejamos algumas da funções implícitas no FORTRAN
Nome Definição Argumento Tipo de função
SIN(x) Seno REAL em radianos REAL, REAL*8
ASIN(x) Arcosseno REAL REAL, REAL*8
COS(x) cosseno REAL em radianos REAL, REAL*8
ACOS(x) arcocosseno REAL REAL, REAL*8
TAN(x) tangente REAL em radianos REAL, REAL*8
ATAN(x) arcotangente REAL em radianos REAL, REAL*8
EXP(x) exponencial REAL REAL, REAL*8
LOG(x) logaritmo nepleriano REAL REAL, REAL*8
LOG10(X) logaritmo base 10 REAL RELA, REAL*8
ABS(x) valor absoluto INTEGER, REAL, INTEGER*4, REAL*8 REAL, REAL*8
SQRT(x) raiz quadrada REAL, REAL*8 REAL, REAL*8
Portabilidade
Vimos algumas das funções implícitas do FORTRAN. Existem muitas mais e uma referência está em
https://www.obliquity.com/computer/fortran/intrinsic.html
onde você encontrará uma lista detalhada das funções disponíveis que constituem uma biblioteca de funções.
No entanto, cada fabricante tem funções que extrapolam a biblioteca básica, o que pode ser uma vantagem para alguns mas um problema de portabilidade.
Portabilidade
Portabilidade é a propriedade que um código tem de ser capaz de se executado numa máquina/compilador diferente no qual foi projetado.
Quanto mais portável um programa for, menos modificações serão necessárias para fazer que o mesmo se torne um executável.
Usar bibliotecas específicas de um fabricante pode diminuir a portabilidade de seu programa.
Solução?
Portabilidade
Portabilidade é a propriedade que um código tem de ser capaz de se executado numa máquina/compilador diferente do qual foi projetado.
Quanto mais portável um programa for, menos modificações serão necessárias para fazer que o mesmo se torne um executável.
Usar bibliotecas específicas de um fabricante pode diminuir a portabilidade de seu programa.
Solução?
Leia os manuais...
Funções
E quando não houver uma função de seu interesse na biblioteca de funções?
O FORTRAN, assim como todas a linguagens, permite que você crie suas próprias funções.
Isto se justifica por:
● Funções de uso específico
● Tornar o código mais fácil de ler
● Evitar repetições desnecessárias no código
FUNCTION
As funções são declaradas depois do código que agora chamaremos de programa principal
PROGRAM nome Declaração de variáveis Comandos … a = nomef(...) ... STOP END
Tipo FUNCTION nomef(par1, par2, …, parn) Declaração de variáveis par1, par2, …, parn, outras Comandos … nomef = ... ... RETURN END
FUNCTION
● Uma FUNCTION retorna um único valor do tipo no qual ela foi declarada
● Uma FUNCTION em FORTRAN podem ter vários atributos que denominaremos parâmetros
● A única forma de comunicação entre uma ou mais FUNCTIONS e o programa principal é por passagem de valor destes parâmetros
● Da mesma maneira que o programa principal pode ter vários STOP FUNCTION pode ter vários RETURN.
● Ao chegar ao RETURN a função retorna ao programa principal
FUNCTION
● O valor retornado ao programa principal será o atribuído ao nome da função dentro do corpo da função e do tipo no qual a função é declarada
● FUNCTION necessariamente retorna algum valor
Reescrevendo um programa
Calcule o valor da função exponencial no ponto x=1 usando a série de Taylor truncada em n termos que é dada por
e x
=1+x1!
+x2
2!+
x3
3 !+⋯+
xn
n!
Reescrevendo um programa
PROGRAM e
REAL exp INTEGER fat, i, j, n, ntermos
READ(*,*) n
exp = 1
DO 1 i = 1, ntermos fat = 1 DO 2 j = 1, i fat = fat * j 2 CONTINUE exp = exp + 1.0/fat 1 CONTINUE
WRITE(*,*) exp
STOP END
Reescrevendo um programa
Embora este programa funcione bem, observemos que a legibilidade dele é prejudicada por calcularmos a soma que resulta no valor da série e o fatorial de n simultaneamente
FUNCTION
Vamos criar um programa onde o fatorial seja calculado usando FUNCTION
Fatorial: fluxograma e pseudocódigo
programa fatorial
inteiro fat, i, n
leia n
fat ←1
para i ← 2 até n
fat ←fat * i
fim parafim para
imprima fatimprima fat
fimfim
i ← 2até n
fat ← fat * i
início
fat←1
fat
fim
n
Fatorial: Código FORTRAN
PROGRAM fatorial INTEGER i, n REAL fat
n = 5
fat = 1
DO 1 i = 2, n fat = fat * i
1 CONTINUE
WRITE(*,*) fat
STOP END
Versão como função
REAL FUNCTION fatorial(n) INTEGER i, n REAL fat
fat = 1
DO 1 i = 2, n fat = fat * i 1 CONTINUE
fatorial = fat
RETURN END
Reescrevendo um programa
PROGRAM efat
REAL exp INTEGER i,n
READ(*,*) n
exp = 1.0
DO 1 i = 1, n exp = exp + 1.0/fatorial(i) 1 CONTINUE
WRITE(*,*) exp
STOP END
REAL FUNCTION fatorial(n) INTEGER n, i REAL fat
fat = 1 DO i 1 i = 1, n fat = fat * i 1 CONTINUE fatorial = fat RETURN END
FUNCTION
Os programas são funcionalmente idênticos, ou seja, geram o mesmo resultado mas observe que a versão com FUNCTION é mais legível
FUNCTION
Vamos agora criar uma função que nos dá o valor da função exponencial pelo uso de FUNCTION que passe como parâmetros o valor de x e o número de termos da série, n
FUNCTION PROGRAM expf NTEGER i, j, n REAL x, y
n = 10 x = 0.5 y = expon(x, n)
WRITE(*, 1000) x, exp(x), y 1000 FORMAT(3F15.7)
STOP END
REAL FUNCTION fatorial(n) INTEGER n, i REAL fat
fat = 1.0
DO 1 i = 2, n fat = fat * i 1 CONTINUE fatorial = fat
RETURN END
REAL FUNCTION expon(x, n)
INTEGER i, n REAL x, soma, xaux
soma = 1.0 xaux = x
DO 1 i = 1, n soma = soma + xaux/fatorial(i) xaux = xaux * x
1 CONTINUE
expon = soma
RETURN END
FUNCTION
Experimente fazer a mudança indicada abaixo no código
xaux = x
DO 1 i = 1, n soma = soma + xaux/fatorial(i) xaux = xaux * x 1 CONTINUE
para
xaux = x
DO 1 i = 1, n soma = soma + x/fatorial(i) x = xaux * x 1 CONTINUE
Discuta o porquê da diferença na saída dos valores
Exercício
Determine os números primos menores ou iguais a n usando o Crivo de Eratóstenes.
Exemplo do Crivo de Eratóstenes
Vejamos um exemplo para n = 20
i) Escreva os números de 1 a 20
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
ii) corte da lista os múltiplos de 2
1, 2, 3, x, 5, x, 7, x, 9, x, 11, x, 13, x, 15, x, 17, x, 19, x
ii) corte da lista múltiplos de 3
1, 2, 3, x, 5, x, 7, x, x, x, 11, x, 13, x, x, 17, x, 19, x
iii) como o número 4 já foi cortado, cortemos os múltiplos de 5
1, 2, 3, x, 5, x, 7, x, x, x, 11, x, 13, x, x, 17, x, 19, x
Exemplo do Crivo de Eratóstenes
iv) como o número 6 já foi cortado, cortemos os múltiplos de 7
1, 2, 3, x, 5, x, 7, x, x, x, 11, x, 13, x, x, 17, x, 19, x
v) paramos pois os múltiplos do próximo número não cortado, 11, é maior que 20
Exercício
Uma forma de implementar está em preenchermos um vetor com o valor igual ao seu índice e “matarmos“ os valores múltiplos de cada valor no vetor partindo de 2. Observe que
● Como os primeiros múltiplos serão os de 2, não tem sentido matar valores maiores que n/2
● Da mesma forma, não há sentido em matar valores múltiplos de 3 maiores que n/3 ou múltiplos de 4 maiores que n/4 e etc.
Exercício
PROGRAM eratostenes
INTEGER vetor(100), i, j, n LOGICAL ok
ok = .TRUE.
DO WHILE (ok)
WRITE(*, *) "Entre com um numero positivo e nao nulo ate' 100"
READ(*,*) n
IF (n.LE.100) THEN IF (n.GT.0) THEN ok = .FALSE. ENDIF ENDIF ENDDO
DO 1 i = 1, n vetor(i) = i 1 CONTINUE
DO 3 i = 2, n/2
DO 2 j = 2,n/i
vetor(i * j) = 0
2 CONTINUE
3 CONTINUE
WRITE(*,*) "Os numeros primos entre 2 e ", n, "sao:"
DO 4 k = 1, n
IF (vetor(k).NE.0) WRITE(*, *) vetor(k)
4 CONTINUE
STOP
END
Exercício
Repare que fizemos uma leitura inteligente pois não permitimos valores inválidos, seja por serem negativos ou nulos, seja por “estourar“ a dimensão do vetor
Exercício
Repare que fizemos uma leitura inteligente pois não permitimos valores inválidos, seja por serem negativos ou nulos, seja por “estourar“ a dimensão do vetor
No entanto, esta implementação não é muito inteligente pois ela “mata” o que já está “morto” e usa os valores “mortos” para “matar” múltiplos dele.
Exercício
Repare que fizemos uma leitura inteligente pois não permitimos valores inválidos, seja por serem negativos ou nulos, seja por “estourar“ a dimensão do vetor
No entanto, esta implementação não é muito inteligente pois ela “mata” o que já está “morto” e usa os valores “mortos” para “matar” múltiplos dele.
● Aperfeiçoe este programa de forma que ele não use valores já “mortos” para “matar” seus múltiplos
Exercício
É claro que podemos ter várias implementações do mesmo algoritmo.
Exercício
É claro que podemos ter várias implementações do mesmo algoritmo.
Uma ideia está em usar um vetor LOGICAL inicialmente preenchido com .TRUE., ou seja, a princípio todos os valores representados seriam vistos como primos em potencial. A medida que aplicamos o Crivo de Eratóstenes, marcamos como .FALSE. os números que excluídos como primos
Exercício
PROGRAM eratostenes
LOGICAL vetor(100), ok INTEGER i, j, n
ok = .TRUE.
DO WHILE (ok)
WRITE(*, *) "Entre com um numero positivo e nao nulo ate' 100"
READ(*,*) n
IF (n.LE.100) THEN
IF (n.GT.0) THEN
ok = .FALSE.
ENDIF ENDIF ENDDO
DO 1 i = 1, n vetor(i) = .TRUE. 1 CONTINUE
DO 3 i = 2, n/2
DO 2 j = 2,n/i
vetor(i * j) = .FALSE.
2 CONTINUE
3 CONTINUE
WRITE(*,*) "Os numeros primos entre 2 e ", n, "sao:"
DO 4 k = 1, n
IF (vetor(k)) WRITE(*, *) k
4 CONTINUE
STOP END
Exercício
E se quiséssemos criar uma versão deste programa como função (ou funções)?
● Faremos isto para apresentar alguns aspectos interessantes sobre o uso do FUNCTION
Exercício
● Uma FUNCTION fará a leitura e filtragem da leitura, como nos programas anteriores, e devolverá o valor lido e válido
Exercício
● Uma FUNCTION fará a leitura e filtragem da leitura, como nos programas anteriores, e devolverá o valor lido e válido
● Uma outra FUNCTION determinará e imprimirá os números primos
Exercício
● Uma FUNCTION fará a leitura e filtragem da leitura, como nos programas anteriores, e devolverá o valor lido e válido
● Uma outra FUNCTION determinará e imprimirá os números primos
Observe que está função não precisaria retornar nenhum valor...
Exercício
● Uma FUNCTION fará a leitura e filtragem da leitura, como nos programas anteriores, e devolverá o valor lido e válido
● Uma outra FUNCTION determinará e imprimirá os números primos
Observe que está função não precisaria retornar nenhum valor...
● ...mas toda FUNCTION retorna um valor...
Exercício
Cada função por vez...
Exercício
Leitura INTEGER FUNCTION leitura() LOGICAL ok INTEGER n
ok = .TRUE.
DO WHILE (ok)
WRITE(*, *) "Entre com um numero positivo e nao nulo ate' 100"
READ(*,*) n
IF (n.LE.100) THEN
IF (n.GT.0) THEN
ok = .FALSE.
ENDIF ENDIF ENDDO
leitura = n
RETURN END
Exercício
Determinação e impressão dos primos FUNCTION primos(n) LOGICAL vetor(100) INTEGER i, j, n
DO 1 i = 1, n vetor(i) = .TRUE. 1 CONTINUE
DO 3 i = 2, n/2
DO 2 j = 2,n/i
vetor(i * j) = .FALSE. 2 CONTINUE 3 CONTINUE
WRITE(*,*) "Os numeros primos entre 2 e ", n, "sao:"
DO 4 k = 1, n
IF (vetor(k)) WRITE(*, *) k
4 CONTINUE RETURN END
Exercício
Programa principal
PROGRAM eratostenes2 INTEGER n, bobagem
n = leitura()
bobagem = primos(n)
STOP END
Como toda função retorna um valor, criamos um valor de retorno formal que não tem função nenhuma...
FUNCTION
Vimos que numa FUNCTION não é necessário nenhum parâmetro de entrada mas sempre é necessário que ele retorne algo, mesmo que isto não tenha sentido
FUNCTION
Isto é um tanto deselegante e FUNCTION não tem serventia se precisamos fazer um subprograma devolver vários valores
FUNCTION
Isto é um tanto deselegante e FUNCTION não tem serventia se precisamos fazer um subprograma devolver vários valores
Para tal situação o FORTRAN dispõe da declaração SUBROUTINE
SUBROUTINE
O formato de SUBROUTINE tem similaridade com FUNCTION
SUBROUTINE nome(par 1, par 2, …, par n)
e no programa ou subprograma no qual ele é necessário será invocado com
...
CALL nome(par 1, par 2, … par n)
...
SUBROUTINE
Observe que o nome da SUBROUTINE não devolve um valor como FUNCTION e nem tem um tipo especificado
Relembrando a versão de implementação do Crivo de Eratóstenes com funções, vemos que seria mais interessante e elegante implementarmos a função primos() como SUBROUTINE
Exercício
Determinação e impressão dos primos SUBROUTINE primos(n) LOGICAL vetor(100) INTEGER i, j, n
DO 1 i = 1, n vetor(i) = .TRUE. 1 CONTINUE
DO 3 i = 2, n/2
DO 2 j = 2,n/i
vetor(i * j) = .FALSE. 2 CONTINUE 3 CONTINUE
WRITE(*,*) "Os numeros primos entre 2 e ", n, "sao:"
DO 4 k = 1, n
IF (vetor(k)) WRITE(*, *) k
4 CONTINUE RETURN END
Exercício
Programa principal
PROGRAM eratostenes3 INTEGER n
n = leitura()
CALL primos(n)
STOP END
Exercício
Programa principal
PROGRAM eratostenes3 INTEGER n
n = leitura()
CALL primos(n)
STOP END
O programa fica mais “limpo“ e elegante
SUBROUTINE
Todos os parâmetros especificados em sua declaração são compartilhados com o(s) subprograma(s) que o invocaram
Isto permite que troquemos mais de um valor entre o subprograma que o invoca mas somente os que estiverem na lista de parâmetros
SUBROUTINE
Vamos a um exemplo sobre como os argumentos de SUBROUTINE são afetados na comunicação com o subprograma que o invoca
SUBROUTINE
PROGRAM subroutine1
C Programa originalmente apresentado pela professora Valeria Torres C Programa demonstrativo da dinamica de uso e invocacao de C parametros em subprogramas.
INTEGER a, b, c
a = 1 b = 2 c = 3
CALL teste(c)
WRITE(*,*) a, b, c
STOP END
SUBROUTINE teste(c) INTEGER a, b, c
a = 10 b = 20 c = 30
RETURN END
SUBROUTINE
A saída de impressão será
1 2 30
o que ilustra que os únicos parâmetros visíveis entre os processos são os que são passados como parâmetros.
Reescrevendo um programa
Vamos reescrever o programa de Ordenação por Seleção usando SUBROUTINE
Ordenação por Seleção
PROGRAM selecao
INTEGER vet(10), i, j, k, n, menor, aux
vet(1) = -3 vet(2) = 1 vet(3) = 4 vet(4) = 2 vet(5) = 4
DO 1 i = 1, 4 menor = i
DO 2 j = i+1, 5 IF (vet(menor).GT.vet(j)) menor = j 2 CONTINUE aux = vet(menor) vet(menor) = vet(i) vet(i) = aux 1 CONTINUE
WRITE(*,*) 'Vetor ordenado' , (v(k), k = 1, n)
STOP END
Reescrevendo um programa
Aqui faremos um SUBROUTINE que faça a troca entre as variáveis dadas
Ordenação por Seleção
PROGRAM selecao2
INTEGER vet(10), i, j, k, n, menor, aux vet(1) = -3 vet(2) = 1 vet(3) = 4 vet(4) = 2 vet(5) = 4
DO 1 i = 1, 4 menor = i
DO 2 j = i+1, 5 IF (vet(menor).GT.vet(j)) menor = j 2 CONTINUE CALL troque (vet(menor), vet(i)) 1 CONTINUE
WRITE(*,*) 'Vetor ordenado' , (v(k), k = 1, n)
STOP END
SUBROUTINE troque(a, b)
INTEGER a, b, aux
aux = a a = b b = aux
RETURN END
Ordenação por Seleção
Repare que o nome da SUBROUTINE (como também no caso do nome para FUNCTION) pode ser qualquer um, algo como xpto2i ou c45xc3 ou z
No entanto, é fácil de ver que é melhor um nome que funcione como documentação do que está sendo feito
Exercício
Dada uma matriz A nxn, crie uma matriz D que contém apenas a diagonal de A
Exercício
Observe que este programa é muito simples:
Se os índices da matriz A forem iguais, faça o conteúdo da matriz com estes índices seja atribuído à matriz D
Exercício
PROGRAM diagonal
REAL a(5, 5), d(5,5) INTEGER i, j, ordem
ordem = leitura()
WRITE(*,*) "Entre com os elementos da matriz seguido de <enter> a *pos cada valor"
DO 1 i = 1, ordem DO 2 j = 1, ordem READ(*,*) a(i, j) d(i,j) = 0.0 2 CONTINUE 1 CONTINUE WRITE(*,*)
DO 3 i = 1, ordem WRITE(*,*)(a(i, j), j = 1, ordem) 3 CONTINUE
DO 4 i = 1, ordem d(i, i) = a(i, i) 4 CONTINUE WRITE(*,*)
DO 5 i = 1, ordem WRITE(*,*) (d(i, j), j = 1, ordem) 5 CONTINUE
STOP END
INTEGER FUNCTION leitura() LOGICAL ok INTEGER n
ok = .TRUE.
DO WHILE (ok)
WRITE(*, *) "Entre com um numero no intervalo [2, 5]"
READ(*,*) n
IF (n.LE.5) THEN IF (n.GT.1) THEN ok = .FALSE. ENDIF ENDIF ENDDO
leitura = n
RETURN END
Exercício
● Repare que aproveitamos o código do filtro de leitura onde aplicamos algumas pequenas mudanças para adaptadas ao que estamos fazendo agora
● Outra coisa que fizemos foi zerar os elementos da matriz D enquanto liamos a matriz A. Não é elegante mas é um recurso
● Observe ainda o uso do WRITE(*,*) para fazer um salto de linha entre os dados impressos. Também não é elegante mas é outro recurso...
● Há ainda repetições de código como no momento de imprimir as matrizes
Exercício
Vamos fazer uma nova versão usando SUBROUTINE de forma a tornar o código mais compreensível e menos repetitivo
Exercício PROGRAM diagonal REAL a(5, 5), d(5,5) INTEGER i, j, ordem
ordem = leitura() WRITE(*,*) "Entre com os elementos da matriz seguido de <enter> a *pos cada valor"
DO 1 i = 1, ordem DO 2 j = 1, ordem READ(*,*) a(i, j) 2 CONTINUE 1 CONTINUE
CALL zeramat(d,ordem) CALL impmat(a) DO 4 i = 1, ordem d(i, i) = a(i, i) 4 CONTINUE
CALL impmat(d) STOP END
SUBROUTINE zeramat(mat, n) REAL mat(5,5) INTEGER n, i, j
DO 1 i = 1, n DO 2 j = 1, n mat(i,j) = 0.0 2 CONTINUE 1 CONTINUE RETURN END
INTEGER FUNCTION leitura() LOGICAL ok INTEGER n
ok = .TRUE.
DO WHILE (ok) WRITE(*, *) "Entre com um numero no intervalo [2, 5]" READ(*,*) n
IF (n.LE.5) THEN IF (n.GT.1) THEN ok = .FALSE. ENDIF ENDIF ENDDO
leitura = n RETURN END
SUBROUTINE impmat(mat, n) REAL mat(5,5) INTEGER n, i, j
WRITE(*,*) DO 1 i = 1, n WRITE(*,*) (mat(i, j), j = 1, n) 1 CONTINUE RETURN END
Exercício
Repare que o código ficou mais legível com o uso das SUBROUTINE
Exercício
Dada uma matriz A nxn, imprima a matriz triangular estritamente superior de A.
Exercício
Exemplifiquemos com uma matriz 4x4
D é a diagonal de A, L é a matriz triangular estritamente inferior de A e U a matriz triangular estritamente superior de A
(3 −4 8 51 4 6 9
−4 1 −4 37 2 8 1
)⇒D=(3 0 0 00 4 0 00 0 −4 00 0 0 1
) ; L=(0 0 0 01 0 0 0
−4 1 0 07 2 8 0
) ;U=(0 −4 8 50 0 6 90 0 0 30 0 0 0
)
Reescrevendo um programa
Observe que a primeira linha (índice da linha igual a 1) da matriz estritamente superior de A o índice da coluna irá de 2 até n, na segunda linha o índice da coluna irá de 3 até n, até que na n-ésima menos um linha terá somente a componente n.
● A última linha só tem componentes nulos
● Isto sugere o fragmento de código que se segue para termos o solicitado pelo problema
Reescrevendo um programa
…
DO 1 i = 1, n-1
DO 2 j = i+1, n
u(i, j) = a(i,j)
2 CONTINUE
1 CONTINUE
...
Exercício PROGRAM diagonal REAL a(5, 5), u(5,5) INTEGER i, j, ordem
ordem = leitura() WRITE(*,*) "Entre com os elementos da matriz seguido de <enter> a *pos cada valor"
DO 1 i = 1, ordem DO 2 j = 1, ordem READ(*,*) a(i, j) 2 CONTINUE 1 CONTINUE
CALL zeramat(d,ordem) CALL impmat(a) DO 4 i = 1, ordem-1 DO 5 j = i+1, ordem u(i, i) = a(i, i) 5 CONTINUE 4 CONTINUE
CALL impmat(u) STOP END
SUBROUTINE zeramat(mat, n) REAL mat(5,5) INTEGER n, i, j
DO 1 i = 1, n DO 2 j = 1, n mat(i,j) = 0.0 2 CONTINUE 1 CONTINUE RETURN END
INTEGER FUNCTION leitura() LOGICAL ok INTEGER n
ok = .TRUE.
DO WHILE (ok) WRITE(*, *) "Entre com um numero no intervalo [2, 5]" READ(*,*) n
IF (n.LE.5) THEN IF (n.GT.1) THEN ok = .FALSE. ENDIF ENDIF ENDDO
leitura = n RETURN END
SUBROUTINE impmat(mat, n) REAL mat(5,5) INTEGER n, i, j
WRITE(*,*) DO 1 i = 1, n WRITE(*,*) (mat(i, j), j = 1, n) 1 CONTINUE RETURN END
Exercício
Faça uma SUBROUTINE que extraia de uma matriz quadrada: a diagonal, a matriz triangular inferior e a matriz triangular superior de A
Introduzindo valores
Vamos ver uma outra maneira de entrar com informações num programa FORTRAN
PARAMETER
Algumas informações não devem ser alteradas durante a execução de um programa. Para evitar que um erro de programação possa fazer isto, temos o PARAMETER que deve ser colocado no início do código, após à declaração de variáveis e poderá ter qualquer tipo de variáveis do FORTRAN
PARAMETER
Exemplo:
REAL a(10,10), x, y
PARAMETER (pi = 3.1415926, ok = .TRUE., n = 5)
…
● Observação:
Estes valores são simbólicos, ou seja, não são variáveis
Introduzindo valores
Outra maneira de introduzir informações diretamente num programa é por meio do DATA que tem por finalidade inicializar variáveis, sejam lá de que tipo forem.
PARAMETER
Exemplo:
CHARACTER p*20
INTEGER a(2,2), b(2,3)
REAL x, y
DATA a(1,1)/1/,a(1,2)/2/, a(2,1)/-1/, a(2,2)/3/, x,y/1.23, 4.32/
DATA b/6*0/, p/“uma frase“/
...
Introduzindo valores
Nem todos estes exemplos são bons ou elegantes mas todos são válidos
Introduzindo valores
Quando DATA for usado com uma cadeia de caracteres, se o número de caracteres da inicialização for menor que o espaço da cadeia, então o restante será preenchido com espaços em branco
Introduzindo valores
Como exemplo de utilização temos a seguir um programa que gera uma tabuada de multiplicação de um determinado número dado.
Este programa também alguns aspectos simples do uso do FORMAT. Sugiro que vocês experimentem formatos diferentes e também compare com a saída dada pelo comando WRITE(*,*), ou seja, saída com formatação padrão
Introduzindo valores
PROGRAM tabuada CHARACTER mult, igual INTEGER n, i, j
DATA mult, igual/'x', '='/
WRITE(*,*) "Gerador de Tabuadas" WRITE(*,*) "Entre com um valor numérico entre 1 e 10"
n = leitura(1, 10)
DO 1 i = 1, 10 WRITE(*,1000) n, mult, i, igual, n * i 1 CONTINUE
1000 FORMAT(I2,A2,I3,A2, I3)
STOP END
INTEGER FUNCTION leitura(min, max) LOGICAL ok INTEGER min, max, n
ok = .TRUE.
DO WHILE (ok)
WRITE(*, *) "Entre com um numero no intervalo [min, max]"
READ(*,*) n
IF (n.LE.max) THEN IF (n.GT.min) THEN ok = .FALSE. ENDIF ENDIF ENDDO
leitura = n
RETURN END
Introduzindo valores
Observe ainda que fazemos uso de uma versão mais elaborada da FUNCTION leitura, agora com dois parâmetros que dão o valor mínimo e máximo admitido com válidos.