Nos subconjuntos anteriores F90/1 e F90/2 aprendemos a escrever programas Fortran utilizando comandos que faziam o computador:
a) Ler valores e atribuir estes valores às variáveis:
READ, RAIO, ALTURA
b) Avaliar expressões aritméticas e atribuir valores às variáveis:
VOLUME = 3.1416 * RAIO ** 2 ALTURA
c) Imprimir resultados com identificação:
PRINT *, “'VOLUME DO CILINDRO = ”, VOLUME
Nestes programas, os comandos eram executados em seqüência até o comando STOP ser atingido. Neste ponto, a execução do programa se encerra.
Aqui, no F90/3, aprenderemos duas maneiras pela qual a seqüência do programa pode ser alterada. Uma delas, envolve o uso repetido de um conjunto de comandos, a outra, envolve caminhos alternativos no fluxo do programa. A primeira maneira é chamada de “comando de repetição”, a segunda, é chamada de “desvio”.
Tomemos o programa que calcula a média de notas numa disciplina de um aluno qualquer,
PROGRAM
MEDIA3
IMPLICIT NONE
REAL :: NOTA1, NOTA2, NOTA3, MEDIA
WRITE (*, *) “Este programa
calcula a média aritmética de &
&3 notas de um aluno”
WRITE (*, *) “Informe as 3 notas do aluno,
separadas &
&por
brancos: ”
READ (*, *) NOTA1, NOTA2, NOTA3
MEDIA = (NOTA1 + NOTA2 + NOTA3) / 3.
WRITE (*, *) “NOTAS DO ALUNO
NA DISCIPLINA: ”, NOTA1, “, ”, &
&“NOTA2, “ e ”, NOTA3
WRITE (*, *) “MÉDIA NA DISCIPLINA = ”,
MEDIA
STOP
END PROGRAM MEDIA3
Se tivéssemos apenas um aluno para calcular a média na disciplina, este seria o programa.
Admitamos agora que quiséssemos calcular a media na disciplina de 10 alunos. Teríamos então um programa idêntico ao anterior, com a diferença que o conjunto de comandos:
WRITE (*, *) “Informe as 3 notas do aluno,
separadas &
&por
brancos: ”
READ (*, *) NOTA1, NOTA2, NOTA3
MEDIA = (NOTA1 + NOTA2 + NOTA3) / 3.
WRITE (*, *) “NOTAS DO ALUNO
NA DISCIPLINA: ”, NOTA1, “, ”, &
&“NOTA2, “ e ”, NOTA3
WRITE (*, *) “MÉDIA NA DISCIPLINA = ”,
MEDIA
apareceria 10 vezes no programa, uma vez para cada aluno.
de an zero com que um conjunto ~ t1e , tantas vezes quantaE comandoDO e ()ecomando ~
Entretanto, existem em Fortran, dois comandos que fazem com que um conjunto de comandos seja repetido automaticamente, tantas vezes quantas necessárias. Estes comandos são: o comando DO e o comando WHILE.
Formato:
DO <contador> = <valor inicial>, <valor final>, <incremento>
<comandos a serem repetidos> ou <corpo do DO>
END DO
Os valores: <valor inicial>, <valor final> e <incremento> são variáveis ou constantes inteiras. O <incremento> é opcional e sua ausência define o valor 1 para se adicionado à variável <contador>.
A variável de controle <contador> é uma variável inteira que é responsável pela quantidade de vezes que o conjunto de comandos pertencentes ao <corpo do DO> deve ser repetido. <valor inicial> é o primeiro valor após o sinal de igual e define o valor com que a variável de controle <contador> é inicializada. O <valor final> é o segundo valor, e define o valor limite que a variável de controle pode assumir permitindo ainda a execução dos comandos do <corpo do DO>. O <incremento> é o terceiro número e define o valor que será adicionado à variável de controle <contador> após cada repetição ser executada.
Passo 1: É atribuído o <valor inicial> ao <contador>;
Passo 2: É executado o teste para verificar se o valor de <contador> ultrapassou o <valor final>; se o <contador> não <ultrapassou o valor final> então a execução continua no passo 3, caso contrário, o comando DO é terminado e a execução do programa continua no comando seguinte ao END DO;
Passo 3: Executa os comandos que formam o <corpo do DO>;
Passo 4: Ao atingir a declaração END DO, adiciona à variável <contador> o valor de <incremento> e retorna ao passo 2;
Portanto, para o exemplo citado anteriormente, usaremos o comando DO ao invés de repetir o conjunto de comandos 10 vezes:
PROGRAM MEDIA3
IMPLICIT NONE
REAL :: NOTA1, NOTA2, NOTA3, MEDIA
WRITE (*, *) “Este programa
calcula a média aritmética de &
&3 notas de um aluno”
DO VEZES = 1, 10, 1
WRITE (*, *) “Informe as 3 notas do
aluno, separadas &
&por brancos: ”
READ (*, *) NOTA1, NOTA2, NOTA3
MEDIA = (NOTA1 + NOTA2 + NOTA3) / 3.
WRITE (*, *) “NOTAS DO ALUNO NA
DISCIPLINA: ”, NOTA1, “, ”, &
&“NOTA2, “ e ”, NOTA3
WRITE (*, *) “MÉDIA NA DISCIPLINA = ”,
MEDIA
END DO
STOP
END PROGRAM MEDIA3
1) O comando DO é sempre usado quando sabemos exatamente o número de vezes que um conjunto de comandos deve ser repetido. Podemos utilizar quaisquer valores inteiros (variáveis ou constantes) para definir <valor inicial>, <valor final> e <incremento>. necessitamos inicializar <contador> com o número Ioumcremehtá- Io d~ I em I. Podemos te~ por exemplo: 100 1617 IDO 1~0' I = READ, MEDIP PRINT, IPRINT, CONTINUE 12, 3~, 2 NOTA1, NOTA2, NOTA3 = (NOTAl + l'TOTA2 + NOTA3) 13. 'NOTAS DO P,LUNO', }TOTAl, NOTA2, 'MEDIA DO CURSO', MEDIA NOTA3 o importante é que nós sabemos com certeza que este co~ junto de comandos, dentro do CICLO DO, será repetido 10 vezes.
2) Quando omitimos o incremento de um comando DO, por defau1t, o incremento é igual a 1. Exemplo:
DO I = 1, 30 ! é assumido 1 para o incremento
3) Seja o comando DO I = V1, V2, V3 pode ocorrer que para ; ,. - uma certa combinação destes':valdres Vl' V2' V3 o contador I.não " . at1nJC:: o valor exato de V2 ~ r-Teste caso o loop term1na quando ,1 q.tingirum valor > V2. Ex: DO 20 I = 1,6 ,2
4) Os valores de I, V1, V2 e V3 não podem ser alterados dentro do corpo do DO.
5) Após o processamento completo de um DO, o valor do índice da variável de controle estará com o valor que ultrapassou o valor final e pode ser usado no programa.
6) Ninhos de DO´s (DO dentro DO) - Os DO's externos têm de envolver completamente os DO's mais internos Exemplo:
DO I = 1, 10, 1
DO J = -10, 10, -1
WRITE(*, *) I, J
END DO
END DO
7) Em ninhos de DO´s, o contador do DO mais interno varia seu valores totalmente para cada repetição do DO mais externo.
DO I = 1, 5
DO J = 1, 10
K
= I + J
END
DO
WRITE(*, *) K
END DO
Enquanto I do DO externo está com valor 1, no DO interno J varia de 1 a 10; quando J ultrapassa o valor 10, o valor de K é impresso. A seguir I assume o valor 2 enquanto J mais uma vez varia de 1 a 10; e assim por diante. J varia pela última vez de l a 10, quando o valor de I é 5. O laço externo terminará quando I ultrapassar o valor 5 -
Antes de aprendermos o outro comando de repetição, o WHILE, veremos o conceito de Expressões Lógicas.
Expressões Lógicas são constantes, variáveis ou expressões aritméticas dos tipos inteiro ou real, ligadas entre si através de operadores lógicos e que assumem apenas dois valores: VERDADEIRO ou FALSO.
Operador |
Relação |
.EQ. ou == |
Igual a ou |
.NE. ou /= |
Diferente de |
.LT. ou < |
Menor que |
.LE. ou <= |
Menor ou igual a |
.GT. ou > |
Maior que |
.GE. ou >= |
Maior ou igual a |
.AND. |
E |
.OR. |
Ou |
Vejamos então exemplos de expressões lógicas.
EXPRESSÃO LÓGICA VALOR LÓGICO
5.0 == 2 + 3 VERDADEIRO
7 .GT. 2 VERDADEIRO
2 .LT. 6 * 5 VERDADEIRO
5 + 3 <= 2 + 1 FALSO
6 .NE. 6.0 FALSO
5 .GT. 5 FALSO
PI * 2 /= 2 * PI FALSO
Podemos ter ainda expressões lógicas compostas, que são expressões lógicas simples ligadas entre si através dos operadores .AND. e .OR..
EXPRESSÃO LÓGICA COMPOSTA VALOR LÓGICO
(8 > 7) .AND. (2 == l + l) VERDADEIRO
(6 > 3) .OR. (5 <= 3) VERDADEIRO
(3 /= l + 2) .AND. (3 + 3 > 25.) FALSO
(3 + 5 >= 10) .OR. (55 == 5.5) FALSO
Format:
DO WHILE (<condição>)
<comandos a serem repetidos> ou <corpo do WHILE>
END DO
A <condição> (expressão lógica) é testada antes do início do laço. Se a condição é VERDADEIRA, o conjunto de comandos do <corpo do WHILE> é executado e em seguida a condição é novamente testada. Quando a <condição> finalmente torna-se FALSA, controle é passado para o próximo comando após o END DO.
Passo 1: Testa a condição; se verdadeira segue para o passo 2; caso contrário termina o laço e o controle passa para o comando que segue o END DO
Passo 2: Executa o <corpo do WHILE> e retorna ao passo 1.
Exemplo 1: Então para o exemplo dos 10 alunos poderíamos ter:
PROGRAM MEDIA3
IMPLICIT
NONE
REAL :: NOTA1, NOTA2, NOTA3, MEDIA
INTEGER :: CONT
WRITE (*, *) “Este programa
calcula a média aritmética de &
&3 notas de um aluno”
CONT
= 1
DO
WHILE (CONT <= 10)
WRITE (*, *) “Informe as 3
notas do aluno, separadas &
&por
brancos: ”
READ (*, *) NOTA1, NOTA2, NOTA3
MEDIA = (NOTA1 + NOTA2 + NOTA3) / 3.
WRITE (*, *) “NOTAS DO ALUNO
NA DISCIPLINA: ”, NOTA1, “, ”, &
&“NOTA2, “ e ”, NOTA3
WRITE (*, *) “MÉDIA NA DISCIPLINA = ”,
MEDIA
CONT = CONT + 1
END DO
STOP
END PROGRAM MEDIA3
Este exemplo, é mais indicado para o comando DO porque sabemos que o conjunto de comandos deve ser repetido exatamente 10 vezes. Nós usamos o comando DO WHILE quando não sabemos exatamente o número de vezes que o conjunto de comandos deve ser executado, mas sabemos; que deve ser executado enquanto a <condição for VERDADEIRA.
Exemplo 2: Suponha que desconhecemos o número de alunos da turma mas sabemos que todas as notas ³ 0. Então colocamos um FLAG (marca) no final dos dados com uma nota negativa, esta nota indicará ao programa o fim dos dados (fim de arquivo) e codificaremos nosso programa da seguinte maneira:
PROGRAM MEDIA3_1
IMPLICIT NONE
REAL :: NOTA1, NOTA2, NOTA3, MEDIA
WRITE (*, *) “Este programa calcula a média
aritmética de &
&3 notas de um aluno”
WRITE (*, *) “Informe as 3 notas do aluno,
separadas &
&por
brancos: ”
READ (*, *) NOTA1, NOTA2, NOTA3
DO
WHILE (NOTA1 >= 10)
MEDIA = (NOTA1 + NOTA2 + NOTA3) / 3.
WRITE (*, *) “NOTAS DO ALUNO
NA DISCIPLINA: ”, NOTA1, “, ”, &
&“NOTA2, “ e ”, NOTA3
WRITE (*, *) “MÉDIA NA DISCIPLINA = ”,
MEDIA
WRITE (*, *) “Informe as 3 notas do aluno,
separadas &
&por
brancos: ”
READ (*, *) NOTA1, NOTA2, NOTA3
END
DO
STOP
END PROGRAM MEDIA3
Exemplo 3:
! PROGRAMA PARA CALCULAR O FATORIAL DE
NÚMEROS LIDOS ATÉ
! QUE SEJA LIDO UM VALOR NEGATIVO (FLAG)
PROGRAM FATORIAL_NUM
IMPLICIT NONE
INTEGER NUMERO, K, FAT
WHITE(*, *) “CÁLCULO DO FATORIAL DE UM
NÚMERO”
WHITE(*, *) “INFORME O NÚMERO PARA O
CÁLCULO DO FATORIAL: ”
READ (*, *) NUMERO
DO WHILE (NUMERO >= 0)
FATOR = 1
FATORIAL
= 1
DO
WHILE (FATOR <= NUMERO)
FATORIAL = FATORIAL * FATOR
FATOR = FATOR + 1
END DO
WHITE(*, *) “O FATORIAL DE “, NUMERO, “
É ”, FATORIAL
WHITE(*, *) “INFORME O NÚMERO PARA O
CÁLCULO DO FATORIAL: ”
READ
(*, *) NUMERO
END
DO
STOP
END PROGRAMA FATORIAL_NUM
Quando usamos o comando WHILE precisamos ter cuidado para o laço não torna-se infinito. Para evitar isto é necessário:
1) Alterar o valor da variável envolvida na condição dentro do corpo do laço.
2) Certificar-se que a condição de fim de laço será atingida.
Vamos aprender agora a outra estrutura que modifica a seqüência normal da execução de um programa. Esta é a estrutura de desvio.
Comando IF
Formato:
IF (<condição>) THEN
<comando(s) a executar, caso a condição seja VERDADEIRA>
END IF
ou
IF (<condição>) THEN
<comando(s) a executar, caso a condição seja VERDADEIRA>
ELSE
<comando(s) a executar, caso a condição seja FALSA>
END IF
Para o primeiro formato, se a <condição> for VERDADEIRA, o conjunto de comandos entre a cláusula THEN e o END IF são executados e o de controle passa para o comando após o END IF; caso contrário, o controle passa diretamente para o comando após o END IF.
Para o segundo formato, se a <condição> é VERDADEIRA , o conjunto de comandos entre a cláusula THEN e o ELSE são executados; caso contrário, o conjunto de comandos entre a cláusula ELSE e o END IF são executados. Em qualquer caso o controle passa para o comando que segue a declaração END IF. Qualquer comando (inclusive o IF) pode fazer parte dos comandos internos ao IF.
Vejamos um exemplo em Fortran: programa para verificar quantos alunos foram aprovados e quantos foram reprovados numa disciplina, sabendo-se que classe possui 50 alunos.
PROGRAM
AVALIA
IMPLICIT NONE
INTEGER :: APROV, REPROV, I
REAL :: TOTAL, NOTA2, NOTA3, MEDIA
READ (*, *) NOTAl, NOTA2, NOTA3
APROV = 0
REPROV = 0
DO I = 1, 50
READ (*, *) NOTA1, NOTA2, NOTA3
MEDIA = (NOTA1 + NOTA2 + NOTA3 ) /3
IF (MEDIA .GE. 5.0) THEN
APROV = APROV + 1
ELSE
REPRV = REPROV + 1
END IF
PRINT *, NOTA1, NOTA2, NOTA3, MEDIA
END DO
PRINT *, “TOTAL DE APROVADOS = ”, APROV
PRINT *, “TOTAL DE REPROVADOS = ”, REPROV
STOP
END
PROGRAM AVALIA
Agora vejamos um exemplo com um IF sem a parte opcional ELSE. Suponha que no exemplo anterior estivéssemos interessados apenas em saber quantos alunos conseguiram média 10.0. Logo, o comando IF seria:
IF (MEDIA == 10.0) THEN
TOTAL
= TOTAL + 1
END IF
Aqui a declaração ELSE não existe mas, fica claro que se MEDIA não for igual a 10.0, não incrementamos a variável TOTAL.
Para ilustrar uma condição composta, suponha que queremos saber quantos alunos obtiveram MEDIA no intervalo de 5.0 à 7.0. Logo o comando IF seria:
IF (MEDIA >= 5.0 .AND, MEDIA <= 7.0) THEN
TOTAL = TOTAL + 1
END IF
Programa que conta votos por partido de uma eleição onde cada voto é lido através do teclado. Se o valor lido for 0, então o voto será branco; se o valor lido for 1, o voto será do partido da situação; e se 2, o voto será do partido de oposição. Qualquer outro número, consideraremos um voto nulo. O primeiro valor a ser lido deve representar a quantidade de votos que deverão ser computados. A saída do programa deve conter a listagem dos votos lidos, com cada voto seguido da mensagem do tipo de voto. No final, deve ser impresso o total de cada tipo de voto.
LISTAGEM
DOS VOTOS:
0 BRANCO
1 SITUAÇÃO
2 OPOSIÇAO
2 OPOSIÇÃO
4 NULO
2 OPOSIÇÃO
RESULTADO
DA ELEIÇÃO:
EM BRANCO = 1
NULO = 1
SITUAÇÃO = 1
OPOSIÇÃO = 3
TOTAL DE VOTOS = 6
PROGRAMA
ELEICAO
IMPLICIT NONE
INTEGER :: I, VOTO, BRANCO, NULO, SIT,
OPOS, NUMVOTO
BRANCO = 0
NULO = 0
SIT = 0
OPOS = 0
WRITE (*, *) “INFORME O NÚMERO DE VOTOS DA
URNA: ”
READ (*, *) NUMVOTO
WRITE(*, *) “LISTAGEM DOS VOTOS:”
DO I = 1, NUMVOTO
READ
(*, *) VOTO
IF
(VOTO == 0) THEN
WRITE(*, *) “ ”, VOTO, “BRANCO”
BRANCO = BRANCO + 1
ELSE
IF (VOTO == 1) THEN
WRITE(*, *) “ ”, VOTO, “SITUAÇÃO”
SIT
= SIT + 1
ELSE
IF (VOTO == 2) THEN
WRITE(*, *) “ ”, VOTO, “OPOSIÇÃO”
OPOS = OPOS + 1
ELSE
WRITE(*, *) “ ”, VOTO, “NULO”
NULO = NULO + 1
END IF
END IF
END IF
END
DO
WRITE(*, *) “RESULTADO DA ELEIÇÃO:”
WRITE(*, *) “ BRANCO = ”, BRANCO
WRITE(*, *) “ NULO = ”, NULO
WRITE(*, *) “ SITUAÇÃO = ”, SIT
WRITE(*, *) “ OPOSIÇÃO = ”, OPOS
WRITE(*, *) “ TOTAL DE VOTOS = ”, NUMVOTO
STOP
END PROGRAMA ELEICAO
Existem, duas maneiras, de rotular a saída de resultados num programa. A primeira delas já vista nos capítulos anteriores. Por exemplo, se nosso programa calcula o volume de uma caixa, então, o rótulo de saída no comando PRINT é:
PRINT *, “VOLUME DA CAIXA = ”, VOLUME
Onde, a constante literal “VOLUME DA CAIXA = “, rotula, ou seja, explica exatamente o significado do conteúdo do valor que está sendo mostrado.
A outra maneira acontece quando um conjunto de variáveis devem ser listadas, em colunas, na saída do programa como no exemplo a seguir.
Programa que imprime uma tabela das funções Y e Z para valores de X = 0.5, 1.0, l.5, ... , 5.0, sendo:
y = ln x è função logarítmica
z = ex è função exponencial
O rótulo da saída deve ser:
FUNÇÃO FUNÇÃO
VALOR DE X LOGARITMICA EXPONENCIAL
0.5000000E00 -0.6931472E00 0.1648721e01
0.1000000E01 . .
0.1500000E01 . .
. . .
.
.
0.5000000E01
Sabemos que uma variável inteira ocupa um campo de 12 posições na impressão enquanto que uma variável real ocupa 14 posições. Se as variáveis X, Y e Z são todas reais, então cada uma delas vai ocupar 14 posições na impressão, portanto o rótulo de cada variável deve ocupar também, 14 posições para que o rótulo fique exatamente sobre a variável que ele vai identificar (explicar), seja, por exemplo:
“ VALOR DE X ”, deve ficar na coluna que X será mostrada;
“ FUNÇÃO ”
“ LOGARÍTMICA ”, deve ficar na coluna que Y será mostrada;
“ FUNÇÃO ”
“ EXPONENCIAL ”, deve ficar na coluna que X será mostrada.
O programa ,será então:
! PROGRAMA QUE CALCULA AS FUNÇÕES LOGARÍTMQ E EXPONENCIAL PARA
! VALORES DE X = 0.5, 1.0, 1.5, ... , 5,0
PROGRAM CALCULA_FUNCOES
IMPLICIT NONE
INTEGER :: I
REAL :: X, FUNLOG, FUNEXP
PRINT *, “ ”, “
FUNÇÃO ”, “ FUNÇÃO
”
PRINT *, " VALOR DE X ”, “ LOGARITMICA ”, “ EXPONENCIAL ”
X = 0
DO I = 1, 10
X = X + 0.5
FUNLOG = ALOG(X)
FUNEXP = EXP(X)
PRINT *, X, FUNLOG, FUNEXP
END DO
STOP
END PROGRAM
CALCULA_FUNCOES
1. Suponha que você dispõe de Cr$ 150.000, guardados para utilizar numa eventual emergência. Assumindo uma inflação de 250% ao ano, escreva um programa Fortran que imprima a cada ano, durante 8 anos, a quantia em real que você deverá ter para manter sempre o equivalente deste dinheiro guardado.
2. Fazer um programa Fortran que imprima uma tabela Da função y para valores de x = 0.1, 0.2,..., 1.0 sendo:
10
y = å x3
n=l N! ou seja,
y = x3 + x3 + ...+ x3
1! 2! n!
onde n! 1 x 2 x 3 x...x n fatorial de n-l.
3. Fazer um programa Fortran que calcula e mostra as raízes de 15 equações do 2o. grau, lendo os coeficientes de cada equação através do teclado.
Fórmula:
D = delta = b2 – 4ac
D < 0 è não pode calcular raiz; mostrar mensagem dizendo delta é negativo e mostrar este valor.
D = 0 è raiz = -b/2a
____ ____
D
> 0 è
raizl = -b + Ödelta
raiz2 = +b + Ödelta
2a 2a
4. Fazer um programa Fortran que mostre o conjunto dos números pares positivos até o 15o. termo e o conjunto dos números ímpares positivos até o 20o. termo.
OBS. Comentar todos os programas.