Académique Documents
Professionnel Documents
Culture Documents
Apostila de Treinamento:
Introduo ao Fortran90
Reviso: 2009
2
NDICE 1-INTRODUO 1.1-Histria 1.2-Fortran 77 1.3-Fortran 90 1.4-Exemplo de Programa 2-ELEMENTOS DO FORTRAN 90 2.1-Caractersticas de Codificao 2.2-Regras de Codificao 2.3-Compilao no Ambiente CENAPAD-SP EXERCCIO 1-Compilao e Execuo EXERCCIO 2-Reestruturao de programa 2.4-Estrutura e Organizao de Programas 2.5-Tipo de Dado 2.6-Constantes 2.7-Tipo de Dado Implcito 2.8-Declarao de Variveis 2.9-Declarao de Constantes 2.10-Inicializao de Variveis EXERCCIO 3-Erro na Declarao de Variveis EXERCCIO 4-Declarao de Variveis 2.11-Expresses 2.11.1-Operador de Atribuio ( = ) 2.11.2-Operadores Numricos 2.11.3-Operadores Relacionais 2.11.4-Operadores Lgicos 2.11.5-Operador Caractere ( // ) 2.11.6-Precedncia de Operadores EXERCCIO 5-Expresses 3-COMANDOS DE CONTROLE DO FLUXO DA EXECUO 3.1-Comando IF 3.2-Comando IF...THEN...END IF 3.3-Comando IF...THEN...ELSE...END IF 3.4-Comando IF...THEN...ELSEIF...END IF 3.5-Comando IF...THEN...ELSEIF...END IF Identificado EXERCCIO 6-Comando IF 3.6-Comando de LOOP Condicional DO-EXIT-END DO 3.7-Comando de LOOP Cclico Condicional DO-CYCLE-EXIT-END DO 3.8-LOOPs Identificados 3.9-Comando DO-WHILE 3.10-Comando DO iterativo 3.11-Comando SELECT CASE-CASE-END SELECT 3.12-Operaes entre Tipos de Dados 3.13-Diviso por Inteiros 3.14-Procedimentos Internos do Fortran90 3.15-Comando PRINT 3.16-Comando READ EXERCCIO 7-DO EXERCCIO 8-SELECT CASE EXERCCIO 9-Funes Matemticas 4-CONJUNTO DE DADOS 05 05 06 07 08 09 09 10 11 12 13 14 15 16 16 17 19 20 21 21 22 22 23 23 24 24 25 26 27 28 29 30 31 33 34 35 35 36 36 37 38 39 39 40 41 41 42 42 43 44
3
4.1-Declarao de Conjunto de Dados 4.2-Visualizao de um Conjunto de Dados 4.3-Organizao do Conjunto de Dados 4.4-Sintaxe de um Conjunto de Dados 4.5-Leitura e Impresso dos Elementos de um Conjunto de Dados 4.6-Funes de Tratamento de Conjunto de Dados 4.7-Alocao Dinmica de Conjunto de Dados EXERCCIO 10-Definio de Conjunto de Dados EXERCCIO 11-Funes de Caractersticas de um Conjunto de Dados EXERCCIO 12-Funes de Operaes de um Conjunto de Dados EXERCCIO 13-Uso de um Conjunto de Dados 5-SEES PRINCIPAIS DE PROGRAMAS 5.1-Sees de um Programa 5.2-Seo Principal: PROGRAM 5.3-Sees Internas: Procedimentos 5.3.1-Procedimentos: SUBROUTINE 5.3.2-Procedimentos: FUNCTION 5.3.3-Detalhes de Procedimentos 5.4-Seo Especial: MODULE EXERCCIO 14-Subrotina EXERCCIO 15-Funo EXERCCIO 16-Procedimentos EXERCCIO 17-Definio de um Mdulo EXERCCIO 18-Uso de um Mdulo 6-TRATAMENTO DE ARQUIVOS 6.1-ENTRADA / SADA 6.2-Comando OPEN 6.3-Comando READ 6.4-Comando WRITE 6.5-loops Inseridos nos Comandos READ/WRITE 6.6-Descritores de Edio 6.7-Formatao de Dados (FORMAT/FMT=) 6.8-Outros comandos de I/O 6.9-Comando DATA 7-DEFINIO DE TIPO DE DADOS 7.1-Definio: Estrutura TYPE 7.2-Comando de Declarao: TYPE 7.3-Utilizao de um Novo Tipo de Dados 8-COMANDOS DE EXCEO 8.1-Comando GOTO 8.2-Comando RETURN 8.3-Comando STOP 9-RECOMENDAES DE CODIFICAO EXERCCIO 19-I/O EXERCCIO 20-I/O EXERCCIO 21-Formatao EXERCCIO 22-Derivao de Dados 10-REFERNCIAS 45 46 47 48 49 50 52 53 54 54 55 56 56 57 58 59 60 61 64 65 65 65 66 66 67 67 68 70 72 74 75 76 77 79 80 80 80 81 82 82 82 82 83 84 84 84 85 86
IF <(expresso lgica)> THEN <bloco de comandos> ... [ELSE <bloco de comandos> ...] END IF
1. 2. 3.
A expresso lgica do IF obrigatria; O bloco de comandos aps o comando THEN, obrigatrio; O comando ELSE opcional, mas se for utilizado, o bloco de comandos aps o ELSE, passa a ser obrigatrio.
IF
1.2 Fortran77
Algumas necessidades em programao, definiram o Fortran77 como uma linguagem obsoleta em relao s linguagens atuais: Formato fixo: Linhas de instrues, comeavam na posio 7 e iam at a 72; Somente letras maisculas; Nomes de variveis, at 6 caracteres.
Impossibilidade de determinar operaes paralelas; uma situao crtica, pois o Fortran considerado com uma linguagem de alta performance, no entanto, at o padro 77 no existia nenhuma instruo que permitisse ao usurio definir regies do programa que pudessem executar em paralelo, utilizando os recursos de mais de um processador, como por exemplo, o compartilhamento de endereos de memria. No possvel a alocao dinmica de memria; No Fortran77, o programador obrigado a declarar vetores com o maior tamanho possvel para reservar memria durante a compilao, ou seja, no era possvel utilizar conjuntos de dados temporrios durante a execuo. No possui representao numrica portvel; Diversos ambientes computacionais criaram extenses do Frotran77 para melhorar a preciso numrica em suas arquiteturas, o que tornava o cdigo no portvel para outra arquitetura. No Fortran90, as diversas idias de preciso numrica foram padronizadas, melhorando a portabilidade. No era possvel definir uma nova estrutura de dados pelo usurio. No possui recurso explcita; No era possvel chamar uma funo dentro de outra funo. No havia recurso!
1.3 Fortran90
Formato livre: 132 caracteres por linha; Maisculas e minsculas; Nomes at 31 caracteres; Mais de um comando por linha.
Novas instrues que permitem execues de partes do programa em paralelo. PARALLEL DO (Definio de loops paralelos); PARALLEL SECTION; Operaes de ARRAYS em paralelo (SUM, MAX, etc). O ARRAY dividido em diversos vetores, para ser distribudo por entre diversos processos.
Novas instrues que permitem a alocao dinmica de memria (ALLOCATABLE, ALLOCATE); Possibilidade de definio de novas estruturas de dados (Comando de declarao TYPE);
TYPE COORDS_3D REAL :: x, y, z END TYPE COORDS_3D TYPE(COORDS_3D) :: pt1, pt2
Maior flexibilidade e portabilidade na definio da preciso numrica de uma varivel (Parmetro KIND);
INTEGER x FORTRAN IBM ! Preciso de 4 bytes FORTRAN CRAY ! Preciso de 8 bytes x
INTEGER(KIND=4)
Recursividade de funes e rotinas; Estruturas de controle: DO...ENDDO DOWHILE SELECT CASE EXIT CYCLE IFTHENELSEENDIF
Nova orientao - Desligar a definio automtica de variveis como reais ou inteiras. IMPLICIT NONE
Possui duas estruturas principais de programao FORTRAN: MODULE e PROGRAM; MODULE muito utilizado para centralizar funes e rotinas do usurio que sero utilizadas por diversos programas; PROGRAM a estrutura principal de qualquer programa FORTRAN.
Uma estrutura auxiliar: FUNCTION, que pode ser definida dentro da estrutura MODULE ou PROGRAM;
Comando opcional de declarao IMPLICIT NONE utilizado uma nica vez para cada estrutura principal, para desligar a definio automtica das variveis;
Comando de declarao USE Especifica a utilizao de rotinas ou funes definidas por uma estrutura MODULE
Comando de execuo READ L valores de uma determinada entrada e os atribui s variveis especificadas;
&
Caractere de continuao de linha. Colocado no final da linha, indica que o comando continua na prxima linha. Em caso de continuao de strings, esse caractere pode ser utilizado na prxima linha para indicar a posio exata da continuao do string e evitar brancos desnecessrios; PRINT *, Hoje o primeiro dia do curso de & &Introduo ao Fortran90
Caractere de separao de comandos. Vrios comandos podem estar na mesma linha; PROGRAM Teste; REAL a; END PROGRAM
Smbolos aritmticos:
+ * / **
10
Podem continuar com letras, dgitos ou _ CHARACTER CHARACTER CHARACTER Uso de Comentrios PROGRAM Teste ! ! Definio das variveis ! REAL :: aux1 ! Varivel auxiliar :: :: :: atoz Certo a-z Errado a_z Certo
11
extenso: .f , .F , .f90
Opes genricas de compilao: -o -O, -O1, -O2, -O3 -c -g -L<path> -l<biblioteca> Especifica o nome do arquivo executvel (Default: a.out); Nvel de otimizao do cdigo; No gera o arquivo executvel, somente o arquivo objeto; Gera um arquivo executvel com informaes para depurao; Localizao das bibliotecas para serem integradas ao arquivo (linkedio); Especifica uma determinada biblioteca;
Exemplos de compilaes: xlf90 cofigo.f -o teste -O3 Arquivo executvel: teste xlf90 cena.f -c -L/usr/lib/scalapack -lscalapack Arquivo objeto: cena.o ifort salto.f -o salto -O3 -L/home/kusel -lbib1 Arquivo executvel: salto ifort parceiro.f -o par -g -O Arquivo executvel para ser depurado: par
12
PROGRAM QES IMPLICIT NONE INTEGER :: a, b, c, D REAL :: Part_Real, Part_imag PRINT*, ''Entre com os valores de a, b, c'' READ*, a, b, c IF (a /= 0) THEN D = b*b - 4*a*c !Calculo do discriminante IF (D == 0) THEN !Uma raiz PRINT*, ''Raiz '', -b/(2.0*a) ELSE IF (D > 0) THEN !Raizes reais PRINT*, ''Raizes so '',(-b+SQRT(REAL(D)))/(2.0*a),& ''e '', (-b-SQRT(REAL(D)))/(2.0*a) ELSE !Raizes complexas Part_Real = -b/(2.0*a) Part_Imag = (SQRT(REAL(-D))/(2.0*a)) PRINT*, ''1a. Raiz'', Prat_Real, ''+'', Part_Imag, ''i'' PRINT*, ''2a. Raiz'', Part_Real, ''-'', Part_Imag, ''i'' END IF ELSE ! a == 0 PRINT*, ''No uma equao quadrtica'' END IF END PROGRAM QES
2. Compile e execute o programa. Verifique se ele executa corretamente para os valores abaixo: ifort quadsol.f90 ./quadsol (a) (b) (c) (d) a a a a = = = = 1 1 1 0 b b b b = = = = -3 -2 1 2 c c c c = = = = o quadsol O3
2 1 1 3
3. Copie quadSol.f para novoquadsol.f90. cp quadsol.f90 novoquadsol.f90 4. Edite esse novo arquivo e declare uma nova varivel real de nome parte2a. 5. Na seo executvel do cdigo, defina a nova varivel igual ao valor de 1/(2.0*a). parte2a=1/(2.0*a) 6. Aonde aparecer a expresso 1/(2.0*a), substitua pela nova varivel.
13
2.
14
1.
2.
Comandos de Declarao:
IMPLICIT NONE, REAL, INTEGER, CHARACTER, COMPLEX, PARAMETER, DATA recomendado que se defina todas as variveis que sero usadas no programa e, se for necessrio, as suas caractersticas iniciais;
recomendado que use o comando IMPLICIT NONE para desligar a definio automtica das variveis.
3.
15
! Verdadeiro ou Falso ?
2.6 Constantes
Constante um objeto com valor fixo +12345 1.0 -6.6E-06 .FALSE. Curso Fortran Observaes: Nmeros Reais possuem ponto decimal e/ou o smbolo expoente e/ou sinais + ou -; Nmeros Inteiros no possuem ponto decimal e so representados por uma seqncia de dgitos com o sinal + ou -; S existem dois valores Lgicos: .FALSE. e .TRUE. ; Valores caracteres so delimitados por ou Valor Valor Valor Valor Valor numrico Inteiro numrico Real numrico Real Lgico Caractere
16
I, J, K, L, M ou N, ser definida como Inteiro (INTEGER); Qualquer outra letra ser definida como Real (REAL);
Tipo de dado implcito potencialmente perigoso e deve ser evitado, podendo ser modificado ou desligado (Fortran90), obrigando ao usurio definir todas as variveis que sero utilizadas no programa. Para isso, utiliza-se o comando:
Neste caso, devido ao e devido a definio automtica de variveis, o compilador Fortran77 entendeu como a definio da varivel real DO30I como o valor 1.1, ao invs de executar o contedo do loop 1000 vezes.
O Comando IMPLICIT deve ser utilizado logo aps a definio da estrutura do programa. PROGRAM teste IMPLICIT NONE ...
17
::
<variveis> =valor
No obrigatrio, a menos que se especifique um atributo ou um valor inicial para a varivel; Nome das variveis, separadas por , Valor inicial da varivel
Opes LEN= utilizada para definir o tamanho de variveis do tipo caractere (Default=1 byte ou 1caractere); utilizada para definir a preciso numrica de variveis do tipo inteiro ou real (Default=4 bytes ou preciso simples); OBS: A notao utilizando o * ,padro do Fortran77, para indicar o tamanho das variveis, ainda aceito pelo Fortran90.
KIND=
Atributos PARAMETER DIMENSION Determina que um valor seja fixado para a varivel; Determina a que a varivel ir compor um conjunto de dados, em vrias dimenses, com vrios elementos em cada dimenso; Determina que o nmero de elementos de uma dimenso da varivel ser alocado durante a execuo do programa; Determina que o tipo e valor de uma varivel seja global, esttico, visvel por todo o programa; Utilizado na declarao de variveis em funes e subrotinas, serve para identificar se a varivel de entrada ou sada.
ALLOCATABLE
SAVE
INTENT
18
-
Exemplos:
Sintaxes alternativas:
REAL :: x
ou
REAL x ou
ou
REAL*4 x
ou
REAL(4) x
ou
REAL(KIND=4) :: x
REAL(KIND=8) y
REAL(8) y
REAL, DIMENSION(10,10) :: y, z
Outros exemplos:
INTEGER :: k=4 LOGICAL ptr CHARACTER sexo CHARACTER(LEN=32) :: str CHARACTER(LEN=10), DIMENSION(10,10) :: CHARACTER(LEN=8) :: cidade = "Campinas" INTEGER :: pi = +22/7 LOGICAL :: wibble = .TRUE. REAL :: a = 1., b = 2 CHARACTER*6 :: you_know = "y'know" INTEGER :: a, b, c, d LOGICAL, DIMENSION(2) :: bool vetor
Observaes: O tipo DOUBLE PRECISION pode ser substitudo por REAL(8) S existem dois valores para o tipo LOGICAL, que devem vir entre pontos: .true. ou .false. As sintaxes alternativas de declarao de variveis so devido a necessidade de manter a compatibilidade com as verses mais antigas do Fortran.
19
Na declarao de constantes caracteres, pode-se utilizar a opo LEN=* em conjunto com o atributo PARAMETER, indicando que o valor constante atribudo a varivel, determinar o tamanho dessa varivel caractere; CHARACTER(LEN=*), PARAMETER :: n1=Paulo, n2=Francisco n1 n2 Varivel caractere de 5 caracteres Varivel caractere de 9 caracteres
Recomenda-se utilizar o atributo PARAMETER; O atributo PARAMETER determina que o valor da varivel no poder mudar durante a execuo do programa.
20
possvel declarar uma varivel como sendo o resultado de uma expresso aritmtica entre outras variveis que j foram declaradas e iniciadas, mas com o atributo PARAMETER. No geral, as funes internas do Fortran, no podem ser utilizadas em expresses que iniciam uma varivel, mas isso depende da implementao do Fortran. No ambiente CENAPAD-SP, o compilador Fortran90 da IBM (xlf90), no permite o uso de funes, j o compilador Fortran90 da Intel (ifort), permite o uso de funes. REAL, PARAMETER :: pi=3.14159 REAL, PARAMETER :: radius=3.5 REAL :: circo=2*pi*radius REAL :: pi_2=4.*atan(1.0) ! expresso ! Uso da funo arcotangente. ! Depende do compilador
21
1.
Caminhe para o diretrio ~/curso/fortran/ex3, tente compilar o programa declara.f90 . Verifique e corrija os erros na declarao das variveis. Analise com ateno as mensagens de erro. cd ~/curso/fortran/ex3
2.
Edite, corrija os erros e tente compil-lo novamente. Verifique e tente entender os resultados. nano declara.f90 Editores: vi, pico ou emacs
1.
Caminhe para o diretrio ~/curso/fortran/ex4, crie um programa em fortran90 (variavel.f90) que apenas declare as seguintes variveis da tabela abaixo: cd ~/curso/fortran/ex4 nano variavel.f90
2.
Compile e execute o programa. Verifique se h erros de compilao. ifort variavel.f90 ./var o var
22
2.11 Expresses
Expresses so construdas com pelo menos um operador ( + , - , * , / , // , ** ,etc. ) e, com pelo menos um operando. X+1 campo//campo A .GT. B Expresso numrica (Adio) Expresso caractere (Concatenao) Expresso lgica
Normalmente uma expresso utilizada em conjunto com um operador de atribuio =, que ir definir ou atribuir um valor a um novo objeto. a = b c = SIN(0.7)*12.7 nome = iniciais//sobrenome logi = (a.EQ.b.OR.c.NE.d)
OBS: Os operandos a esquerda e a direita do sinal de igualdade no necessitam ser do mesmo tipo.
OBS: Os operandos podem ser: constantes, variveis escalares ou vetoriais, com exceo do expoente que necessariamente deve ser escalar.
So utilizados em expresses lgicas, entre dois operandos, retornando um valor lgico (.TRUE. ou .FALSE.) . Os operadores relacionais, como mnemnicos, so sempre utilizados entre dois pontos, maisculo ou minsculo.
So utilizados em expresses lgicas, com um ou dois operandos, retornando um valor lgico (.TRUE. ou .FALSE.) : .AND. " .OR. " .NOT. " .EQV. " .NEQV." " .TRUE. .TRUE. .TRUE. .TRUE. .TRUE. Se Se Se Se Se ambos os operandos forem .TRUE. pelo menos um operando for .TRUE. o operando for .FALSE. os operandos possurem o mesmo valor os operandos possurem valores diferentes
Se T=.TRUE. e F=.FALSE. ento T .AND. F " .FALSE. T .OR. F " .TRUE. T .EQV. F " .FALSE. F .AND. F " .FALSE. F .OR. F " .FALSE. T .NEQV.F " .TRUE.
2.11.5 Operador CARACTERE ( // ) Uma varivel caractere, pode ser representada como um vetor de caracteres, podendo ser manipulada conforme a sintaxe de vetores. vetor(posio inicial : posio final) CHARACTER(LEN=*), PARAMETER :: string= abcdefgh string(1:1) string(2:4) string(6:7) string(1: ) string( :1) " " " " " a bcd fg abcdefgh a
Utilizado para efetuar a concatenao //, somente de variveis caracteres. CHARACTER(LEN=*), PARAMETER :: string=abcdefgh
a=string//string(3:5) " abcdefghcde b=string(1:1)//string(2:4) " abcd estado=So Paulo cidade=Campinas endereco=estado//-//cidade//-//Brasil " So Paulo-Campinas-Brasil
( )
**
*,/
+,-
//
Toda expresso que vier entre parntesis, ser avaliada primeiro; Em expresses aritmticas, com o mesmo nvel de avaliao, o que vier da esquerda para direita, ser avaliado primeiro, com exceo do expoente.
OBS: Dois operadores no podem ficar adjacentes. 1*-1 1*(-1) Errado Correto
26
EXERCCIO 5 Expresses
1. Caminhe para o diretrio ~/curso/fortran/ex5. Edite o programa area_circulo.f90 cd ~/curso/fortran/ex5 nano area_circulo.f90
2. O programa est incompleto. Acrescente na linha das reticncias o que solicitado. ...Declarao de variveis... ...Expresso para clculo da rea e volume... 3. Frmulas para serem codificadas: rea do Crculo: Volume da esfera: area = r volume = 4r 3
27
O comando IF analisa uma expresso que, se o resultado for verdadeiro, executa os comandos que vierem aps o THEN, se for falso , executa os comandos que vierem aps o ELSE. O lao da condio finaliza com o comando ENDIF;
DO...ENDDO, DO WHILE...ENDDO
O comando DO permite a execuo repetitiva de um bloco de comandos (loops). O nmero de iteraes pode ser uma constante, varivel ou uma expresso, desde que resultem para um valor constante. O Fortran aceita loops encadeados (um loop dentro de outro loop);
O comando SELECT permite a execuo de comandos baseado no valor que uma expresso pode assumir. uma construo equivalente ao IF...THEN...ELSE...ENDIF;
Direciona a execuo do programa para uma linha de comando identificada por um nmero. Bastante poderoso, mas deve ser evitado ou utilizado com cuidado em situaes que necessitam uma ao de emergncia;
So opes de comandos de I/O que funcionam como o comando GOTO, em determinadas situaes de emergncia (erro geral de I/O, erro de fim de arquivo encontrado e erro de fim de registro encontrado), direciona a soluo do problema para um determinada posio do programa;
28
3.1 Comando IF
a forma mais bsica de execuo condicional; determina a execuo de um nico comando, se uma expresso lgica for verdadeira, caso contrrio a execuo passa para a prxima linha.
.true.
IF ( X /= 0 ) Y = 1/X
.false.
Prxima linha
Importante: Somente um comando pode ser executado se a condio for verdadeira; O comando deve vir na mesma linha do comando IF.
29
X = 0
END IF
Importante: O bloco de comandos deve iniciar na linha seguinte ao do comando IF...THEN; O comando IF...THEN, finaliza com o comando END IF ou ENDIF.
30
IF <(expresso lgica)> THEN <bloco de comandos> ... [ELSE <bloco de comandos> ...] END IF
Exemplo: IF ( X == 0 ) THEN PRINT *, X=0 X=X+1 Y=10**X ELSE PRINT *, X diferente de 0 Y=10**X END IF
X /= 0
ELSE
Y = 1/X
Y = 1
END IF
Importante: O bloco de comandos deve iniciar na linha seguinte ao do comando IF...THEN e na linha seguinte do comando ELSE; O bloco de comandos do THEN, finaliza com o comando ELSE. O comando IF...THEN...ELSE, finaliza com o comando END IF ou ENDIF.
31
IF <(expresso lgica)> THEN <bloco de comando> ... [ELSEIF <(expresso lgica)> THEN <bloco de comandos> ...] [ELSE <bloco de comandos> ...] END IF
Exemplo: IF ( X == 0 ) THEN PRINT *, X=0 X=X+1 Y=10**X ELSEIF ( X < 0 ) THEN PRINT *, X um nmero negativo Y=1/10**X ELSE PRINT *, X um nmero positivo Y=10**X END IF
Importante: Podem existir vrios ELSEIFs dentro da lgica de um IF; No existe ENDIF para ELSEIF, pois ele est ligado lgica do IF principal; Pode existir um IF dentro do bloco de comandos de um ELSEIF, neste caso, existe o ENDIF;
32 Diagrama de execuo: IF ( X == 0) THEN Y=1 ELSEIF ( X < 0 ) THEN Y=1/X ELSE Y=X END IF
IF (X==0) THEN
X=0
X /= 0
X<0
ELSE
Y=1/X
Y=X
ENDIF
33
34
EXERCCIO 6 Comando IF
1. Caminhe para o diretrio ~/curso/fortran/ex6. Edite o programa triangulo.f90 cd ~/curso/fortran/ex6 nano triangulo.f90
2.
3.
Esse programa solicita que se digite trs valores inteiros que podero definir os trs lados de um tringulo Eqiltero, Issceles, Escaleno, ou no formar um tringulo.
4.
Se trs valores formam um tringulo, ento 2 vezes o maior valor tem que ser menor que a soma de todos os trs valores, ou seja, a seguinte expresso tem que ser verdadeira para que um tringulo exista. (2*MAX(lado1,lado2,lado3) < lado1+lado2+lado3)
5. Substitua as linhas com reticncias pela lgica de programao que ir determinar que tipo de tringulo ser formado. Analise com ateno o resto do programa para perceber como montar os comandos. Em um determinado instante, a expresso acima ser utilizada.
35
36
b) b) d) a)
! ! ! !
12 4 10 6
37
DO
DO
38
SELECT CASE <(expresso)> CASE <(seleo)> <comando> CASE <(seleo)> <comando> ... CASE DEFAULT <comando> END SELECT
OBS: 1 - A seleo de valores, nos comandos CASE, pode representar uma lista de valores, quando se utiliza os caracteres especiais:
, e/ou :
(6, 10, 100) " Valores iguais a 6, 10 ou 100 (10:65,67:98) " Valores entre 10 e 65, inclusive, ou entre 67 e 98 inclusive (100:) " Valores maiores ou iguais a 100 2 - Inmeros comandos CASE podem existir em um nico SELECT CASE 3 - S existe um CASE DEFAULT em um SELECT CASE
Exemplo: SELECT CASE (I) CASE (1) PRINT*, CASE (2:9) PRINT*, CASE (10:) PRINT*, CASE DEFAULT PRINT*, END SELECT
39
Ocorrem confuses em relao aos resultados quando da diviso entre nmeros inteiros. Ateno, normalmente, o resultado um valor inteiro.
40
Numricas
ABS, AIMAG, AINT, AMAX0, AMIN0, ANINT, CEILING, CMPLX, CONJG, DBLE, DCMPLX, DFLOAT, DIM, DNUM, DPROD, DREAL, FLOAT, FLOOR, IFIX, ILEN, IMAG, INT, INUM, JNUM, MAX, MAX1, MIN, MIN1, MOD, MODULO, NINT, QCMPLX, QEXT, QFLOAT, QNUM, QREAL, RAN, REAL, RNUM, SIGN, SNGL, ZEXT, EXPONENT, FRACTION, NEAREST, RRSPACING, SCALE, SET_EXPONENT, SPACING, DIGITS, EPSILON, HUGE, MAXEXPONENT, MINEXPONENT, PRECISION, RADIX, RANGE, SIZEOF, TINY, DOT_PRODUCT, MATMUL, MCLOCK, SECNDS. ABS(x) INT(x) REAL(x) DBLE(x) MAX(x1,x2,...,xn) MIN(x1,x2,...,xn) MOD(a,p) Valor absoluto; Converte x para um valor inteiro; Converte x para um valor real; Converte x para um valor de preciso dupla; Valor mximo entre os valores x1 e xn; Valor mnimo entre os valores x1 e xn; Resto da diviso a/p;
Caracteres
ADJUSTL, ADJUSTR, INDEX, LEN_TRIM, REPEAT, SCAN, TRIM, VERIFY, IACHAR, ICHAR, IARG, IARGC, LEN, NARGS, NUMARG, LGE, LGT, LLE, LLT.
ADJUSTL(str) ADJUSTR(str) LEN(str) REPEAT(str,i) TRIM(str) IACHAR(str) ACHAR(x) IACHAR(C) ACHAR(67)
ACHAR,
CHAR,
Alinha o valor de str pela esquerda; Alinha o valor de str pela direita; Tamanho da varivel str (Nmero de caracteres); Repete o valor de str, i vezes Remove brancos a direita da varivel str; Retorna o cdigo do caractere str na tabela ASCII; Retorna o caractere identificado pelo cdigo x na tabela ASCII; 67 C
Conjunto
MERGE, PACK, SPREAD, UNPACK, ALLOCATED, LBOUND, SHAPE, SIZE, UBOUND, MAXLOC, CSHIFT, EOSHIFT, RESHAPE, TRANSPOSE, ALL, ANY, COUNT, MAXVAL, MINVAL, PRODUCT. MINLOC,
Outras
ASSOCIATED, BADDRESS, CACHESIZE, EOF, ERF, ERFC, FP_CLASS, IARGPTR, INT_PTR_KIND, ISNAN, LOC, LOGICAL, MALLOC, MULT_HIGH, NULL, PRESENT, TRANSFER.
41
<formato> *
Exemplo:
Formato livre
PROGRAM uno IMPLICIT NONE CHARACTER(LEN=*), PARAMETER :: nome_completo = Mauricio Silva REAL :: x, y, z LOGICAL :: varlog x = 1; y = 2; z = 3 varlog = (y .EQ. X) PRINT*, nome_completo PRINT*,X= ,x, Y = ,y, Z = ,z PRINT*,Varivel lgica: ,varlog END PROGRAM uno Mauricio Silva X = 1.000 Y = 2.000 Z = 3.000 Varivel lgica: F
Formato livre
42
EXERCCIO 7 DO
1 Sugere-se que a populao dos Estados Unidos possa ser modelada de acordo com a frmula:
P (t ) =
2 - Caminhe para o diretrio ~curso/fortran/ex7. Edite o programa pop.f90 . Esse programa calcula a populao dos EEUU a cada 10 anos, entre 1790 e 2000. Acrescente ao programa o loop e a formula para visualizar os valores.
CADEIRAS 50 100 140 e 200 240 300 340 400 440 Acima de 500 Qualquer outro valor
2 Substitua nas reticncias a estrutura de um SELECT CASE que determinar o preo do ingresso. 3 Compile e execute o programa diversas vezes para verificar se est certo. 4 Altere o programa, de maneira que, fique em loop solicitando o nmero da cadeira, at ser digitado 0 que determina o fim do programa.
43
(radianos ) =
( graus )
180
= arctan(1) 4
sen( ) = cos( ) =
y r x r
1. r = 12 2. r = 1000 3. r = 1000 4. r = 20 5. r = 12
= 77 = 0 = 90 = 100 = 437
44
4 CONJUNTO DE DADOS
Em programao, normalmente necessrio manipular uma grande quantidade de dados para efetuar determinadas tarefas: A mdia de um conjunto de nmeros; a anlise do resultado de testes; a ordenao de uma lista de nmeros ou nomes; a soluo de um sistema de equaes lineares. Para eliminar a necessidade de definio de centenas de variveis, pode-se usar o recurso de definio de conjuntos de dados ou Arrays, ou seja, variveis com mais de um elemento, como um vetor de dados ou uma matriz de dados, que sero armazenados na memria e acessados individualmente de acordo com a sua posio espacial, definida pelas dimenses do conjunto de dados.
Conjunto de 2 dimenses (Matriz) Matriz de 15 elementos - 5 x 3: Dimenso 2 1,1 2,1 Dimenso 1 3,1 4,1 5,1 1,2 2,2 3,2 4,2 5,2 1,3 2,3 3,3 4,3 5,3
45
O Fortran90 permite definir os limites inferior (LBOUND) e superior (UBOUND) de cada dimenso de um conjunto de dados, utilizando o caractere : para separar os limites. Caso no exista esse caractere, o valor informado ser sempre o limite superior e o limite inferior ser sempre 1. possvel limites com valores negativo;
REAL, DIMENSION(1:10,1:10) :: S REAL, DIMENSION(-10:-1) :: X REAL, DIMENSION(1:5,1:3) :: Y,Z
O valor dos limites pode ser uma varivel do tipo inteira ou uma expresso aritmtica que resolva para um valor inteiro;
INTEGER, PARAMETER REAL, DIMENSION(0:lda-1) REAL, DIMENSION(1+lda*lda,10) :: lda = 5 :: Y :: Z
O tamanho de um conjunto de dados igual multiplicao dos elementos em cada dimenso; O Fortran90 possui a definio da aparncia (SHAPE) de um conjunto de dados, que definido como sendo o nmero de elementos em cada dimenso;
REAL, DIMENSION(0:20, -5:40, -10:-1) 3 Dimenses Dimenso 1 limite inferior(LBOUND)=0 limite superior(UBOUND)=20 Nmero de elementos da dimenso=21 limite inferior(LBOUND)=-5 limite superior(UBOUND)=40 Nmero de elementos da dimenso=46 limite inferior(LBOUND)=-10 limite superior(UBOUND)=-1 Nmero de elementos da dimenso=10
Dimenso 2
Dimenso 3
46
A(1)
A(2)
A(3)
...
...
...
...
...
...
...
...
...
...
A(14) A(15)
47
48
Operao aritmtica entre alguns elementos do conjunto de dados: A(1) = 0.0 B(0,0) = A(3) + C(5,1)
Operao aritmtica entre sees de elementos de um conjunto de dados: A(2:4) = 0.0 B(-1:0,1:0) = C(1:2, 2:3) + 1.0
Operaes aritmticas com procedimentos internos do Fortran90: B=SIN(C) + COS(D) D=MAX(A,B,C) % % B(i,j)=SIN(C(i,j)) + COS(D(i,j)) D(i,j)=MAX( A(i,j), B(i,j), C(i,j) )
A([<limite
inferior>:<limite superior>][:<incremento>]
todo o conjunto de dados; os elementos A(3) at A(9) de 1 em 1; os elementos A(8) at A(3) de 1 em 1; os elementos A(m) at o limite superior; os elementos do conjunto, de 2 em 2;
49
Leitura: INTEGER, DIMENSION(2,3) :: A READ*, A OBS: 6 elementos sero lidos na ordem por colunas; 123456
A(1,2)=3 A(2,2)=4
A(1,3)=5 A(2,3)=6
1 2 3
4 5 6
7 8 9
PRINT*, Elemento da Matriz PRINT*, Seco da Matriz PRINT*, Sub-Matriz PRINT*, Toda Matriz PRINT*, Matriz Transposta Elemento da Matriz Seco da Matriz Sub-Matriz Toda Matriz Matriz Transposta
=, a( 3 , 2 ) =, a( : , 1 ) =, a( :2 , :2 ) =, a =,TRANSPOSE(a)
50
MAXVAL(ARRAY[,DIM] ), MINVAL(ARRAY[,DIM] )
Retorna o valor mximo/mnimo entre todos os elementos ou entre os elementos de uma dimenso de um conjunto de dados. 1 3 5 2 4 6
MAXVAL(X)=6 MINVAL(X)=1 MAXVAL(X,DIM=1)=(/2,4,6/) MAXVAL(X,DIM=2)=(/5,6/) MINVAL(X,DIM=1)=(/1,3,5/) MINVAL(X,DIM=2)=(/1,2/)
X =
51 SUM(ARRAY[,DIM] ) Retorna a soma de todos os elementos ou entre os elementos de uma dimenso de um conjunto de dados.
X =
1 3 5 2 4 6
SUM(X)=21
SUM(X,DIM=1)=(/3,7,11/)
SUM(X,DIM=2)=(/9,12/)
PRODUCT(ARRAY[,DIM] ) Retorna o produto de todos os elementos ou entre os elementos de uma dimenso de um conjunto de dados.
X =
1 3 5 2 4 6
DOT_PRODUCT(ARRAY1,ARRAY2) a soma do produto interno de dois vetores de dois conjuntos de dados, em apenas uma dimenso.
DP=DOT_PRODUCT(A,B)
DP=A(1)*B(1)+A(2)*B(2)+
DP=SUM(A*B)
MATMUL(ARRAY1,ARRAY2) O resultado a tradicional multiplicao de dois conjuntos de dados de no mximo duas dimenses (matrizes), podendo ser um dos conjuntos de dados, de uma dimenso.
MATMUL(X,Y)
SUM(X(i,:)*Y(:,j))
52
! 1D ! 2D
Alocar a memria durante a execuo do programa: Comando - ALLOCATE ALLOCATE(ARRAY(DIM)[,STAT=<varivel>]) READ*, isize ALLOCATE(idade(isize), STAT=err) IF (err /= 0) PRINT*, idade : Falhou a alocao de memria ALLOCATE(velo(0:isize-1,10), STAT=err) IF (err /= 0) PRINT*, velo : Falhou a alocao de memria
OBS: O espao de memria reservado para um conjunto de dados, permanece alocado at ser efetuado um DEALLOCATED ou, at o fim da execuo do programa.
53
54
2.
Utilize uma funo de conjunto de dados para definir o valor de M e N, como sendo o nmero de elementos do conjunto A, em cada dimenso. Imprima esses valores; Imprima o conjunto A por linhas; Imprima a soma do produto entre os elementos das colunas de A; Imprima o produto da soma dos elementos das linhas de A; Imprima a soma dos quadrados dos elementos de X; Imprima a mdia dos elementos de X; Imprima o maior valor absoluto de X; Imprima o maior valor absoluto da soma das colunas de A.
3. 4. 5. 6. 7. 8. 9.
55
2 Caminhe para o diretrio ~/curso/fortran/ex13. Edite o programa MatrizSalario.f90 . Codifique o que solicitado nas reticncias. Esse programa calcula o custo total que a companhia ter com o incremento de 5%, 4% e 2% para as categorias 1, 2 e 3 respectivamente.
56
PROGRAM
Seo principal do programa aonde a execuo inicia e finaliza. Pode conter vrios procedimentos como subrotinas e funes.
MODULE
Seo do programa que pode conter novas declaraes e procedimentos podendo ser anexado ao programa principal.
O Fortran90 possui dois tipos de definio de procedimentos, que devem estar dentro do contexto do programa principal ou do mdulo.
SUBROUTINE
A subrotina um programa com parmetros de entrada e sada, comandos de declarao e lgica de execuo, que pode ser chamada de dentro do programa principal com o comando CALL.
CALL <subrotina> ([parmetro1, parmetro2,...])
FUNCTION
A funo similar a uma subrotina, podendo ter vrios parmetros de entrada, comandos de declarao e lgica de execuo, no entanto, retorna apenas um nico valor que armazenado no nome da funo. A funo pode ser executada dentro de um outro comando.
PRINT*, Resultado da Funo :, f(x)
57
O comando PROGRAM opcional, assim como o nome do programa, mas uma boa prtica sempre us-lo; O programa principal pode conter comandos de declarao, comandos executveis e procedimentos internos: subrotinas e funes, definidas pelo usurio. Esses procedimentos so definidos e separados do resto do programa pelo comando CONTAINS; O programa principal pode definir inmeros procedimentos internos, mas estes, no podem definir novos procedimentos; O programa principal tem que ser finalizado com o comando END.
Exemplo: PROGRAM main IMPLICIT NONE REAL :: x READ*, x PRINT*, SQRT(x) ! Funo interna PRINT*, Negative(x) ! Funo do usurio CONTAINS REAL FUNCTION Negative(a) REAL, INTENT(IN) :: a Negative = -a END FUNCTION Negative END PROGRAM Main
58
Sempre se questione se necessrio criar um cdigo para resolver alguma tarefa do seu programa. Existem dezenas de bibliotecas de rotinas, algumas de domnio pblico, que facilitam a soluo de determinados problemas. Normalmente, os cdigos dessas rotinas j foram bastante depurados e otimizados.
Bibliotecas comerciais:
NAG - Numerical Algorithms Group - www.nag.co.uk IMSL - International Mathematics and Statistics Library - www.vni.com/products/imsl ESSL - Engineering and Scientific Subroutine Library - www-03.ibm.com/systems/p/software/essl/index.html
- www.netlib.org/blas
Fortran da GNU: gcc.gnu.org/fortran Fortran da Intel: software.intel.com/en-us/articles/non-commercial-software-download Conversor de Fortran para C: www.netlib.org/f2c
59
Para se definir uma subrotina usa-se a estrutura SUBROUTINE END SUBROUTINE; Para se usar uma subrotina usa-se o comando CALL <nome da subrotina>; Uma subrotina enxerga todas as variveis declaradas no programa principal; Uma subrotina pode incluir a chamadas a outras subrotinas. Subrotinas so posicionadas entre o comando CONTAINS e o comando END PROGRAM; O Fortran90 permite execuo recursiva de subrotinas, ou seja, subrotina que chama ela mesma; basta acrescentar o comando RECURSIVE antes de SUBROUTINE.
Exemplo: PROGRAM algo IMPLICIT NONE REAL, DIMENSION(100) :: numeros ... CALL ImprimeNum(numeros) ... CONTAINS SUBROUTINE ImprimeNum(num) REAL, DIMENSION(:), INTENT(IN) :: num PRINT*,Esses so os nmeros, num END SUBROUTINE ImprimeNum END PROGRAM algo OBS: A varivel dummy: num, assume a dimenso da varivel nmeros, definida no programa principal.
60
[<Tipo da Funo>] FUNCTION <nome> [(<argumentos>)] Declarao dos argumentos dummy Declarao dos objetos Comandos executveis Comando de atribuio do resultado END [FUNCTION [<nome>]]
Funo funciona sobre o mesmo princpio da subrotina, com a diferena de que a funo retorna um nico resultado; Uma funo definida usando-se a estrutura FUNCTION END FUNCTION; Pra usar uma funo, basta cham-la pelo nome; Funo pode ser definida na rea de declarao de variveis quando se identifica o tipo da funo; O tipo da funo pode ser especificado quando for definida a funo, ou dentro da definio da funo, pois o nome da funo receber o resultado; O Fortran90 permite execuo recursiva de funes, ou seja, funo que chama ela mesma; basta acrescentar o comando RECURSIVE antes de FUNCTION.
Exemplo Alternativa 1 PROGRAM algo IMPLICIT NONE ... PRINT*, F(a,b) ... CONTAINS REAL FUNCTION F(x,y) REAL, INTENT(IN) :: x,y F=SQRT(x*x + y*y) END FUNCTION F END PROGRAM algo
Exemplo Alternativa 2 PROGRAM algo IMPLICIT NONE ... PRINT*, F(a,b) ... CONTAINS FUNCTION F(x,y)
REAL :: F
REAL, INTENT(IN) :: x,y F=SQRT(x*x + y*y) END FUNCTION F END PROGRAM algo
61
Considere o comando: PRINT*, F(a,b) E a definio da funo: REAL FUNCTION F(x,y) Os argumentos do programa principal: a e b, esto associados aos argumentos dummy: x e y, da funo F. Se os valores dos argumentos dummy forem alterados durante a execuo da funo, ento os valores associados, tambm sero modificados.
Na definio do procedimento abaixo: SUBROUTINE madras(i,j) INTEGER, INTENT(IN) :: i,j REAL :: a REAL, DIMENSION(i,j) :: x END SUBROUTINE madras
a e x so conhecidos como objetos locais, e x, pode ter uma aparncia e tamanho diferente a cada chamada do procedimento. Isso significa que, os objetos locais:
1. so iniciados cada vez que o procedimento chamado; 2. so eliminados quando o procedimento finaliza sua execuo; 3. no mantm seus valores entre chamadas, a no ser que na declarao, sejam iniciados com um determinado valor (REAL :: a=0); 4. no utilizam o mesmo espao de endereamento de memria do programa principal.
62 Atributo INTENT
Esse atributo da declarao de objetos locais utilizado para facilitar a compilao e por razes de otimizao, mas a sua utilizao no essencial.
INTENT(IN)
Objeto de entrada, enviado pelo programa principal e no pode ser modificado durante a execuo do procedimento; Objeto de sada, o seu valor definido pelo procedimento que devolvido ao programa principal; Objeto de entrada e sada, enviado pelo programa principal, pode ser modificado pelo procedimento e ento devolvido ao programa.
INTENT(OUT)
INTENT(INOUT)
Exemplo: SUBROUTINE ex(arg1,arg2,arg3) REAL, INTENT(IN) :: arg1 INTEGER, INTENT(OUT) :: arg2 CHARACTER, INTENT(INOUT) :: arg3 REAL r r=arg1*ICHAR(arg3) arg2=ANINT(r) arg3=CHAR(MOD(127,arg2)) END SUBROUTINE ex
1. arg1 no modificado no procedimento; 2. o valor de arg2 no utilizado at ser definido pelo procedimento; 3. arg3 utilizado e o seu valor redefinido.
63 Atributo SAVE
Variveis definidas com o atributo SAVE so conhecidas como objetos estticos e por sua vez possuem armazenamento esttico no sendo reiniciadas a cada chamada do procedimento. Com exceo das variveis dummy e das variveis definidas com o atributo PARAMETER, as variveis declaradas possuem, implcito, o atributo SAVE, desde que possuem um valor inicial na declarao.
Exemplo 1 (Sem o atributo SAVE) PROGRAM A REAL :: X CALL CH() PRINT *,"Programa principal x=",X CALL CH() PRINT *,"Programa principal x=",X CONTAINS SUBROUTINE CH REAL :: X X=X+1 PRINT*,"Subrotina x=",X END SUBROUTINE END Subrotina x= 1.000000 Programa principal x= 0.0000000E+00 Subrotina x= 1.000000 Programa principal x= 0.0000000E+00 PROGRAM A Exemplo 2 (Com o atributo SAVE) PROGRAM A REAL :: X CALL CH() PRINT *,"Programa principal x=",X CALL CH() PRINT *,"Programa principal x=",X CONTAINS SUBROUTINE CH REAL,SAVE :: X ! ou REAL :: X=0.0 X=X+1 PRINT*,"Subrotina x=",X END SUBROUTINE END Subrotina x= 1.000000 Programa principal x= 0.0000000E+00 Subrotina x= 2.000000 Programa principal x= 0.0000000E+00 PROGRAM A
X => 0
SUBROUTINE CH
X => 0
SUBROUTINE CH
Exemplo 3 (Sem a definio de X na subrotina) PROGRAM A REAL :: X CALL CH() PRINT *,"Programa principal x=",X CALL CH() PRINT *,"Programa principal x=",X CONTAINS SUBROUTINE CH X=X+1 PRINT*,"Subrotina x=",X END SUBROUTINE END Subrotina x= 1.000000 Programa principal x= 1.000000 Subrotina x= 2.000000 Programa principal x= 2.000000
Exemplo 4 (Vriveis X indenpendentes) PROGRAM A REAL :: X X=X+100 CALL CH() PRINT *,"Programa principal x=",X X=X+100 CALL CH() PRINT *,"Programa principal x=",X CONTAINS SUBROUTINE CH REAL,SAVE :: X X=X+1 PRINT*,"Subrotina x=",X END SUBROUTINE END Subrotina x= 1.000000 Programa principal x= 100.0000 Subrotina x= 2.000000 Programa principal x= 200.0000 PROGRAM A
PROGRAM A
X => 1,2
SUBROUTINE CH
X=X+1
64
Exemplo: Definio do mdulo - Declara as variveis X, Y e Z como variveis reais globais. MODULE global REAL, SAVE :: X, Y, Z END MODULE global
Utilizao do mdulo:
PROGRAM teste USE global IMLPICIT NONE ... END PROGRAM teste
65
EXERCCIO 14 Subrotina
1 Caminhe para o diretrio: ~/curso/Fortran/ex14. Edite o arquivo subrotina.f90 e adicione a subrotina de acordo com a descrio do problema. Esse programa possui uma rotina interna que retorna, como primeiro argumento, a soma de dois nmeros reais. Subrotina summy(arg1, arg2, arg3) arg1 arg2 arg3 varivel com resultado varivel com 1 nmero varivel com 2 nmero
arg1=arg2+arg3 O programa principal dever chamar a rotina trs vezes e imprimir o resultado: # # # Nmeros: 2.6 e 3.1 Nmeros: 6.1 e 9.2 Nmeros: 0.1 e 0.555
EXERCCIO 15 Funo
1 Caminhe para o diretrio: ~/curso/Fortran/ex15. Edite o arquivo funcao.f90 e adicione a funo de acordo com a descrio do problema. Esse programa possui uma funo interna que retorna a soma de dois nmeros reais, fornecido pelos argumentos. Funo real summy(arg1,arg2) Arg1 Arg2 varivel com 1 nmero varivel com 2 nmero
summy=arg1+arg2 O programa principal dever chamar a rotina quatro vezes e imprimir o resultado: # # # # Nmeros: 1.0 e 2.0 Nmeros: 1.0 e -1.0 Nmeros: 0.0 e 0.0 Nmeros: 1.0E54 e 9192652.0
66
4 Copie o objeto (.o) e o mdulo (.mod), gerado no exerccio anterior, para este diretrio. Crie o executvel linkeditando os dois objetos, da seguinte maneira:
ifort o Teste_modulo UsoModulo.o DefModulo.o OBS: Tudo isso pode ser feito em um nico passo, desde que os arquivos do exerccio anterior j tenham sido copiados. ifort UsoModulo.f90 DefModulo.o o Teste_modulo
3.0 17.0 7.56 78.1 99.99 0.8 11.7 33.8 29.6 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 11.0 12.0 13.0 14.0
67
Existe uma regra para a disposio da seqncia de dados; No existe uma regra para a seqncia de dados, sendo o caractere branco o limite entre uma seqncia e outra; (ENDFILE)Registro especial que determina o fim do arquivo.
Em Fortran90, um arquivo conectado durante a execuo do programa atravs de uma unidade lgica, que definida por um nmero inteiro e positivo, no comando de abertura do arquivo. Na maioria dos compiladores esse nmero est limitado entre 1 e 999; Cada unidade lgica pode possuir diversas propriedades para a manipulao dos arquivos: - Arquivo - Ao Nome do arquivo que ser conectado; Modo de acesso ao arquivo:
read (leitura) write (gravao) read/write (leitura e gravao);
- Status
Status do arquivo:
old (arquivo j existe) new (arquivo novo) replace (sobreposio de arquivo);
- Mtodo de acesso
68
O nico parmetro obrigatrio o valor inteiro que ir identifica a unidade lgica, mas aconselhvel informar o nome do arquivo e mais dois parmetros para analisar possveis erros.
UNIT= FILE= ERR= Valor inteiro, qualquer, que especifica a unidade lgica para um arquivo; Especifica, entre aspas, o nome do arquivo que ser conectado; Valor inteiro, que especifica uma posio lgica de controle, no programa, aonde ser analisado o erro que ocorreu na abertura do arquivo. OBS: Especificar esse parmetro, evita que o Fortran cancele a execuo do programa, caso o erro ocorra. Varivel inteira que ir armazenar o cdigo do erro na abertura de arquivo. Um valor igual a zero significa que no houve erro.
IOSTAT=
REPLACE O arquivo ser sobreposto; SCRATCH O arquivo temporrio e ser apagado quando fechado (CLOSE); UNKNOW Desconhecido (default, assumir OLD ou NEW); ACCESS= Especifica o mtodo de acesso: DIRECT Acesso direto a registros individuais. obrigado a usar a opo RECL;
SEQUENTIAL Acesso sequncial, linha por linha (default); ACTION= Especifica o modo de acesso ao arquivo: Somente leitura; READ Somente gravao; WRITE READWRITE Leitura e gravao; RECL= Especifica uma expresso, que resolva para um valor inteiro, que ir determinar o tamanho do registro, somente quando o modo de acesso for direto.
69
Exemplos:
PROGRAM arquivo CHARACTER(LEN=40) :: FILNM DO I=1,4 FILNM = '' PRINT *, 'Entre com o nome do arquivo.' READ *, FILNM OPEN (UNIT=1, FILE=FILNM, STATUS='OLD', IOSTAT=IERR, ERR=100) PRINT*,'Abrindo arquivo: ', FILNM ... CLOSE (UNIT=1) STOP IF (IERR .EQ. FOR$IOS_FILNOTFOU) THEN ! Cdigo 29 Arquivo no existe PRINT *, 'Arquivo: ', FILNM, ' no existe. ' ELSE IF (IERR .EQ. FOR$IOS_FILNAMSPE) THEN PRINT *, 'Arquivo: ', FILNM, ' com problemas, entre novamente:' ELSE PRINT *, 'Erro indefinido! Cdigo =', IERR STOP END IF
100
END DO PRINT *, 'Arquivo no encontrado. Corrija o problema e execute novamente! ' END PROGRAM arquivo
OPEN(17,FILE=saida.dat,ERR=10,STATUS=REPLACE,& ACCESS=SEQUENTIAL,ACTION=WRITE)
70
O nico parmetro realmente obrigatrio a unidade lgica para identificar de qual arquivo est sendo feito leitura, no entanto, se for uma leitura em um arquivo com os dados formatados, o parmetro de formato (FMT), tambm ser necessrio.
UNIT= Valor inteiro, qualquer, que especifica a unidade lgica para um arquivo. O smbolo * representa a unidade padro, neste caso, o monitor. A unidade pode indicar um arquivo externo ou uma varivel caractere criada no programa; Especifica o formato da leitura dos dados. A especificao do formato tem vir, primeiro, entre aspas, e segundo, entre parnteses, ou, pode ser feita uma indicao de uma posio lgica no programa, aonde se encontra um comando FORMAT com a descrio do formato; FMT=(I4) ERR= FMT=200
FMT=
Valor inteiro, que especifica uma posio lgica de controle no programa, aonde ser analisado o erro que ocorreu na leitura do arquivo. OBS: Especificar esse parmetro, evita que o Fortran cancele a execuo do programa, caso o erro ocorra. Varivel inteira que ir armazenar o cdigo do erro na abertura de arquivo. Um valor igual a zero significa que no houve erro. Valor inteiro, que especifica uma posio lgica de controle no programa, aonde ser analisado o erro de fim de arquivo. Especifica uma expresso, que resolva para um valor inteiro, que ir determinar o nmero do registro. Utilizado somente quando o modo de acesso for direto. Parmetro que especifica (YES ou NO) se cada comando READ deve, ou no, iniciar a leitura em um novo registro. O padro : ADVANCE=YES, se for utilizado o parmetro para no avanar a leitura, ento, ser obrigatrio o arquivo ser conectado no modo de acesso seqencial e a descrio do formato de leitura, no parmetro FMT. Valor inteiro, que especifica uma posio lgica de controle no programa, aonde ser analisado o erro fim de registro. Este parmetro s utilizado no comando READ e quando o parmetro ADVANCE=NO for utilizado; Varivel inteira que ir armazenar o nmero de caracteres lidos pelo comando READ e, somente quando o parmetro ADVANCE=NO tiver sido utilizado.
IOSTAT=
END=
REC=
ADVANCE=
EOR=
SIZE=
71
Exemplo 1: PROGRAM ler 501 FORMAT(3I5) INTEGER A,B,C DO READ(*,501,END=50,ERR=90) A,B,C IF(A=0 .OR. B=0 .OR. C=0) THEN PRINT *,Um dos lados e igual a zero ! STOP ELSE S = (A + B + C) / 2.0 AREA = SQRT( S * (S - A) * (S - B) * (S - C)) PRINT *, A, B, C, AREA ENDIF END DO 50 PRINT *, Fim do programa! STOP 90 PRINT *,Entrada de dado errada! STOP END PROGRAM Exemplo 2: Arquivo:control_file.txt pi 3.1415 invalid 5.7 vector 0 1 1 2 3 Arquivo:control_file.f90 ! JASON BLEVINS <JRBLEVIN@SDF.LONESTAR.ORG> ! DURHAM, MAY 6, 2008 PROGRAM controle IMPLICIT NONE CHARACTER(LEN=100) :: buffer, label INTEGER :: pos INTEGER, PARAMETER :: fh = 15 INTEGER :: ios = 0 INTEGER :: line = 0 REAL :: pi INTEGER, DIMENSION(5) :: vector OPEN(fh, FILE='controle.txt') DO WHILE (ios == 0) READ(fh, '(A)', IOSTAT=ios) buffer IF (ios == 0) THEN line = line + 1 pos = SCAN(buffer, ' ') label = buffer(1:pos) buffer = buffer(pos+1:) SELECT CASE (label) CASE ('pi') ! Leitura de uma unidade interna: o registro armazenado em buffer READ(buffer, *, IOSTAT=ios) pi PRINT *, 'READ pi: ', pi CASE ('vector') ! Leitura de uma unidade interna: o registro armazenado em buffer READ(buffer, *, IOSTAT=ios) vector PRINT *, 'READ vector: ', vector CASE DEFAULT PRINT *, 'SKIPPING INVALID LABEL AT LINE', line END SELECT END IF END DO END PROGRAM controle Outros exemplos: READ(14,FMT=(3(F10.7,1x)),REC=exp) a,b,c READ(*, (A), ADVANCE=NO,EOR=12,SIZE=nch) str
72
WRITE([UNIT=]<inteiro> [,[FMT]=<formato ou label>] [,ERR=<label>] [,IOSTAT=<ivar>] [,ADVANCE=<modo>] [,REC=<expresso inteira>] [,SIZE=<ivar>]) <lista de variveis>
O nico parmetro realmente obrigatrio a unidade lgica para identificar para qual arquivo est sendo feito gravao, no entanto, se for uma gravao em um arquivo com os dados formatados, o parmetro de formato (FMT), tambm ser necessrio.
UNIT= Valor inteiro, qualquer, que especifica a unidade lgica para um arquivo. O smbolo unidade padro, neste caso, o monitor;
* representa a
FMT=
Especifica o formato da gravao dos dados. A especificao do formato tem vir, primeiro, entre aspas, e segundo, entre parnteses, ou, pode ser feita uma indicao de uma posio lgica no programa, aonde se encontra um comando FORMAT com a descrio do formato; Valor inteiro, que especifica uma posio lgica de controle no programa, aonde ser analisado o erro que ocorreu na gravao do arquivo. OBS: Especificar esse parmetro, evita que o Fortran cancele a execuo do programa, caso o erro ocorra. Varivel inteira que ir armazenar o cdigo do erro na abertura de arquivo. Um valor igual a zero significa que no houve erro. Especifica uma expresso, que resolva para um valor inteiro, que ir determinar o nmero do registro. Utilizado somente quando o modo de acesso for direto. Parmetro que especifica (YES ou NO) se cada comando WRITE deve, ou no, iniciar a gravao em um novo registro. O padro : ADVANCE=YES, se for utilizado o parmetro para no avanar a gravao, ento, ser obrigatrio o arquivo ser conectado no modo de acesso seqencial e a descrio do formato de gravao, no parmetro FMT.
ERR=
IOSTAT=
REC=
ADVANCE=
73
Exemplo 1: PROGRAM divisores C Este programa acha os divisores de uma valor inteiro informado. C O divisor salvo em um arquivo. INTEGER n, k, d(10) OPEN (UNIT = 1, FILE = "div.txt") PRINT *, "Informe um valor inteiro positivo :" READ *, n WRITE (1,*) "Divisores de ", N, " :" k = 0 DO i = 1, n IF (MOD(n,i) .EQ. 0) THEN k = k + 1 d(k) = i END IF IF (k .EQ. 10) THEN WRITE (1,5) (d(j), j = 1, 10) k = 0 END IF END DO WRITE (1,5) (d(j), j = 1, k) 5 FORMAT (10I7) CLOSE (1) PRINT *, "Os divisores esto salvos no arquivo 'div.txt' " END Arquivo div.txt
Divisores de 1 2 40 50 625 800 10000 12500 100000 : 4 5 80 100 1000 1250 20000 25000 8 10 125 160 2000 2500 50000 100000 16 200 3125 20 250 4000 25 400 5000 32 500 6250
Outros exemplos:
74
Exemplos:
INTEGER :: j REAL, DIMENSION(10) :: A READ (*,*) ( A(j), j=1,10 ) WRITE (*,*) ( A(j), j=10,1,-1 )
J=1,10 )
A(6,1), A(6,2), A(6,3), B(6), A(4,1), A(4,2), A(4,3), B(4), A(2,1), A(2,2), A(2,3), B(2)
75
Descritores de dados
A[w] Descreve dados do tipo caractere. O tamanho w do campo opcional. Iw
Descreve dados do tipo inteiro; w indica o nmero de dgitos.
Fw.d Descreve dados do tipo real; w indica o nmero total de dgitos e d o nmero de decimais. Ew.d Descreve dados do tipo real com expoente; w indica o nmero total de dgitos e d o nmero de decimais. Lw Bw Ow Zw
Descreve dados do tipo lgico;w indica o nmero de caracteres no campo lgico. Descreve dados do tipo inteiro em base binria; w indica o nmero de dgitos no campo binrio. Descreve dados do tipo inteiro em base octal; w indica o nmero de dgitos no campo octal. Descreve dados do tipo inteiro em base hexadecimal; w indica o nmero de dgitos no campo hexadecimal.
Descritores de Controle
BN BZ Tn
Na leitura de dados, ignora os brancos a esquerda de campos numricos. Na leitura de dados, trata os brancos a esquerda de campos numricos, como zeros. Posiciona a leitura ou gravao na posio n.
[n]X Pula n espaos em branco. [r]/ Finaliza o registro atual e pula para o incio do prximo registro (o r significa repetio da ao). : $
Para de processar o formato se no possuir mais variveis para utilizar a sequncia editada. Na gravao de dados, se o primeiro caractere for um branco ou +, este smbolo, elimina o caractere de fim de linha (cr ou lf), mantendo a continuao da gravao, na mesma linha.
76
FORMAT
A expresso caractere com a formatao dos dados uma sequncia de descritores de edio;
Exemplo 1: WRITE(17, FMT=(2X, 2I4, 1X, Nome , A7))11, -195, Paulo WRITE(*, FMT=10)1.05133, 333356.0 FORMAT(vals,2(F15.6,2X))
1 1 1 9 5 N o m e P a u l o
10
- 1 . 0 5 1 3 3 0
3 3 3 3 5 6 . 0 0 0 0 0 0
Exemplo 3: PRINT 10, (X(I), I = 1, N ) 10 FORMAT( 'X1:', I2 : ' X2:', I2 Quando N=1 X1: 1 Sem o caractere : o resultado seria: X1: 1 X2: Exemplo 4: Formato F8.5,F8.5 E9.1,F9.3 Valor especificado 1234567812345.67 734.432E8123456789 Resultado 123.45678, 12345.67 734.432E8, 123456.789 X3:
' X3:', I3 )
77
Exemplo 6:
Arquivo: 001 0101 002 0201 003 0301 004 0401 005 0501 006 0601 007 0701 008 0801 009 0901 010 1001 FOR002.DAT 0102 0103 0104 0202 0203 0204 0302 0303 0304 0402 0403 0404 0502 0503 0504 0602 0603 0604 0702 0703 0704 0802 0803 0804 0902 0903 0904 1002 1003 1004
0105 0205 0305 0405 0505 0605 0705 0805 0905 1005
PROGRAM ex INTEGER I, J, A(2,5), B(2) OPEN (unit=2, access='sequential', file='FOR002.DAT') READ (2,100) (B(I), (A(I,J), J=1,5),I=1,2) & 100 FORMAT (2(I3, X, 5(I4,X), /)) ' WRITE (6,999) B, ((A(I,J),J=1,5),I=1,2) ( 999 FORMAT (' B is ', 2(I3, X), '; A is', / 1(' ', 5(I4, X))) READ (2,200) (B(I), (A(I,J), J=1,5),I=1,2) ) 200 FORMAT (2(I3, X, 5(I4,X), :/) ) WRITE (6,999) B, ((A(I,J),J=1,5),I=1,2) * READ (2,300) (B(I), (A(I,J), J=1,5),I=1,2) + 300 FORMAT ((I3, X, 5(I4,X))) WRITE (6,999) B, ((A(I,J),J=1,5),I=1,2) , READ (2,400) (B(I), (A(I,J), J=1,5),I=1,2) 400 FORMAT (I3, X, 5(I4,X) ) WRITE (6,999) B, ((A(I,J),J=1,5),I=1,2) . END PROGRAM ex
& Este comando READ ler: B(1); A(1,1) at A(1,5); B(2); A(2,1) at A(2,5). O primeiro
registro a ser lido ser o 001 que inicia o processo de leitura;
' No comando FORMAT indicado, processa dois registros com o formato I3, X, 5(I4, X). O caractere (/) fora a leitura para o segundo registro, aps o dado A(1,5) ser processado. A
leitura para, no incio de um terceiro registro, aps o dado A(2,5) ser processado; ( Este comando WRITE mostra o resultado na tela (unidade padro 6): B is 1 2 ; A is 101 102 103 104 105 201 202 203 204 205
) Este comando READ comea a leitura no registro 004. O caractere (/) fora a leitura para o prximo registro, aps o dado A(1,5) ser processado. O caractere (:), para a leitura, aps o dado A(2,5) ser processado, antes do caractere (/) forar a leitura de um novo registro; * Este comando WRITE mostra o resultado na tela (unidade padro 6):
B is 4 5 ; A is 401 402 403 404 405 501 502 503 504 505
+ Este comando READ comea a leitura no registro 006. Aps o dado A(1,5) ser processado, ocorre a reverso do formato para continuar a leitura, ou seja, o formato reiniciado; a colocao dos parnteses no incio da sequncia dos descritores, causa a leitura do prximo registro, iniciando o processo de formatao no parnteses da esquerda, antes do I3; , Este comando WRITE mostra o resultado na tela (unidade padro 6):
B is 6 7 ; A is 601 602 603 604 605 701 702 703 704 705
- Este comando READ comea a leitura no registro 008. Aps o dado A(1,5) ser processado,
ocorre a reverso do formato para continuar a leitura, ou seja, o formato reiniciado; a colocao dos parnteses no incio da sequncia dos descritores, causa a leitura do prximo registro, iniciando o processo de formatao no parnteses da esquerda, antes do I4; . Este comando WRITE mostra o resultado na tela (unidade padro 6): B is 8 90 ; A is 801 802 803 804 805 9010 9020 9030 9040 100
78
CLOSE[([UNIT=]unit[,ERR=])][unit]
REWIND[([UNIT=]unit[,ERR=])][unit]
BACKSPACE[([UNIT=]unit[,ERR=])][unit]
ENDFILE[([UNIT=]unit[,ERR=])][unit]
Fora a gravao de um registro indicando o fim de arquivo (EOF), sem fechar a conexo com a unidade lgica, e se posiciona aps esta marca de fim de arquivo. OBS: No permitido gravar registros aps a marca de fim de arquivo. Se for preciso ler ou gravar algum dado, ser necessrio executar um REWIND ou BACKSPACE para voltar a uma posio antes desta marca.
WRITE (14, *) x ENDFILE 14 REWIND 14 READ (14, *) y
DELETE([UNIT=]unit[,REC=][,ERR=])
Elimina, da unidade lgica especificada em modo de acesso direto, o registro informado no parmetro REC=
DELETE(17,REC=20)
79
variveis ou conjuntos de dados; valores das variveis, separados por vrgulas. Pode-se usar o operador * para representar repetio de valores;
Exemplo 1: INTEGER :: count, I, J REAL :: inc, max, min CHARACTER(LEN=5) :: luz LOGICAL :: vermelho, azul, verde DATA count/0/, I/5/, J/100/ DATA inc, max, min/1.0E-05, 10.0E+05, -10.0E+05/ DATA luz/Clara/ DATA vermelho/.TRUE./, azul, verde/.FALSE.,.FALSE./ Exemplo 2: REAL DATA DATA DATA DATA DATA Exemplo 3: DATA matriz(1,1:100)/50*1.0,50*2.0/ ! Primeira linha Exemplo 4: DIMENSION A(10,10) DATA A/100*1.0/ ! Iniciar por nome do conjunto DATA A(1,1), A(10,1), A(3,3) /2*2.5, 2.0/ ! Iniciar por elemento do conjunto DATA ((A(I,J), I=1,5,2), J=1,5) /15*1.0/ ! Iniciar por loops subentendidos :: matriz(100,100) matriz(1,1:100)/100*1.0/ matriz(100,1:100)/100*1.0/ matriz(2:99,1)/98*1.0/ matriz(2:99,100)/98*1.0/ matriz(2:99,2:99)/9604*0.0/ ! ! ! ! !
Primeira linha ltima linha Primeira coluna ltima coluna Interior do conjunto
DATA ((diag(i,j),diag(j,i),j=i+1,100),i=1,100)/9900*0.0/
80
Exemplo:
! DERIVED.F90 PROGRAM deriva TYPE pessoa INTEGER idade CHARACTER (LEN = 20) nome END TYPE pessoa REAL :: x INTEGER :: valor TYPE (pessoa) :: jorge TYPE (pessoa) :: ana END PROGRAM
81
Outra forma, especificar os componentes do novo tipo de dados entre parnteses, na ordem que foram definidos os componentes.
varivel definida = tipo definido ( componente1, componente2,...) Exemplo: ! DERIVED.F90 PROGRAM deriva TYPE pessoa INTEGER idade CHARACTER (LEN = 20) nome END TYPE pessoa REAL :: x INTEGER :: valor TYPE (pessoa) :: jorge TYPE (pessoa) :: ana jorge = pessoa( 33, 'Jorge Alberto' ) ana%idade = 56 ana%nome = 'Ana Aparecida' WRITE (*,*) jorge WRITE (*,*) ana END
82
ou
GO TO <label>
8.3 - STOP
Comando que causa a parada imediata da execuo do programa.
STOP [texto]
Exemplo: OPEN(1,FILE='file1.dat', status='OLD', ERR=100) ... STOP 'Ocorreu um erro na abertura do arquivo!' END
100
83
9 - RECOMENDAES DE CODIFICAO
Sempre utilize o comando de declarao IMPLICT NONE, ou seja, sempre declare todas as variveis que forem utilizadas no programa;
Comandos, procedimentos internos e as definidas pelo programador, devem ser colocadas em maisculas;
OBS: No obrigatrio! Apenas uma recomendao.
84
EXERCCIO 19 I/O
1 - Caminhe para o diretrio ~/curso/Fortran/ex19. Edite o programa Write_io.f. Substitua as reticncias pelo comando adequado. Esse programa solicita dados para serem digitados e os grava em um arquivo. 2 Compile e execute o programa, testando com os seguintes valores: Blair Major Ashdown END 94. 2. 49. 0. 97. 6. 28. 0. 97. 6. 77. 0. 94. 5. 66. 0.
3 - Edite o programa Read_io.f. Substitua as reticncias pelo comando adequado. 4 - Compile e execute o programa.
EXERCCIO 20 I/O
1 - Caminhe para o diretrio ~/curso/fortran/ex20. Edite o programa io_spec.f90 Substitua as reticncias pelos comandos de I/O, solicitados nas linhas de comentrio. Este programa grava e l um arquivo com um nico registro. 2 Compile e execute o programa. Verifique se o ltimo resultado est de acordo com os valores: 1 2 3 4 5 6 7 8 -1 -2
EXERCCIO 21 Formatao
1 Dado o comando abaixo: READ(*,'(F10.3,A2,L10)') A,C,L Como ser representado o valor de A (REAL), o valor de C (CHARACTER de tamanho 2) e o valor de L LOGICAL logical) para os seguintes valores de dados? (OBS: b significa espao em branco.) bbb5.34bbbNOb.TRUE. 5.34bbbbbbYbbFbbbbb b6bbbbbb3211bbbbbbT bbbbbbbbbbbbbbbbbbF 2 - Caminhe para o diretrio ~/curso/Fortran/ex21. Edite o programa IOFormatado.f. Substitua as reticncias pelo comando adequado. Esse programa gera um arquivo com linhas de cabealho e linhas de dados, sendo: NAME (at 15 caracteres), AGE (at 3 dgitos), HEIGHT (em metros 4 posies e 2 decimais) e o FONE ( 4 dgitos inteiros). Name ---Bloggs J. G. Clinton P. J. Age --45 47 Height (metres) -----1.80 1.75 Tel. No. -------3456 6783
85
86
10 - REFERNCIAS
1 - IBM XL Fortran for AIX Users Guide Version 8 Release 1 2 - IBM XL Fortran for AIX Language Reference Version 8 Release 1 3 - INTEL Fortran Language Reference 4 - The University of Liverpool Fortran 90 Programming Dr. A.C. Marshall 5 - Fortran 90 Handbook - Complete ANSI / ISO Reference - Intertext Publications McGraw-Hill Book Company Jeanne C. Adams Walter S. Brainerd Jeanne T. Martin Brian T. Smith Jerrold L. Wagener 6 - Introduction to Fortran 90 for Scientists and Engineers Brian D Hahn Department of Applied Mathematics - University of Cape Town