Você está na página 1de 101

FORTRAN 90

Sintaxe das Principais Estruturas da Linguagem e Exemplos

COPPE/UFRJ

Jaci Maria Bernardo Guigon

ndice
1. PROGRAMAO EM FORTRAN 77/FORTRAN 90 1.1 - O COMPILADOR FORTRAN90 1.2 - EXEMPLOS DE BIBLIOTECAS NUMRICAS, ESTATSTICAS E PARA PARALELIZAO DE ALGORITMOS INTEGRADAS AO FORTRAN 90 1.3 - GNUPLOT - SOFTWARE DE VISUALIZAO ....................... ....................... ....................... 3 6 7

2 ESTRUTURA DA LINGUAGEM 2.1 ESCREVENDO O CDIGO FONTE 2.2 USANDO O COMPILADOR FORTRAN NO LINUX

....................... .......................

8 11

3 ELEMENTOS DE PROGRAMAO 3.1 TIPOS DE DADOS E VARIVEIS 3.2 IMPLICIT NONE 3.3 O ATRIBUTO KIND FORTRAN90 3.4 ARITMTICA INTEIRA, REAL E MISTA 3.5 VALORES CONSTANTES PARAMETER 3.6 DECLARAO DATA 3.7 OPERADORES E EXPRESSES ARITMTI CAS E LGICAS 3.8 OPERADOR DE CONCATENAO E SUBSTRINGS 3.9 FUNES PARA CADEIAS DE CARACTERES 3.10 HIERARQUIA DOS OPERADORES 3.11 ATRIBUTOS DE UMA VARIVEL

....................... ....................... ....................... ....................... ....................... ....................... ....................... ....................... ....................... ....................... .......................

13 14 17 21 22 22 23 24 25 26 27

4 - COMANDOS BSICOS E ESTRUTURAS DE CONTROLE DE EXECUO 4.1 STOP 4.2 END 4.3 PAUSE 4.4 GO TO 4.5 IF 4.6 SELECT CASE 4.7 DO LOOP

....................... ....................... ....................... ....................... ....................... ....................... .......................

28 28 29 29 30 32 33

5 5.1 5.2 5.3 5.4 5.5

ARRAYS DIMENSION SIMPLIFICAO NA ESCRITA E UTILIZAO DE ARRAYS FORTRAN90 LEITURA E GRAVAO DE ELEMENTOS DO ARRAY DO IMPLCITO WHERE SIMPLIFICANDO AS OPERAES COM ARRAYS - FUNES INTRNSECAS PARA MATRIZES E VETORES - FORTRAN90

....................... ....................... ....................... ....................... ....................... .......................

38 40 43 44 46 48

6 - USER-DEFINED DATA TYPE TIPOS DERIVADOS

7 7.1 7.2 7.3 7.4

LEITURA E GRAVAO DE DADOS F ILES READ, WRITE, PRINT FORMATAO PARA LEITURA DE DADOS FORMATAO PARA GRAVAO DE DADOS LEITURA E GRAVAO DE DADOS EM ARQUIVOS

....................... ....................... ....................... .......................

52 55 58 61

8 8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 8.9

SUBPROGRAMAO FUNES INTRNSECAS FUNO DECLARAO FORTRAN77 FUNES EXTERNAS SUBROTINAS EXTERNAS SUBPROGRAMAS INTERNOS MDULOS COMPARTILHANDO DADOS COM SUBPROGRAMAS - PASSANDO ARRAYS PARA SUBPROGRAMAS PERMISSES DE ACESSO PARA PARMETROS PASSADOS PARA MDULOS E SUB -PROGRAMAS 8.10 RECURSIVE FUNCTIONS-RECURSIVIDADE EM SUB ROTINAS E FUNES - FORTRAN90

....................... ....................... ....................... ....................... ....................... ....................... ....................... ....................... ....................... .......................

65 68 69 70 71 73 76 78 82 85

9 9.1 9.2 9.3 9.4

ESTRUTURAS DINAMICAS DE DADOS ARRAYS E POINTERS - ARRAYS ALOCVEIS ( ALLOCATABLE ARRAYS ) POINTERS ESTRUTURAS DINAMICAS DE DADOS LISTAS LINKADAS AUTOMATIC ARRAYS

....................... ....................... ....................... .......................

87 89 93 94

10 10.1 10.2 10.3

MIXED LANGUAGE PROGRAMMING VISUAL BASIC X FORTRAN90 EXEMPLO FORTRAN90 X C EXEMPLO DELPHI X FORTRAN90 EXEMPLO

....................... ....................... ....................... .......................

95 96 97 101

11 REFERENCIAS

Programao em FORTRAN77/FORTRAN 90
1.1 - O compilador Fortran 90
O Fortran (FORmula TRANslation) teve a sua primeira verso desenvolvida entre 1954 e 1957, sendo considerada a mais antiga linguagem de programao destinada computao cientfica. Antes deste perodo, os cdigos eram executados em linguagem de mquina. Foi inicialmente desenvolvido para executar em um computador IBM Type704, e j em 1958 , mais da metade dos cdigos utilizados naquele computador estavam escritos na linguagem FORTRAN. Tal popularidade fez com que grupos diferentes comeassem a escrever os seus prprios compiladores - em 1962 surgiu a verso FORTRAN IV. Para contornar o problema da portabilidade, a linguagem foi oficialmente padronizada em 1966, sob responsabilidade do American National Standards Institute(ANSI) e denominada Fortran 66. A partir de 1977, o Fortran passou por grandes modificaes, surgindo em 1980 uma nova verso padronizada - o Fortran 77.

Paralelamente s modificaes decorrentes destas verses, foram surgindo novas linguagens com recursos de programao e conceitos mais modernos. Apesar disto, a comunidade cientfica continuou utilizando e adotando a linguagem para o desenvolvimento de cdigos, especialmente por possuir algumas caractersticas: Linguagem de programao de fcil codificao Grande potencial para clculos, devido disponibilidade de um grande nmero de funes intrnsecas, operaes e representaes de dados Boa interface com bibliotecas (matemticas e estatsticas) externas amplamente utilizadas em aplicaes cientficas Surgimento de implementaes destinadas otimizao do cdigo Dificuldade de migrao de milhes de linhas de cdigo implementadas originariamente em Fortran, para uma outra linguagem

Apesar de seu uso intensivo durante as dcadas seguintes sua padronizao e j englobando conceitos mais modernos de programao do que as suas verses anteriores, o Fortran 77 ainda continuava defasado, quando comparado s modernas linguagens de programao recm-criadas. Alguns exemplos da deficincia da linguagem podem ser citados: utilizao de formato fixo na codificao dos programas; inexistncia de estruturas para acesso dinmico aos dados; problemas relacionados com a portabilidade numrica; ausncia de recursividade; problemas na manipulao de dados globais, dentre outros. Com o intuito de eliminar tais restries, foram introduzidas grandes modificaes surgindo o Fortran 90, padronizado em 1993. O Fortran 90 considerado um superset do Fortran 77, mantendo todas as estruturas anteriores da linguagem. Desta forma, programas escritos em Fortran 77 podem ser submetidos ao compilador do Fortran 90, muito embora, vrios comandos sejam considerados obsoletos, sendo desaconselhado o seu uso em novos programas.

Caractersticas do Fortran90
Cdigo Fonte em Formato livre Tipos de Dados Parametrizados (KIND) Derived Types Otimizao de Arrays Pointers Alocao Dinmica de Memria Otimizao de Subprogramas Mdulos Novas Procedures Intrnsecas

Compiladores FORTRAN 90/95


O Fortran 90, assim como o C e o C++ so as linguagens mais utilizadas nos sistemas de work-stations e em mquinas destinadas Computao de alto desempenho em geral. Tambm existem verses para micro-computadores, disponveis para todos os sistemas operacionais.

Para mquinas destinadas a computao de alto desempenho, existe verses Fortran HPF (High Performance Fortran) , prprias para a execuo do cdigo em paralelo e outras otimizaes relacionadas com a computao intensiva. Para sistemas LINUX, pode-se citar os compiladores Lahey Fortran, Intel, AbSoft Fortran, g95, dentre outros. Para os sistemas da Microsoft, o Fortran PowerStation foi bastante difundido, existindo at a verso 4. Posteriormente, a verso da Compaq (Compaq Visual Fortran) tambm preservava o mesmo ambiente de programao. Atualmente, o compilador Fortran Intel a nova denominao para o antigo MS Fortran PowerStation, posteriormente denominado COMPAQ Fortran. O Fortran 90 tambm faz parte do conjunto de linguagens de Programao do Visual Studio .NET. As verses do compilador para os sistemas Microsoft so bastante amigveis, oferecendo um ambiente de programao integrando as fases de edio, compilao, debug e execuo do programa.

1.2 - Bibliotecas Numricas, Estatsticas e para Paralelizao de Algoritmos

IMSL Fortran Library - Biblioteca de rotinas matemticas e estatsticas integrada ao


compilador Fortran 90

NAG Numerical Libraries for Fortran 90 Users Numerical Recipes - Fontes de Algortmos Numricos de domnio pblico
disponveis no mdulo Numerical Recipes

OpenMP

OpenMP API User's Guide Multiprocessamento/Paralelizao de Algoritmos

Diretivas

para

1.3 GNUPLOT - Software de visualizao


Vrios aplicativos de visualizao podeM ser utilizados para visualizao dos arquivos de dados gerados pelos cdigos Fortran90, seja em formato ASCII ou binrio. Alguns aplicativos podem ser integrados aos cdigos de processamento, gerando grficos de forma interativa. Um exemplo de aplicativo freeware para visualizao de grficos e superfcies o GNUPLOT.

GNUPLOT
O Aplicativo gnuplot utilizado para visualizao de grficos e superfcies, comuns nas aplicaes cientficas. Este aplicativo de domnio pblico, tendo verses para diversos sistemas operacionais tais como Unix, Linux, Windows, etc. O GNUPLOT pode ser utilizado para traar curvas (2 dimenses) e superfcies (3 dimenses). Em 3D, as funes podem ser plotadas na forma de malha, superfcies em trs coordenadas ou isolinhas no plano x-y. Em 2D, h muitas opes incluindo linhas, pontos, grficos de barras, etc. Pode-se utilizar ttulos para o grfico e para os eixos, data/hora, legendas, etc.

Formas de utilizao do gnuplot


1) Linhas de comandos do aplicativo 2) Criao de scripts contendo comandos. O script executado dentro do aplicativo, a travs do comando load 3) O Script contendo os comandos do gnuplot poder ser executado dinamicamente dentro de um programa Fortran90 4) Uso de bibliotecas contendo funes do gnuplot. Utilizadas na linguagem C.

2 - Estrutura da Linguagem
2.1 - Escrevendo o cdigo fonte
O formato padro para a escrita de novos cdigos em Fortran90 o formato livre, ou seja, sem alinhamentos especficos por colunas conforme ser visto a seguir. No entanto, programas em formato fixo (alinhados em colunas especficas) escritos de acordo com a sintaxe das verses anteriores da linguagem, tambm sero compilados. O tipo de formatao que estiver sendo usado, dever ser especificada para o compilador atravs da extenso do nome do programa. Programas escritos em formato livre devero ter uma das extenses: .f90, .F90, .f95 ou F95. Programas escritos em formato fixo, devero ter a extenso .f, .F, .for ou .FOR O compilador tambm aceita fontes com a extenso .f03 or .F03. Eles so tratados de forma equivalente a .f95 e .F95 e poderia ser utilizado para indicar que o fonte contm extenses do Fortran 95 (verso FORTRAN 2003).

Elementos da Linguagem
O FORTRAN utiliza como caracteres bsicos as letras A-Z ( no case-sensitive ) e os dgitos 0-9; como caracteres especiais podem ser utilizados: + - / * , = . ( ) $ :

FORMATO FIXO Tamanho da linha do cdigo e linhas de continuao


Um programa em formato fixo dever ser escrito em linhas de no mximo 80 colunas. Um comando ou conjunto de comandos (ou expresses) em Fortran pode ocupar uma ou mais linhas. So consideradas linhas de continuao, aquelas que contm qualquer caracter diferente de branco na coluna 6. No FORTRAN 77, pode-se ter at 19 linhas de continuao.

Comentrios
As linhas de comentrio so utilizadas para documentao do programa. Qualquer caracter (em geral, * ou C) colocado na primeira coluna, ir caracterizar a linha como comentrio sendo portanto, ignorada pelo compilador. Tambm pode-se comentar uma linha de comando; neste caso, utilizar o caracter !, aps o comando e precedendo o comentrio.

Rtulos (labels)
Usados para identificar uma linha de comando ou formato, a ser referenciado posteriormente. Corresponde a um valor numrico (1-99999) digitado nas cinco colunas iniciais.

Texto
Representa o programa propriamente dito. Aqui, texto refere-se s declaraes e os comandos da linguagem Fortran. O texto deve ser escrito entre as colunas 7 e 72. Qualquer texto digitado aps a 72 coluna, ser ignorado. O texto no case-sensitive, podendo ser utilizadas letras maisculas e minsculas, tendo o mesmo significado.

FORMATO LIVRE Tamanho da linha do cdigo e linhas de continuao


Cada linha do programa-fonte pode ter at 132 caracteres. Uma linha de continuao identificada atravs do caracter '&' digitado ao final da linha anterior. No formato livre pode-se ter normalmente at 39 linhas de continuao.

Exemplo:
format (/A area de , f4.1, por , f4.1, & do retangulo , f6.2 )

Comentrios
! Exemplo de utilizao de comentarios em FORTRAN 90 temp = x ! uso de comentario apos comando

Rtulos (labels)
No formato livre, qualquer . (colocar tbem quando nao numero...) read(5,100) a, b ; 100 format (i5, a10)

Texto
Os comandos podem iniciar a partir de qualquer coluna. No FORTRAN 90, pode-se ter vrios comandos na mesma linha, separados pelo caracter ';' .

Exemplo:
if ( I = = 1) then; I =2; else if (I >= 2)then; I = 1; endif

Different Fortran standards


Properties Whole Fortran 66 Whole Fortran 77 Whole Fortran 90 Whole Fortran 95 Continuation line indicated in column 6 on the next line Continuation line indicated with & at the end of the present line Blank line as comment Significant blanks Generic functions User-defined generic functions REAL*8 Comment symbol Extension in Unix Extension in DOS Fortran 66 Fortran 77 Fortran 90 Fortran 95 Fixed form Fixed form Fixed Free (Fixed) Free = + -2 = + -2 = = -14 + -2 = = -14 -5 -5 -5 = + -5 -5 -5 = -

C .f .FOR

+ + C * .f .FOR

+ + + C * ! .f .FOR

+ + + + + ! .F90 .F90

+ + + C * ! .f .FOR

+ + + + + ! .F90 .F90

Fonte: http://www.nsc.liu.se/~boein/FORTRAN 77to90

Na Tabela acima, -2 na posio Whole Fortran 66 / Fortran 90 significa que duas propriedades desapareceram na transio do Fortran66 para o Fortran90. Isto aplica-se tanto ao formato fixo quanto ao formato livre. Nas primeiras quarto linhas, o sinal = indica que nada foi modificado; j o sinal -, indica que vrias propriedades esto faltando. Nas sete linhas seguintes, um sinal + indica que a propriedades est presente; o sinal indica propriedade ausente. O uso do Formato fixo desencorajado no Fortran 95. REAL*8 uma variante da declarao DOUBLE PRECISION, introduzida pela IBM e usada pela Digital. Existem vrias outras formas de declarao. recomendado o uso do smbolo ! para indicar linhas de comentrio; este smbolo tambm vlido nas implementaes do Fortran77. No UNIX, no h extenses da linguagem. As extenses no fazem parte do Fortran Standard, sendo de responsabilidade de desenvolvedores especficos.

2.2 - Usando o compilador Fortran no LINUX


A seguir dada uma breve descrio de como utilizar o compilador e executar cdigos desenvolvidos em Fortran90. O primeiro passo utilizar um editor (vi, emacs, etc..) para criar o arquivo-fonte, lembrando que tal arquivo dever ter uma das extenses : .f, .for, .f90, .f95, .F, .F90, ou .F95 .

Exemplo O programa a seguir mostra uma mensagem na tela


demo% cat exemplo.f PROGRAM EXEMPLO PRINT *, 'Programming in Fortran 90 Simple Code Example!' END demo% g95 exemplo.f demo% a.out Programming in Fortran 90 Simple Code Example! demo%

10

No exemplo acima, o g95 compila o cdigo fonte exemplo.f , faz os links necessrios e produz o executvel a.out, por default. Para executar o programa, o nome do arquivo executvel, a.out, dever digitado na linha de comandos. Tradicionalmente, os compiladores UNIX/LINUX escrevem a sada dos arquivos executveis em a.out. Para especificar um nome diferente para o arquivo executvel, utilize a opo de compilao o:

Exemplo
demo% g95 exemplo.f o exemplo demo% exemplo a.out tambm poder ser renomeado posteriormente atravs do comando mv. A seguir, um exemplo de compilao de dois cdigos contidos em diferentes arquivos (inclusive, em formatos diferentes vide extenso), produzindo um executvel chamado heat; a opo g ativa o debug de erros durante a execuo.

Exemplo
demo% f95 -g -o heat heat.f fft.f95 A seguir, a compilao e gerao de executvel com programa principal em Fortran e subrotina em C. A compilao feita em separado, gerando os cdigos-objeto relacionados com cada unidade de programa. Depois feita a link-edio entre os objetos, gerando o cdigo executvel.

Exemplo 1
demo% f95 -c -fast sbr.f demo% cc -c -fast simm.c demo% f95 -fast sbr.o simm.o

Exemplo 2
Utilizando o exemplo anterior, se forem utilizadas opes de compilao, elas devero ser aplicadas na gerao de todos os objetos em separado, assim como na fase de link. demo% f95 -c -fast sbr.f demo% cc -c -fast simm.c demo% f95 -fast sbr.o simm.o link step; passes -fast to th e linker

11

3. Elementos de Programao
3.1 - Tipos de Dados e variveis
Tipos de Dados
Inteiros (INTEGER) Reais de preciso simples (REAL) Reais de preciso dupla (DOUBLE PRECISION*) Complexos (COMPLEX) Lgicos (LOGICAL) Caracteres (CHARACTER)

Nomes de Variveis
Variveis so nomes associados a tipos de dados. Os nomes (identificadores) de variveis, podem conter caracteres alfabticos, nmeros e o smbolo _, iniciando obrigatoriamente por um caracter alfabtico. Nomes de variveis podem ter at 31 caracteres (standard). O valor contido em uma varivel poder mudar no decorrer da execuo do programa, atravs de novas atribuies. So consideradas variveis simples, quelas com capacidade para armazenar apenas um valor. As variveis devero ser obrigatoriamente declaradas no incio do programa, antes de qualquer linha de comando.

Declarao de Variveis
Todas os tipos de variveis devem ser declaradas em Fortran antes de serem utilizadas, EXCETUANDO-SE as variveis reais de preciso simples e inteiras. Caso uma varivel real ou inteira no seja declarada, a primeira letra do nome do identificador ir indicar o tipo da mesma; isto porque o Fortran possui declaraes implcitas pr-

12

definidas, estabelecendo que todas as variveis iniciando com letras no intervalo I-N, so inteiras (caso no sejam declaradas) e as demais (ou seja, iniciando nos intervalos A-H, O-Z ) so reais de preciso simples.

3.2 - Implicit None (Fortran 90)


A declarao IMPLICIT NONE quando utilizada no incio do programa, obriga a declarao de todas as variveis que sero utilizadas no programa. Este recurso visa minimizar a ocorrncia de erros devido enganos na digitao de variveis e facilitar a documentao do programa. O uso desta declarao altamente recomendvel.

IMPLICIT (no recomendvel)


A no necessidade de declarao das variveis inteiras e reais, deve-se ao fato de j existir, internamente na linguagem, um IMPLICIT associado aos nomes das variveis reais e inteiras. Como exemplo, a declarao IMPLICIT REAL (A) , define que toda varivel existente no programa, iniciada com a letra A, ser automaticamente de tipo REAL.

Exemplos
IMPLICIT INTEGER (I-N) IMPLICIT DOUBLE PRECISION (A-H, O-Z) IMPLICIT CHARACTER*6 (R) IMPLICIT LOGICAL (L)

Exemplos de declaraes de variveis Valores Inteiros


INTEGER SOMA INTEGER TOT1, TOT2, INDICE

Atribuindo um valor
SOMA = 0

13

Valores Reais de preciso simples


REAL CONTA REAL X1, X2, TOTAL

Atribuindo um valor
CONTA = 1.0

Valores Reais de preciso dupla


REAL*8 VETOR1 DOUBLE PRECISION DP1, DP2, DP3 REAL(KIND=8) :: VAR1

Atribuindo um valor
VETOR1 = 10.D0 VETOR1 = 10.0

Observao: Prefira o uso do atributo KIND=8 ou REAL(8) para definir variveis em dupla preciso.

Nmeros Complexos
COMPLEX CP1 COMPLEX VCOMP1, VCOMP2 Atribuindo um valor: CP1 = (5.0,2.0)

equivalente a 5 + 2i

Valores Lgicos
LOGICAL FIM LOGICAL ACHOU, FLAG

Atribuindo um valor: FIM = .FALSE. FLAG = .TRUE.

14

Cadeia de Caracteres
CHARACTER(LEN=10) :: PALAVRA (Forma preferencial)

CHARACTER C1*3, C2 CHARACTER*8 ALFA, BETA*4, GAMMA

Ao utilizar a declarao de uma varivel na forma CHARACTER(LEN=N) ou CHARACTER*N, o valor N, correspondente ao tamanho da cadeia, no dever exceder a 255 caracteres.

Exemplo Como devem estar declaradas as variveis XIS, SOMA, TOTAL, VALOR,
CURSO, SUBLEN, FORMULA, COMP, TAM e SY, no incio do programa? XIS = .FALSE. SOMA = INT(15.2)+MOD(18,5) TOTAL = 19853 VALOR = 488.D0 CURSO = CURSO MESTRADO COPPE SUBLEN = C FORMULA = SQRT(XY) COMP = X.LT.5.OR.Y.GE.10.0 TAM=LEN(S) SY = SIN(A)+COS(B)

Primeiro Exemplo de Programa Formato Fixo


C FIXED FORM EXAMPLE READ ANGLE AND HYPOTENUSE; C CALCULATE THE LENGTHS OF SIDES A AND B C PROGRAM TRIANGLE REAL A, B, C, THETA WRITE (*,*) "ENTER THE LENGTH OF THE HYPHOTENUSE C:" READ(*,*) C C WRITE (*,*) "ENTER THE ANGLE THETA IN DEGREES:" READ(*,*) THETA A = C * COS(THETA) B = C * SIN(THETA) WRITE (*,*) "THE LENGTH OF THE ADJACENT SIDE IS: ", * A WRITE (*,*) "THE LENGTH OF THE OPPOSITE SIDE IS: ", B END

15

Primeiro Exemplo de Programa Formato Livre


PROGRAM TRIANGLE ! FREE FORM EXAMPLE READ ANGLE AND HYPOTENUSE; ! CALCULATE THE LENGTHS OF SIDES A AND B ! REAL A, B, C, THETA WRITE (*,*) "ENTER THE LENGTH OF THE HYPHOTENUSE C:" READ(*,*) C WRITE (*,*) "ENTER THE ANGLE THETA IN DEGREES:" READ(*,*) THETA A = C * COS(THETA) B = C * SIN(THETA) WRITE (*,*) "THE LENGTH OF THE ADJACENT SIDE IS: ", & A WRITE (*,*) "THE LENGTH OF THE OPPOSITE SIDE IS: ", B END

3.3 - KIND (FORTRAN 90)


Cada tipo de dado possui um ou mais valores de um atributo KIND associado a ele. Tipos de dados com diferentes valores KIND, usa um nmero diferente de bytes para armazenar informao. Isto significa que tipos de dados numricos com diferentes parmetros KIND tm intervalos distintos de possveis valores e/ou diferentes nveis de acurcia numrica. As variveis, utilizando o atributo KIND, podero ser declaradas da seguinte forma: REAL ( KIND = Y ) VALOR REAL ( KIND = X ) SIMPLES

KIND - Portabilidade do cdigo entre diferentes arquiteturas


A utilizao da declarao DOUBLE PRECISION pode gerar problemas de portabilidade do algoritmo entre mquinas com diferentes tamanhos de palavras Um exemplo so mquinas que necessitam de variveis em dupla preciso, obtida com 64 bits, migrando para um equipamento, cujo tamanho de palavra (preciso simples) j de 64 bits.

16

O uso do atributo KIND permite que a varivel se ajuste automaticamente arquitetura da mquina que est sendo utilizada. Desta forma, o atributo KIND proporciona independncia da arquitetura da mquina, sendo especialmente importante em programas que sero migrados de equipamento.

KIND para tipo REAL


Uma varivel de tipo REAL pode ser declarada como REAL ou DOUBLE PRECISION, ou ter seu intervalo e preciso especificado atravs do atributo KIND. Se o atributo KIND especificado, ele deve ter um dos seguintes valores:

Valores para PCs: Kind 4 (default) 8 Intervalo 2**-126 a 2**127 2**-1012 a 2**1023 Preciso 16 bits -6dgitos de preciso 32 bits -18dgitos de preciso

Valores para sistemas CRAY (arquitetura 64 bits): Kind 4 8 (default) 16 Intervalo 2**-8189 a 2**8190-1 2**-8189 a 2**8190-1 2**-8189 a 2**8190-1 Preciso 64 bits - 14 dgitos de preciso 64 bits - 14 dgitos de preciso 128 bits-29 dgitos de preciso

Exemplo
Deseja-se trabalhar com a varivel BIGVAR, em uma work-station de 32 bits; Esta varivel deve ter 14 dgitos de preciso. Sabe-se que aps, o programa ir rodar em uma mquina com palavra de 64 bits. Como deve ser feita a declarao desta varivel?

Possibilidade 1: double precision BIGVAR


Problema: Se o uso de dupla-preciso no for desabilitado na segunda mquina, a varivel ir requerer 128 bits (que corresponde dupla-preciso naquele equipamento), e os resultados podero no ser de acordo com o esperado; H ainda a possibilidade

17

de degradao de performance do algoritmo e utilizao excessiva de memria, desnecessariamente.

Possibilidade 2: real (kind=8) BIGVAR


Com esta opo, a varivel vai requerer duas palavras de memria (64 bits) na workstation, fornecendo 15 dgitos de preciso e ao migrar para a segunda mquina em questo, ir ajustar-se ao kind=8 daquele equipamento, que corresponde a sua preciso simples (64 bits) e 19 dgitos de preciso.

Kind para tipo INTEGER


No Fortran tradicional, os tipos de dados eram baseados em um modelo de memria onde um tipo real, integer ou logical era representado em uma unidade numrica de memria. Para os inteiros, a especificao do KIND representa o intervalo numrico de representao do dado. Valores para PCs: Kind 1 2 4(default) Intervalo +-127 +-32.767 +-2.147.483.647

Valores para sistemas CRAY: Kind 1 2 3 6(default) 8 Intervalo +- 2.147.483.647 +- 2.147.483.647 +- 2.147.483.647 +- 35.184.372.088.831 +- 9.223.372.036.854.775.807

18

Size Notation for Numeric Data Types Nonstandard


INTEGER*1

Declarator
INTEGER(KIND=1)

Short Form
INTEGER(1)

Meaning One-byte signed integers Two-byte signed integers Four-byte signed integers One-byte logicals Two-byte logicals Four-byte logicals IEEE single-precision fourbyte floating-point IEEE double-precision eightbyte floating-point IEEE quad-precision sixteenbyte floating-point Single-precision complex (four bytes each part) Double-precision complex (eight bytes each part)

INTEGER*2

INTEGER(KIND=2)

INTEGER(2)

INTEGER*4

INTEGER(KIND=4)

INTEGER(4)

LOGICAL*1

LOGICAL(KIND=1)

LOGICAL(1)

LOGICAL*2

LOGICAL(KIND=2)

LOGICAL(2)

LOGICAL*4

LOGICAL(KIND=4)

LOGICAL(4)

REAL*4

REAL(KIND=4)

REAL(4)

REAL*8

REAL(KIND=8)

REAL(8)

REAL*16

REAL(KIND=16)

REAL(16)

COMPLEX*8

COMPLEX(KIND=4)

COMPLEX(4)

COMPLEX*16

COMPLEX(KIND=8)

COMPLEX(8)

Fonte: http://docs.sun.com/source/819-3686/4_f95.html IEEE - Institute of Electrical and Electronics Engineers, Inc.

19

Exemplo Como feita a representao numrica para INTEGER


INTEGER (KIND=1) = NUM De acordo com as tabelas xx e yy, KIND=1 corresponde a inteiros assinalados, armazenados em 1 byte, tendo portanto representao numrica mxima de +127: 8 BITS +/1 1 1 1 1 1 1

26 =64

25 =32

24 =16

23 =8

22 =4

21 =2

20 =1

= + 127

3.4 - Aritmtica Inteira, Real e Mista


Em Fortran, no o operador aritmtico e sim a forma de representao do dado, que define o resultado da operao aritmtica. Inteira 3/5 13/4 Real 3.0/5.0 3./5. 13./4.0 Mista 3.0/5 13/4.0

0 3

0.6 0.6 3.25

0.6 3.25

Ateno! A converso automtica de tipo pode ocorrer quando o nome da varivel for de tipo diferente do resultado da expresso numrica.

Exemplo
NRES = 1.25 + 9 / 4 NRES um tipo inteiro enquanto o resultado da expresso real ( = 3.25 ). Este resultado automaticamente convertido para inteiro e NRES armazenar o valor 3.

20

3.5 - Valores Constantes - PARAMETER


Em Fortran, um valor considerado constante no decorrer da execuo do programa, representado por um identificador, assim como as variveis. O que determina a caracterstica constante do valor o comando no-executvel PARAMETER. Toda constante (PARAMETER) deve ser previamente declarada, independente do uso ou no, da declarao Implicit None.

Exemplo - FORTRAN 77
REAL DIMAT PARAMETER (DIMAT = 100)

Exemplo - FORTRAN 90
REAL, PARAMETER :: DIMAT = 100

3.6 - Declarao DATA (obsoleto)


Utilizado para inicializao de variveis. Os valores so associados s variveis na fase de compilao e no na fase de execuo do programa.

Exemplo 1 - Inicializao de uma varivel real


INTEGER ANGULO REAL RAD, PI, SENO DATA PI /3.1416/ ANGULO = 47 RAD = ANGULO* PI / 180. PRINT *, RAD END

Exemplo 2 - Inicializao de grupo de variveis reais


DATA PI, X, Y / 3.1415, 0.0, 1.2 /

Este comando deveria ser substitudo por:

REAL

::

PI=3.1415,

Y=0.0,

Y=1.2

21

3.7 Operadores e Expresses Aritmticas e Lgicas


Operadores Aritmticos
SMBOLO + / * ** OPERAO
SOMA SUBTRAO DIVISO MULTIPLICAO POTENCIAO

EXEMPLO
A+B X Y ALFA/BETA BETA*GAMMA A**B

Toda expresso aritmtica deve ser escrita na forma linear, observando-se a hierarquia das operaes.

Operadores Relacionais
Smbolo .EQ. .NE. .GT. .GE. .LT. .LE. Smbolo FORTRAN 90 (opcional) == /= > >= < <= Operao IGUAL DIFERENTE MAIOR QUE MAIOR OU IGUAL MENOR MENOR OU IGUAL

Operadores Lgicos
.AND. .OR. .NOT. .EQV. .NEQV.

Exemplo - combinao de operadores lgicos e relacionais


LOGICAL FIM FIM = ISOMA .GT. 100 .AND. ISOMA .LT. 1000
INTEGER)

(observe que ISOMA de tipo

22

3.8 - Operador de Concatenao e Substrings


Duas ou mais strings ou sub-strings podem ser combinadas para a formao de uma nica string (cadeia de caracteres). Esta operao denominada concatenao.

Exemplo 1
Concatenao de strings de caracteres: AB // CD O resultado da operao acima uma string: ABCD

Exemplo 2
Operaes com strings definio de sub-string

Dada a string C: C = ABCDEFG

Pode-se extrair sub-strings da seguinte forma: C(3:7) C(:3) C(5:) CDEFG ABC EFG

Observao: A primeira expresso inteira define o primeiro caracter que ir compor a substring; a segunda expresso inteira define o ltimo caracter da substring.

Exemplo 3
Concatenao e sub-strings

PROGRAM TEST CHARACTER(LEN=10) :: A CHARACTER(LEN=8) :: B, C A = ABCDEFGHIJ B = 12345678 C = A(1:3) // B(4:5) // A(6:8) PRINT ((A)) C END PROGRAM

23

Valor Impresso: ABC45FGH

3.9 - Funes para Cadeias de Caracteres


ADJUSTL(STRING) Ajusta a string esquerda ADJUSTR(STRING) Ajusta a string direita INDEX(STRING, SUBSTRING, Retorna a posio onde inicia a back) substring, dentro da string. Se BACK = true, ser retornada a posio da ltima substring, se for false, retorna a posio da primeira. LEN_TRIM(STRING) Retorna o tamanho da string, sem caracteres brancos no inicio ou final da mesma. LGE(STRING_A, LGT(STRING-A, LLE(STRING_A, LLT(STRING_A, STRING_B) STRING_B) STRING_B) STRING_B) As rotinas acima, comparam duas strings, utilizando a ordenao de caracteres da tabela ASCII. Se uma string for mais curta do que a outra, sero adicionados brancos ao final, para que tenham o mesmo tamanho.

REPEAT(STRING, NCOPIES) Concatena a string NCOPIES vezes, gerando uma nova cadeia de caracteres TRIM(STRING) Retorna a string sem os espaos em branco no significativos (antes do incio, ou depois do final da string). Retorna o tamanho da string de caracteres.

LEN(STRING)

24

3.10 - Hierarquia dos Operadores


Operaes com parnteses, iniciando pelos parnteses mais internos Clculo de Funes Operaes com exponeciais, iniciando da esquerda para a direita Operaes de multiplicao e diviso, iniciando da esquerda para a direita Operaes de adio e subtrao, iniciando da esquerda para a direita Operadores relacionais (==, /=, >, >=, <, <=), iniciando da esquerda para a direita Concatenao Operadores .NOT. Operadores .AND. iniciando da esquerda para a direita Operadores .OR. iniciando da esquerda para a direita Operadores .EQV. e .NEQV., iniciando da esquerda para a direita Sempre em caso de igualdade de hierarquia, resolve-se a expresso da esquerda para a direita; para quebrar a hierarquia, faa uso dos parnteses. O uso de parnteses para indicar a ordem das operaes altamente recomendvel. Em caso de igualdade de hierarquia, resolve-se a expresso da esquerda para a direita; para quebrar a hierarquia, faa uso dos parnteses. O uso de parnteses para indicar a ordem das operaes altamente recomendvel.

Exemplo
X + 1 / X 1 difere de : ( X + 1 ) / ( X 1 )

25

3.11 - Atributos de uma varivel


Observao: As diversas especificaes para uma varivel, podem ser declaradas em uma mesma linha. Para isto, utilize o smbolo '::'

Exemplo 1

(FORTRAN 77)
REAL A, B, C PARAMETER ( A = 3.141592654 ) DIMENSION B(3) DATA B/1.0, 2.0, 3.0/ DIMENSION C(100) DATA C/100*0.0/

As linhas acima, escritas em FORTRAN 90, ficariam de uma forma mais resumida:
REAL, PARAMETER REAL REAL :: :: :: A B(3) C(1:100) = 3.141592654 = (/1.0,2.0,3.0/) = 0.0

Exemplo 2

(FORTRAN 90)
REAL, DIMENSION(3), PARAMETER :: a = (/10.0, 0.0, 0.0/ ), b=(/1.0, 1.0, 1.0/) COMPLEX, DIMENSION(10) :: &

vortex

26

4. Comandos Bsicos e Estruturas de Controle de Execuo


STOP END PAUSE GO TO IF IF...ELSE...ENDIF DO ... ENDDO DO WHILE... ENDDO SELECT...CASE CYCLE EXIT

4.1 - STOP (obsoleto)


O comando STOP encerra a execuo do programa. Embora pouco utilizado, comum ser visto em programas mais antigos, com a funo de por exemplo, separar o bloco de comandos executveis dos no-executveis (exemplo: comandos executveis de bloco de linhas de formato).

Exemplos

STOP STOP 99 STOP final de programa


Quando o comando STOP executado, o contedo do rtulo ou da string ser exibido no terminal, se o processamento for interativo.

4.2 - END
O comando END indica para o compilador o final de uma unidade de programa, devendo ser portanto, o ltimo comando a ser executado. O seu uso obrigatrio no final de cada unidade de programa, ou seja, programa principal, sub-programa ou mdulo.

27

4.3 PAUSE (obsoleto)


O comando PAUSE suspende temporariamente a execuo de um programa, aguardando que qualquer tecla seja ativada, para que seja dada sequncia ao processamento. Opcionalmente exibe mens agem no terminal do programador.

4.4 GO TO (no recomendvel)


Este considerado um comando de desvio, possibilitando a alterao do fluxo seqencial do cdigo; o seu uso no entanto, altamente desaconselhvel na programao atual. O conhecimento de tais estruturas dever apenas contribuir para a compreenso de cdigos antigos.

GO TO incondicional
O fluxo do programa desviado imediatamente para o rtulo especificado

GO TO 10 .... .... .... 10 ! linhas de comandos A=A+1

GO TO computado (no recomendvel)


Dada uma lista de m rtulos, e uma expresso aritmtica de valor N, o programa desviado para o n -simo rtulo da lista. Caso N seja menor ou igual a zero, ou maior que m, o programa seguir para o comando seguinte, no fazendo desvio para nenhum dos rtulos. Este comando dever ser substitudo pelo select...case.

Exemplo 1
GO TO (10, 11, 15, 30) J/10
No exemplo, se J/10 tem valor 1, o programa transferido para o primeiro rtulo da lista (10); se J/10 tem valor 3, o programa transferido para o terceiro rtulo da lista (15)

Exemplo 2
GO TO (100, 200, 300) LMN
No exemplo, se LMN tem valor 2, o programa transferido para o segundo rtulo da lista (200); se LMN tem valor 0 ou 4 por exemplo, o programa continua a execuo na prxima linha de comando, sem fazer desvio.

28

4.5 - IF (comando condicional)


Utilizado para testar uma expresso lgica e tomar decises baseadas nos resultados. Existem trs possibilidades para o comando IF:

1. 2. 3.

IF lgico IF aritmtico IF bloco (estruturado)

IF lgico
Permite que se execute ou no um comando, dependendo do resultado da expresso lgica.

Exemplos
IF ( A .GT. 1.0 ) A = 0.0 IF ( I .EQ. 0 .AND. K .GT. 5 ) X = X + 1 IF ( Z3 .LE. 10 ) GO TO ( 10, 20, 30 ) Z2

IF aritmtico (obsoleto)
um desvio com trs sadas. O programa escolher uma delas a partir do resultado de uma expresso aritmtica.

Exemplo:
IF ( K*3 A/9) 10, 20, 30 ... 20 ... 10 ... 30 No exemplo acima, se: expresso aritmtica < 0 desvio para rtulo 10 expresso aritmtica = 0 desvio para rtulo 20 expresso aritmtica > 0 desvio para rtulo 30

IF bloco
Serve para a execuo de um bloco de comandos a partir de uma expresso lgica. Neste caso, o comando IF dever ser usado em conjunto com o comando ENDIF (ou END IF) e opcionalmente, com os comandos ELSE ou ELSE IF para formar a estrutura.

29

Comandos: IF ... THEN ELSE ELSE IF ..... THEN END IF

Exemplo 1
IF ( B .GT. C ) THEN A = A + 1 C = 0 ENDIF

Exemplo 2
IF ( B A C ELSE A B ENDIF .GT. C ) THEN = A + 1 = 0 = A 1 = 10

Exemplo 3
IF ( B .GT. C ) THEN A = A + 1 C = 0 ELSE IF (C .EQ. A) THEN A = A 1 B = 10 ENDIF

Exemplo 4
Dada a Tabela:
95 < grade 86 < grade < 95 76 < grade <= 86 66 < grade <= 76 0 < grade <= 66 A B C D F

30

A estrutura em Fortran 90 para avaliar em qual intervalo encontra-se um valor numrico e imprimir a letra correspondente poderia ser escrita da seguinte forma: ,

IF ( grade > 95.) THEN write(*,*) The grade is A. ELSE IF ( grade > 86.) THEN write(*,*) The grade is B. ELSE IF ( grade > 76.) THEN write(*,*) The grade is C. ELSE IF ( grade > 66.) THEN write(*,*) The grade is D. ELSE write(*,*) The grade is F.
END IF

4.6 - SELECT . CASE (FORTRAN 90)


Este comando pode substituir um conjunto de ifs e go tos. No entanto, ele s aplicvel variveis de tipo INTEGER e CHARACTER.

Exemplo 1
integer IVAR SELECT CASE (IVAR) CASE (:1) ! todos os numeros negativos print *, Numero Negativo CASE (0) ! ivar = 0 print *, Zero CASE (1:9) ! numero de um digito print *, Digito, IVAR CASE (10:99) numero de dois digitos print *, Numero , IVAR CASE DEFAULT ! todos os casos restantes print *, Numero muito grande END SELECT

31

Exemplo 2
CHARACTER*10 COR COR = 'VERDE' SELECT CASE (COR) CASE ('VERMELHO') Stop CASE ('AMARELO') call aguarde CASE ('VERDE') call siga END SELECT

4.7 - DO (LOOP) Repetio de Trechos do cdigo


Os LOOPS so estruturas que permitem a execuo de uma seqncia de declaraes por vrias vezes. As duas formas bsicas de LOOPS so as construes WHILE e os Loops Iterativos , sendo que a principal diferena entre eles em como a repetio controlada. No caso de Loops iterativos, a varivel de controle no pode ser alterada no interior do loop.

DO
Cdigos antigos normalmente utilizam a instruo no executvel CONTINUE como limite do comando DO. Atualmente, seu uso no recomendvel. N_FACTORIAL = 1 DO 10 I = 1, N N_FACTORIAL = N_FACTORIAL * I 10 CONTINUE em formato Fixo: N_FACTORIAL = 1 DO 10 I = 1, N N_FACTORIAL = N_FACTORIAL * I CONTINUE

10

32

Exemplo 2
Mesmo comando do exemplo 1. Prefira o uso do enddo como delimitador do trecho de loop. N_FACTORIAL = 1 DO I = 1, N N_FACTORIAL = N_FACTORIAL * I ENDDO

Exemplo 3
Nas verses antigas do Fortran, era comum o uso de variveis de tipo REAL como contadores, conforme exemplo abaixo no entanto, o seu uso em cdigos atuais desaconselhado. Esta estrutura ser descontinuada nas prximas verses da linguagem. H = 0.1 DO X = 4.0, 7.9, H Y = 3 * X ** 2 4 * X + 2 AREA = AREA + Y * H ENDDO

Exemplo 4
DO 20 I=1, 10, 2 .... DO 10 J=1, N .... ... 10 CONTINUE CONTINUE

20

Exemplo 5
DO I = 10, 1, -1 .... WRITE(*,*)X*I .... ENDDO

Pergunta: No exemplo anterior, qual o valor final da varivel I ?

33

DO While Loop condicional


Ao invs de executar o lao n vezes, conforme foi visto no comando DO anterior, a utilizao do DO WHILE faz com que o trecho seja executado enquanto a expresso lgica especificada for verdadeira a expresso avaliada a cada iterao do loop.

Exemplo
I = 1 DO WHILE ( I <= 15 ) AMAX (I) = SQRT(I) I = I + 1 ENDDO

While Loop (FORTRAN 90)


DO IF (expresso_logica) EXIT ENDDO Devido no existncia de uma varivel de controle para encerrar a repetio aps um nmero finito de vezes, necessrio estabelecer uma condio para por fim ao loop. Desta forma, o do loop infinito pode ser interrompido atravs do comando EXIT , combinado com a verificao de alguma condio de trmino (comando IF).

Exemplo 1
DO INDEX = A * SQRT(B) IF ( INDEX < 0 ) EXIT IF ( INDEX == 0 ) CYCLE ... ENDDO

DECLARAES CYCLE e EXIT


CYCLE e EXIT so duas declaraes adicionais que podem ser utilizadas para controle de operao de DO LOOPS.

34

CYCLE
O comando CYCLE dentro de uma declarao DO ou DO WHILE faz com que os comandos subsequentes dentro do loop sejam ignorados, passando direto para uma prxima iterao.

Exemplo
PROGRAM TESTE_CYCLE INTEGER :: I DO I = 1, 5 IF (I == 3) CYCLE WRITE (*,*) I END DO WRITE (*,*) FINAL DO LOOP! END PROGRAM

Resultado
%> teste_cycle 1 2 4 5 FINAL DO LOOP!

EXIT
O comando EXIT termina a execuo de uma construo DO ou DO WHILE, antes de completar as demais iteraes. PROGRAM TESTE_EXIT INTEGER :: I DO I = 1, 5 IF (I == 3) CYCLE WRITE (*,*) I END DO WRITE (*,*) FINAL DO LOOP! END PROGRAM

Resultado
%> teste_exit 1 2 FINAL DO LOOP!

35

Exemplo CYCLE e EXIT no mesmo trecho


SOMA XX: DO I X YY: DO 0.0 1, 10 TAB(I) = 1, 20 IF ( X > TAB(J)) CYCLE XX X = X + TAB(J) ENDDO YY SOMA = SOMA + X IF ( SOMA >= 17.0 ) EXIT XX END DO XX = = = J

36

5 ARRAYS e TIPOS DERIVADOS


Variveis Indexadas - ARRAYS
Um array corresponde a um grupo de valores, todos de mesmo tipo e identificados pelo mesmo nome. Cada valor individual denominado elemento do array, e deve ser acessado atravs de ndice(s). O nmero de ndices para a identificao de cada elemento corresponde ao nmero de dimenses do array. Em FORTRAN, um array pode conter at sete dimenses. Os elementos de um array ocupam posies contguas na memria. Ao contrrio de outras linguagens, o FORTRAN armazena os elementos do array de acordo com a disposio dos dados em colunas. Como exemplo, considere o array NUMEROS, inicializado com valores: INTEGER, DIMENSION(3,3) :: NUMEROS = (/1,4,7,2,5,8,3,6,9/) Ao imprimir a estrutura do array NUMEROS j preenchido com os valores, os dados estaro dispostos da seguinte forma: 1 2 4 5 NUMEROS = 7 8 3 6 9

O acesso (leitura, gravao, atribuio de valores, clculos) ao conjunto de valores de uma varivel indexada, normalmente feito atravs de comandos de repetio, tal como o DO...END DO.

5.1 - Dimension
Exemplo 1
INTEGER A REAL B DIMENSION A(0:10), B(5,5)
Primeiro elemento de A: A(0) Primeiro elemento de B: B(1,1)

37

Exemplo 2
Dimensionamento automtico de VET

INTEGER I, VET(10) REAL(8) MAT (3,5),

X (6)

Exemplo 3
Leitura de valores para a varivel indexada VET(10)

DO I=1,10 READ(*,*) VET(I) ENDDO

Exemplo 1
PROGRAM SQUARES IMPLICIT NONE INTEGER :: I INTEGER, DIMENSION(10) :: NUMBER, SQUARE ! INITIALIZE NUMBER AND CALCULATE SQUARE DO I=1, 10 NUMBER(I) = I ! INITIALIZE NUMBER SQUARE(I) = NUMBER(I)**2 ! CALCULATE SQUARE END DO ! WRITE OUT THE NUMBER AND ITS SQUARE DO I = 1, 10 WRITE(*,100) NUMBER(I), SQUARE(I) END DO 100 FORMAT (1X, Number = , i6, Square = , i6) END PROGRAM

38

5.2 - Simplificao na escrita e na utilizao de Arrays


Uma das mais importantes caractersticas na evoluo do FORTRAN 77 para o FORTRAN 90 a simplificao nas operaes com arrays. O FORTRAN 90 permite que quase todas as operaes que eram anteriormente aplicadas a elementos individuais do array, sejam agora aplicadas ao array inteiro, ou a sees dele. Como isto, no FORTRAN 90 os valores podero ser atribudos aos arrays de uma forma bastante concisa. Isto oferece como vantagens: simplicidade e reduo da escrita do programa-fonte, facilitando o desenvolvimento e a manuteno de aplicaes maior eficincia (otimizao) do cdigo a ser executado em mquinas vetoriais e paralelas Como exemplo, considere A, B, C como arrays de mesmas dimenses. A operao para armazenamento da soma de A e B no array C, era antes escrito da forma: DO I=1, 100 DO J=1,50 C(I,J) = A(I,J) + B(I,J) ENDDO ENDDO Utilizando o FORTRAN 90, a mesma operao poder ser escrita simplesmente na forma C=A+B. A operao C = A + B, pode ser realizada sendo C, A, B, arrays de mesmo formato. A possibilidade de utilizao de um array como se fosse um escalar, facilita as operaes de pesquisa, paralelizao de algortmos, alm de reduzir o tamanho do programa-fonte. Alm disso, esta implementao internamente mais otimizada pelo compilador e oferece melhor desempenho na computao em mquinas vetoriais e paralelas. Outras implementaes que facilitam a manipulao de conjuntos de dados so os tipos derivados e a alocao dinmica de arrays, permitindo a alocao de memria durante a execuo do programa. Alm disso, funes podem retornar um array . Muitas funes intrnsecas funcionam independente de o argumento passado ser um escalar, vetor ou array multi-dimensional. As funes intrnsecas que realizam operaes sobre arrays eliminam a necessidade de do-loops . De acordo com o exemplo a seguir, o argumento angles pode ser uma varivel escalar ou um array; o resultado ser na estrutura correspondente: print *, sin(angles)

39

Mais exemplos de atribuio de valores a um Array em FORTRAN 90: Exemplo 1 FORTRAN 77


REAL SUMS DIMENSION SUMS(2,3) DO J = 1, 3 DO I = 1, 2 SUMS(I, J) = 0.0 ENDDO ENDDO

FORTRAN 90
REAL DIMENSION(2,3) :: SUMS = 0.0

Exemplo 2
Um array pode ainda ser referenciado como se fosse um escalar.

REAL, DIMENSION(3) :: ARRAY = 0.0

Exemplo 3
Os valores podem ser atribudos como listas simples.

REAL, DIMENSION(3) :: ARRAY = ( / 2.0, 4.0, 6.0 /)

Exemplo 4
Os valores podem ser atribudos na forma de construes utilizadas normalmente em comandos DATA, READ e WRITE.

REAL, DIMENSION(3) :: ARRAY = ( / (2 * I, I=1,3 )/)

Exemplo 5
Os valores podem ser atribudos na forma de um do-loop implcito.

REAL, DIMENSION(3) :: ARRAY = ( /(I, I= 2, 6, 2)/) Observe nos exemplos mostrados, que as atribuies de valores para elementos especficos do array so sempre delimitadas por (/ e /). Quais os valores contidos em array aps as declaraes a seguir? REAL, DIMENSION(3) :: ARRAY = (/(I, I=2,6,2)/) ARRAY = ARRAY 1.0

40

Exemplo 6 - Sintaxe FORTRAN 77 versus FORTRAN 90


REAL REAL, DIMENSION :: :: A(10), B(10), C(5) X

(5,5)

Os comandos da primeira e segunda coluna so equivalentes: DO I=1,10 A(I) = B(I) END DO

A = B

C = A(3:7)

DO I=1,5 C(I) = A(I+2) END DO

A(2:10:2) = C

DO I=1,5 A(2*I) = C(I) END DO

A = SIN(B)

DO I=1,10 A(I) = SIN(B(I)) END DO

Exemplo 7
Atribuio de valores a sees de Arrays. .

REAL, DIMENSION (2, 3) :: ARRAY REAL, DIMENSION ( 3) :: ULT_COLUNA REAL, DIMENSION (2 ) :: PRIM_LINHA PRIM_LINHA (:) = ARRAY(1, : ) ! TODOS ELEM. DA PRIMEIRA LINHA ULT_COLUNA (:) = ARRAY (: ,3) ! TODOS OS ELEM. DA ULTIMA COLUNA

Exemplo 8
Passando valores contidos em sees de Arrays, como argumentos para subprogramas.

PROGRAM SLICE REAL, DIMENSION(2,3) :: ARRAY .... CALL LISTA (ARRAY(1, : ) ) END PROGRAM SLICE

41

Exemplo 9
PROGRAM ADD_ARRAYS IMPLICIT NONE INTEGER :: I REAL, DIMENSION(4) :: A = (/1.,2.,3.,4./) REAL, DIMENSION(4) :: B = (/5.,6.,7.,8./) REAL, DIMENSION(4) :: C, D ! ELEMENT-BY-ELEMENT ADDITION DO I = 1,4 C(I) = A(I) + B(I) END DO ! WHOLE ARRAY ADDITION D = A + B

! WRITE RESULTS WRITE (*,100) C , C WRITE (*,100) D , D 100 FORMAT( , A, =, 5(6.1,1X)) END PROGRAM

5.3 - LEITURA E GRAVAO DE ELEMENTOS DO ARRAY - DO IMPLICITO


Utilizado para auxiliar no processo de leitura ou gravao de dados provenientes de vetores e matrizes. Neste tipo de operao, utiliza-se o comando READ, ou WRITE, em conjunto com a especificao de ndices que substituiro um ou mais comandos DO.

Exemplo 1
READ (*,*) (VET(I), I = 1, 10)

Exemplo 2
READ(*,*) (( MAT(I,J), J=1,5), I=1,3)

42

5.4 - WHERE - Simplificando as operaes com Arrays


O comando WHERE aplicvel a arrays, realizando operaes sobre todos os elementos simultaneamente. Pode-se considerar que o WHERE substitui um conjunto de IFs e Do loops.

Sintaxe:
[name:] WHERE (EXPRESSAO RELACIONAL) COMANDO OU BLOCO DE COMANDOS I ELSEWHERE [name] COMANDO OU BLOCO DE COMANDOS II END WHERE [name]

Exemplo 1

FORTRAN 77 source:
INTEGER A(10,10),B(10,10) DO I=1,10 DO J=1,10 IF (A(I,J).LT.B(I,J)) A(I,J)=B(I,J) END DO END DO END

Fortran 90 or Fortran 95 source:


INTEGER A(10,10),B(10,10) WHERE (A.LT.B) A=B END

43

Exemplo 2
PROGRAM CLIMA CHARACTER*1, DIMENSION(18) REAL, DIMENSION(18) LOGICAL , DIMENSION(18) INTEGER ... ! DEFINE HEMISFERIO WHERE ( LATITUDE > = 0 ) HEMISFERIO = 'N' ELSEWHERE HEMISFERIO = 'S' END WHERE ... WHERE ( PRESSAO <= 1.0 ) PRESSAO = PRESSAO + INC END WHERE ! INCREMENTA VALORES PARA ! VALORES <= 1.0 DE PRESSAO ! VERIFICA TODOS OS ELEM. DE LATITUDE ! ATRIBUI VALORES ! IDEM, CASO ELEM. EM LATITUDE SEJA < 0 :: :: :: :: HEMISFERIO TEMPERATURA, PRESSAO, LATITUDE CHUVA INC

Exemplo 3
Como a declarao abaixo seria escrita no FORTRAN 77? WHERE ( B .NE. 0 ) A = A/B

Exemplo 4
O trecho abaixo: DO I = 1, N DO J = 1, M LOGVAL(I,J) = LOG(VALUE(I,J)) END DO END DO equivalente a: LOGVAL = LOG(VALUE)

44

Agora deseja-se calcular o logaritmo apenas para os valores positivos, para os quais a funo est definida: Utilizando o mtodo tradicional: DO I = 1, N DO J = 1, M IF ( value(i,j) > 0.0 ) THEN LOGVAL(I,J) = LOG(VALUE(I,J)) ELSE LOGVAL(I,J) = -99999 END IF END DO END DO Utilizando a construo WHERE, o trecho acima ficar reduzido a: WHERE (value > 0.) Logval = log(value) ELSEWHERE LOGVAL = -99999 END WHERE

45

5.5 - Funes intrnsecas para vetores (FORTRAN 90)


DOT_PRODUCT(VECTOR_A, VECTOR_B)

matrizes e

Retorna o produto escalar entre dois vetores, os quais devem ter o mesmo tamanho (mesmo nmero de elementos). Retorna o produto de duas matrizes que devem ser consistentes, isto , ter dimenses como (M, K) e (K, N). Retorna o maior valor contido em ARRAY. Retorna o menor valor contido em ARRAY. Retorna o produto de todos os elementos contidos em ARRAY. Retorna a soma de todos os elementos contidos em ARRAY. Funo lgica que devolve true se array tiver sido alocado. Retorna o limite inferior do array. Retorna o formato (dimenses) do array. Retorna o nmero de elementos contidos no array. Retorna o limite superior do array.

MATMUL(MATRIX_A, MATRIX_B)

MAXVAL(ARRAY, dim, mask) MINVAL(ARRAY, dim, mask PRODUCT(ARRAY, dim, mask) SUM (ARRAY, dim, mask) ALLOCATED(ARRAY) LBOUND(ARRAY, dim) SHAPE(ARRAY) SIZE(ARRAY, dim) UBOUND(ARRAY, dim)

46

Um Exemplo de uso de Funo Intrnseca para Arrays RESHAPE


A funo intrnseca RESHAPE permite modificar a estrutura de um array, desde que a estrutura anterior e a especificada, contenham a mesma quantidade de elementos. Observe que o RESHAPE atribui os dados de uma mesma maneira, que feita pelo comando READ. RESHAPE ( / 1, 4, 7, 2, 5, 8, 3, 6, 9 /), ( /3, 3/) 1 4 7 2 5 8 3 6 9

Exemplo 2 - Dados os valores para SOURCE, SHAPE e PAD, observe o resultado


da funo RESHAPE. SOURCE = [1,2,3,4,5,6] SHAPE = [2,5] PAD = [0,0] RESHAPE(SOURCE, SHAPE, PAD) = 1 3 5 0 0

47

6 - USER-DEFINED DATA TYPE TIPOS DERIVADOS - FORTRAN 90


Assim como os arrays, um user-defined data type pode ter muitos elementos, com a diferena de que este conjunto pode conter dados de tipos diferentes. Ou seja, um componente pode ser de tipo inteiro, outro de tipo real e assim por diante. Alm disso, cada elemento identificado por um nome e no por um nmero (indice) como no caso do array. Estas estruturas so similares construo RECORD (Pascal) ou STRUCT (C). Sintaxe: TYPE < nome da estrutura > Definio dos componentes (campos) da estrutura END TYPE < nome da estrutura >

Exemplo 1
Exemplo de declarao de um user-defined data type. TYPE PESSOA INTEGER IDADE CHARACTER (LEN=50) NOME END TYPE PESSOA

Exemplo 2
Cada elemento do tipo derivado pode ser acessado de forma independente. O smbolo % utilizado para referenciar componentes especficos da estrutura. TYPE PESSOA INTEGER IDADE CHARACTER (LEN=50) END TYPE PESSOA

NOME

TYPE (PESSOA) :: MARIA MARIA%IDADE = 15 MARIA%NOME = MARIA SCHNEIDER

Criando uma Estrutura Array de user-defined data type


Uma vez criada a estrutura (type ... end type ), podem ser criadas variveis simples daquele tipo type(pessoa) :: maria, como no exemplo anterior, assim como arrays, da seguinte forma:

48

TYPE (PESSOA), DIMENSION(25) :: CADASTRO Esta ultima declarao dimensiona um array de 25 elementos de tipo pessoa.

Exemplo 1
Criao de um cadastro PROGRAM USER_TYPE TYPE PESSOA INTEGER IDADE CHARACTER (LEN=50) NOME END TYPE PESSOA ! TYPE (PESSOA), DIMENSION(25) :: CADASTRO TYPE (PESSOA) FIM_CADASTRO ! CADASTRO(3)%IDADE = 36 CADASTRO(3)%NOME = 'LUIS CARLOS' ! ! OUTRA FORMA DE ASSOCIACAO DE DADOS AO REGISTRO: ! CADASTRO(4) = PESSOA (26, 'ANA BEATRIZ') FIM_CADASTRO = (0, ) ! PRINT*,CADASTRO(3) PRINT*,CADASTRO(4) PRINT*,FIM_CADASTRO END SADA DO PROGRAMA: 36 LUIS CARLOS 26 ANA BEATRIZ 0

49

Criando estruturas mais complexas usando derived types.


TYPE STAFF CHARACTER (LEN=20) INTEGER END TYPE :: PRIMEIRO_NOME, ULTIMO_NOME :: IDENTIFICACAO, DEPTO

TYPE EMPRESA CHARACTER (LEN=20) :: NOME_EMPRESA TYPE (STAFF), DIMENSION(100) :: STAFF_CADASTRO END TYPE . . TYPE (EMPRESA), DIMENSION(10) Associando valores aos campos A atribuio de valores pode ser realizada diretamente sobre um campo especfico: varias_empresas(1)%nome_empresa = PETROBRAS Associando valores, sem e specificao de nomes de campos varias_empresas(1)%staff_cadastro(3) = (Jose, Silva, 113, 03) :: VARIAS_EMPRESAS

50

7 - Leitura e Gravao de Dados, FILES


As operaes de leitura e gravao servem para transferir dados de meios de armazenamento externos tais como unidades de disco, para a memria e vice-versa. Para a realizao destas operaes, o Fortran oferece trs comandos: READ, WRITE e PRINT .

7.1 Read, Write, Print


READ - Comando para Leitura de dados
Sintaxe: READ ( UNIT=<unidade lgica> , FMT=<formato>, REC=<registro>, ERR=<rtulo>, IOSTAT=<varivel inteira>, END=<rtulo> ) <lista de variveis> Onde: <unidade lgica> : nmero do arquivo a ser lido. O uso do nmero 5 ou *, indica que a entrada de dados ser via teclado, considerada a unidade default, para leitura de dados. <formato> : como o dado est ou ser representado, de acordo com seu tipo <registro> : representa o registro a ser lido dentro do arquivo (para arquivos de acesso direto) <varivel inteira> : retorna o cdigo de finalizao do comando para uma varivel inteira. 0 = leitura normal valor negativo = fim de arquivo valor positivo = erro na leitura do dado <rtulo> : rtulo para desvio aps erro (ERR) ou leitura do dado (END) <lista de variveis> : lista de variveis a serem lidas

Exemplo 1
Variveis A, B, C digitadas atravs do teclado READ (5,*) A, B, C READ (*,*) A, B, C

51

WRITE - Comando para saida de dados


Utilizado para mostrar dados na tela ou grav-los em um arquivo; a sintaxe a mesma do comando READ. Todas as opes do comando READ so vlidas, exceto a clusula END. Uma outra diferena que a unidade lgica do comando, corresponde ao nmero do arquivo a ser gravado. O uso do nmero 6 ou *, indica impresso de dados na tela do computador, que considerada a unidade default.

Exemplo 1
Variveis A, B, C tero seus valores exibidos na tela do computador WRITE (6,*) A, B, C WRITE (*,*) A, B, C

PRINT - Comando para gravao de dados


Sintaxe: PRINT *, <lista de variveis> ou PRINT <formato>, <lista de variveis> Este comando poder ser utilizado somente para a exibio de dados em tela, no podendo ser aplicado gravao em arquivos.

Exemplo 1
PRINT *, A, B, C

Formatao de Dados
Muitas vezes, necessrio realizar a leitura ou gravao de dados de maneira formatada, especificando por exemplo, um nmero mximo de casas decimais, ou tamanho total de um campo. Ou seja, a forma como o dado est codificado externamente, ou ser codificado, nas operaes de leitura ou gravao respectivamente. Em Fortran existem duas formas de especificar a formatao: 1) atravs de um rtulo, que servir como referncia para a linha aonde o formato est especificado (atravs do FORMAT), ou uma varivel de tipo 2) atravs de uma declarao de formatao, dentro do comando read ou write.

52

Exemplo: As declaraes abaixo so equivalentes 1) read (5, FMT=(i2))) x

2) read (5,20) 20 format (I2) x

Formato livre : usado quando se deseja ler ou imprimir valores sem se preocupar com o formato. Para tal, basta utilizar um * no lugar da especificao do rtulo, no comando read ou write. Controle de Espacejamento: No Fortran, a primeira posio de um registro gravado reservada para controle de espacejamento. Esta uma caracterstica remanescente das primeiras verses da linguagem. Esta posio nunca impressa e o seu contedo servia para determinar a movimentao do papel (cursor, para terminais), antes da impresso do registro. Sendo assim, ao utilizar o comando PRINT ou WRITE, sempre conveniente deixar um espao antes do texto ou da primeira varivel a ser impressa.

53

7.2 Formatos para Leitura de Dados


I - INTEGER
Formato I4 I3 I8 I3 I8 Valor Externo 2216 -40 bbbb1234 1 2 1234bbbb Valor Lido 2216 -40 1234 102 12340000

F - REAL (Preciso Simples)


Formato F5.2 F5.2 F5.2 F5.2 Valor Externo 12345 1.234 -1234 12 34 Valor Lido 123.45 1.234 -12.34 120.34

X - Ignora caracteres
Exemplo
10 READ (5,10) I,J FORMAT ( I3, 2X, I4 )

Supondo que o contedo do registro fosse: 123456789 os valores lidos seriam: I = 123; J = 6789

54

A - CHARACTER
Sintaxe: A <constante inteira>

Exemplo
Formato A3 A5 Valor Externo ABCbb ABCDE Valor Lido ABC ABCDE

D e E - REAL exponencial

(Preciso simples ou dupla) em notao

Na leitura, o valor pode ter notao cientfica (no Fortran, o valor normalizado entre 0.1 e 10 e multiplicado por alguma potncia de 10). O formato D considerado obsloleto, sendo o seu uso desaconselhado em novos programas. Sintaxe: E <w=constante inteira>.<d=constante inteira> Onde: w : valor inteiro representando o campo total. Para evitar overflow, normalmente ele deve satisfazer a seguinte expresso: w >= d+7 d: valor inteiro suficiente para representar o smbolo E, o sinal do expoente e o expoente.

Exemplo
Formato E11.4 E10.3 D10.2 Valor Externo 25046 1268E+3 12345000.00 Valor Lido 2.5046 b1268000.0 0.12345D+8

ES - Notao Cientfica
A especificao do formato ES, segue a mesma norma do formato E, visto no tem anterior. A nica diferena que este formato segue o exatamente a conveno de notao cientfica, normalizando o valor a ser representado entre 1. E 10., multiplicado por uma potncia de 10.

55

/ - Pular para o prximo registro


Exemplo
Suponha os registros: 123456 789012 Utilizando o comando: READ (5,10) J1, J2, J3, J4 10 FORMAT (I4,I2,/,I3,I3) Os valores lidos sero: J1=1234, J2= 56, J3 = 789, J4=12

56

7.3 - Formatos para Gravao de Dados


Integer
Formato I4 I3 I5 I4.2 I4.4 I3 Valor 1234 -5 123 1 1 -473 Valor Gravado 1234 -5 123 01 0001 ***N

Reais - Preciso Simples


Formato F6.2 F5.2 F5.2 F5.2 Valor 123.0 -4.3 1.234 -10.4 Valor Gravado 123.00 -4.30 1.23 ******

X - Imprime espaos em branco


Exemplo
20 WRITE (6,20) I, A FORMAT (3X, I3, 2X, F4.2 )

Supondo I = 123 e A = 1.23 Seria impresso: bb123bb1.23

CHARACTER
Sintaxe: A <constante inteira>

Exemplo
Formato A5 A3 A5 Valor ABCDE ABCDE ABC Valor Gravado ABCDE ABC ABC

57

D e E - REAL exponencial

(Preciso simples ou dupla)

em notao

Na gravao, a notao cientfica ser representada por D ou E, de acordo com a especificao. O formato D considerado obsloleto, sendo o seu uso desaconselhado em novos programas.

Exemplo
Formato D10.3 E10.5 D11.5 Valor 0.0363 -36.7929 -36.7929 Valor Gravado bb.363D-01 *********** b-.36793D+02

Formato Texto - Imprime uma cadeia de caracteres


Exemplo
I = 10 WRITE (6, 15) I 15 FORMAT ( o valor de I =, I3 ) A saida impressa ser: o valor de I = 10

Exemplo
os formatos a seguir so equivalentes. FORMAT( 4I4, 3F5.2, 2(I3,2X)) FORMAT( I4,I4,I4,I4,F5.2,F5.2,F5.2,I3,2X,I3,2X)

FORMAT( 2(3I2,1X),F5.3) FORMAT( I2, I2, I2, 1X, I2, I2, I2, 1X, F5.3 )

58

Formato para tipos Derivados


possivel imprimir uma estrutura de um tipo derivado, definindo o nome da estrutura como sendo uma varivel simples e especificando a sequncia de formatos para os seus diversos elementos. A mesma definio vale para a leitura de dados.

Exemplo
TYPE string INTEGER LENGTH CHARACTER (LEN=20) WORD END TYPE STRING TYPE (STRING) :: TEXT WRITE(*, '(I2,A)') TEXT

Non Advancing - Impede salto de linhas entre comandos de leitura e gravao.


Exemplo
100 write(6,100) format(' ', Digite um numero: ') read (5,*) i Entre com um numero: 123 < ------valor digitado write(6,100,advance='NO') format(' ', 'Digite um numero: ') read (5,*) i Entre com um numero: 123

Resultado:

100

Resultado:

G - Formato Geral
Como exemplo, o formato F dado por F7.3, pode representar um valor real da forma: ddd.ddd ou dd.ddd. No entanto, se este nmero for >=1000 ou <= -100, a sada especificada no ser suficiente sendo ento representada por um campo de asteriscos. Desta forma, se ao invs do descritor F, for utilizado o G, o nmero, quando muito grande ou pequeno, ser automaticamente substitudo pelo formato E. O formato geral G pode ser utilizado tambm para representar dados inteiros, lgicos ou character, assumindo o formato conveniente em cada caso.

59

7.4 - Leitura e Gravao de Dados em Arquivos


Um arquivo consiste de vrias linhas contendo dados e que poder ser acessado como uma unidade. Cada linha de informao no arquivo denominada registro. Em termos prticos, um arquivo fsico existente em uma unidade de disco por exemplo, dever ser associado a uma unidade lgica dentro do programa, para que possa ser acessado. O FORTRAN pode ler informaes ou gravar em um arquivo, um registro por vez. Uma unidade lgica dentro do programa poder ser conectada a um arquivo em disco atravs do comando OPEN.

OPEN
Associa um nome de arquivo a um descritor (numero da unidade), tornando um arquivo em disco disponvel para leitura ou gravao de dados. O comando OPEN realiza a associao entre o nome real do arquivo (que est ou que ser gravado em disco) e o nmero especificado como unit. A partir da, toda vez tal nmero aparecer em um comando READ ou WRITE, significa que o arquivo correspondente ser acessado. A operao a ser realizada (leitura ou gravao) tambm poder ser especificada atravs de opes dentro do comando OPEN. Opes: OPEN ( UNIT=<unidade>, IOSTAT=<varivel>, FILE=<nome>, STATUS=<stat>, ACCESS=<acc>, FORM= <form>, RECL=<tam> ) Onde: <unidade> : <rtulo erro> : <varivel> : erro no OPEN <nome> : arquivo <stat> : nmero do arquivo lgico (descritor) o rtulo de um comando para onde ser desviado o programa em caso de erro no OPEN. varivel inteira, retornando valor diferente de zero em caso de uma expresso CHARACTER contendo o nome externo do OLD arquivo j existente NEW- ser criado um novo arquivo SCRATCH arquivo temporrio UNKNOWN sem informaes a respeito da existncia ou no SEQUENTIAL acesso sequencial DIRECT - acesso direto FORMATTED arquivo com dados formatados UNFORMATTED arquivo sem formatao de dados expresso inteira que corresponde ao tamanho do registro

do arquivo <acc> <form> <tam>

: : :

60

Exemplos:
1) OPEN (UNIT=8, FILE=ARQ1.DAT, STATUS=OLD) 2) OPEN(UNIT=31,FILE=DADOS.TXT,STATUS=REPLACE, FORM=FORMATTED)

CRIANDO NOMES DE ARQUIVOS DINAMICAMENTE TRANSFORMAO DE NUMERO EM STRING


INTEGER VALUE CHARACTER*2 STRING VALUE = 24 WRITE (STRING, '(I2)'), VALUE PRINT *, STRING OPEN (UNIT=2, FILE="ARQ"//STRING ) WRITE (2,*) "TESTE!!" CLOSE (2) END

Obs ervao: A leitura de arquivo com uso da clusula end= dentro do comando read, no recomendvel no desenvolvimento de novos cdigos. Prefira o controle de fina/dados atravs do uso da opo iostat.
implicit none integer :: io-status, x integer :: line = 0 open ( unit=4, file=a2.dat) io-status = 0 do while (io-status == 0 ) line = line + 1 read (5, FMT=(i2)), iostat=io-status) x if ( io-status == 0 ) then write (6, 102) line, x else write (6, 103) io-status endif enddo 102 format(line, i2, tem inteiro x = , i2) 103 format(Codigo iostat no fim de arquivo (EOF)= , i9) end

61

Exemplo 2 Verificao do final de arquivo com uso do IOSTAT


OPEN (UNIT=8, FILE=TESTE.DAT, STATUS=OLD) ! READ INPUT DATA NVALS = 0 DO READ(8, 100, IOSTAT = ISTAT) TEMP ! CHECK FOR THE END OF THE FILE (DATA) IF (ISTAT < 0) EXIT NVALS = NVALS + 1 ARRAY(NVALS) = TEMP END DO

Exemplo 3 Verificao do final de arquivo com uso da opo END


OPEN (UNIT=8, FILE=TESTE.DAT, STATUS=OLD) ! READ INPUT DATA NVALS = 0 READ(8, 100, END=500) TEMP NVALS = NVALS + 1 ARRAY(NVALS) = TEMP 500 CLOSE(UNIT=8)

CLOSE
Desconecta o arquivo lgico de um arquivo fsico, tornando-o indisponvel para uso no programa. O seu uso altamente recomendvel aps a utilizao de arquivos.

Exemplo
CLOSE (8) CLOSE (UNIT=8)

62

8 Subprogramas (Funes, Subrotinas, Mdulos e interfaces)


Sub-programas so unidades criadas em separado do programa-principal, com o objetivo de executar tarefas especficas. Os sub-programas p odem ser chamados a partir de qualquer ponto do programa solicitante. A criao de sub-programas ajuda na clareza da documentao, evita a repetio de comandos e auxilia na construo de bibliotecas de programas. Os sub-programas so compilados parte do programa principal. Na gerao do cdigo executvel, os cdigos-objeto do programa principal e dos sub-programas so ligados (link), para que seja possvel a interao entre eles. Em FORTRAN

77, os tipos de subprogramas disponveis so:

Funes intrnsecas Funes declarao Funes externas Subrotinas

Novas implementaes para Subprogramas no Fortran 90


O Fortran Procedures.

90

possui novas implementaes que tornam mais fcil o uso de

1) A Interface, as caractersticas dos argumentos ou as procedures externas podem ser especificados explicitamente em uma Interface Block. 2) Uma Interface Block genrica pode especificar um nome que poder acessar quaisquer procedures especficas dentro do bloco, dependendo da natureza atual dos argumentos. 3) Procedures Internas contidas dentro de um programa principal ou outro subprograma permitem acesso direto s entidades(variveis) definidas no programa host. 4) Procedures recursivas so permitidas no Fortran 90; funes e subroutinas podem chamar a si mesmas direta ou indiretamente.

63

No FORTRAN

90, os tipos de subprogramas disponveis so:

Funes intrnsecas Funes externas Subrotinas externas Subrotinas e funes internas Mdulos Interfaces Recursividade

8.1 - Funes Intrnsecas


So funes pr-definidas na linguagem. Abaixo, alguns exemplos: Funo ABS(X) ALOG(X) ALOG10(X) SIN(X) COS(X) MOD(I1,I2) EXP(X) Valor Retornado |X| Ln X Log X Seno(X) Coseno(X) Resto de diviso inteira I1 e I2 ex

entre

Exemplos de funes pr-definidas pelo compilador Y = SIN(A) + SIN(B) Z = SQRT (B**2 - 4*A*C) X = COS(SQRT(A))

TIME FUNCTION
DTIME Devolve o tempo decorrido desde o incio do processamento do ultimo processo (em segundos). Exemplo
REAL(4) I, TA(2), result I = DTIME(TA, result) write(*,*) 'Program has been running for', I, 'seconds.' write(*,*) ' This includes', TA(1), 'seconds of user time and', & TA(2), 'seconds of system time.'

64

Intrinsic Functions List Fortran90


Function abs(x) achar(i) acos(x) adjustl(string) adjustr(string) asin(x) associated(P,T) atan(x) cos(x) cshift(array,shift,dim) dot_product(A,B) exp(x) Definition Absolute value of x ASCII Character corresponding to integer value i Returns the arccosine (inverse cosine) of x (x is real) Returns a character string "string" left justified Right justifies character string "string" Returns the arcsine (inverse sine) of x (x is real) Checks on the association status of a pointer Returns the arctan (inverse tangent) of x (x is real) Returns the cosine of x (x is not an integer) Performs a circular shift of array along dimension dim. Returns the dot product of vectors A and B Calculates e (2.7183...) to the x power (x is not an integer) Returns the largest number that can be represented by a number of the same type and kind as x. Returns the integer value associated with an individual character in the Ascii character set Returns the lower bounds declared for array along dimension dim. Length declared for character entity "string" Returns the number of characters in "string" not including trailing blanks Calculates the natural logarithm of x (x is not an integer and x>0) Calculates the base 10 log of x (x is not an integer and x>0) Returns the matrix which is the result of the matrix multiplication between matrices A and B. Arguments must have one or two dimensions. Returns the maximum of x1, x2,... (arguments must be of the same type) Returns the location of the largest

huge(x)

iachar(string)

lbound(array,dim) len(string) len_trim(string) log(x) log10(x)

matmul(a,b)

max(x1, x2,...) maxloc(array,mask)

65

integer or real array element maxval(array,dim,mask) min(x1, x2,...) minloc(array,mask) minval(array,dim,mask) mod(i,j) nint(x) random_number(harvest) Returns the maximum value of array along dimension dim Returns the minimum of x1, x2,... (arguments must be of the same type) Returns the location of the array element with the smallest value Returns the minimum value of array along dimension dim Produces the remainder of the division of i by j (modulo function) Returns the nearest integer to the real number x Sets a random number from the normal distribution between zero and one. Returns the location of the first occurrence of character in "set" within "string." Returns zero if none found. Delivers the integer specifying the KIND attribute of an integer variable that can contain numbers with at least "i" decimal digits Delivers the integer specifying the KIND attribute of a real variable with decimal precision of at least i digits and a decimal exponent range of j Returns the sine of x (x is not an integer) Returns the square root of x (x is not an integer and >0) Returns the sum of all of the elements along dimension dim. Subroutine which returns information about the clock of the host system. Returns the tangent of x (x is not an integer) Returns the smallest number that can be represented by a real of the same type. Returns the upper bounds declared for array along dimension dim. Returns the location of the first character in "string" that is not in "set"

scan(string,set,back)

selected_int_kind(i)

selected_real_kind(i,j)

sin(x) sqrt(x) sum(array,dim,mask) system_clock(count, count_rate,count_max) tan(x) tiny(x) ubound(array,dim)

verify(string,set,back)

66

8.2 - Funo declarao (FORTRAN 77)


So funes que representam uma nica expresso ( aritmtica, lgica ou caracter ). Sintaxe: <nome da funo>(<lista de parmetros>) = <expresso> Onde: <nome da funo> : o tipo do identificador deve concordar com o tipo da expresso

Exemplo 1 - Exemplos de funes-declarao


DELTA(A,B,C)=SQRT(B**2- 4*A*C) POLY(X)= 3*X**2 - 4*X + 2 TRIG(X,Y) = SIN(X)**2 + COS(Y)**2

LOGICAL COMP COMP(X,Y) = X .LT. 7.5 .OR. Y .GT. 10

Exemplo 2 - Tabela da funo 3x 2-4x+2 (formato FORTRAN 77) - Observe que f(x)
devolve o resultado da expresso digitada no incio do programa de acordo com o valor do parmetro x.

C C C

10 100

REAL F, X, Y DECLARACAO DA FUNCAO F(X)=3*X**2-4*X+2 LOOP PARA A IMPRESSAO DA TABELA NO INTERVALO [ 1.0, 5.0] com incremento 0.1 DO 100 X = 1.0,5.0, 0.1 Y=F(X) WRITE(6, 10) X, Y FORMAT(,10X,X=,F3.1,2X,F(X)=, F8.3) CONTINUE END

67

8.3 Funes Externas


Retorna apenas um valor ao programa solicitante. definida externamente, ou seja, em uma unidade separada do programa principal ou de qualquer sub-programa. A funo externa tem seu incio identificado pela declarao: FUNCTION <nome da funo>, necessitando do comando END para indicar seu final fsico. No Fortran 77, o ponto de retorno ao programa solicitante definido atravs do RETURN, sendo desaconselhado o uso deste comando em novos programas.

Observao: o nome da funo deve aparecer pelo menos uma vez esquerda de
um comando de atribuio no corpo da funo. Sintaxe: <tipo da funo> FUNCTION <nome da funo> (<parmetros>) .... RETURN END Onde <tipo da funo> pode ser: INTEGER REAL DOUBLE PRECISION LOGICAL CHARACTER ARRAY Deve corresponder ao tipo de dado retornado pela funo.

Exemplo
REAL FUNCTION QUADF (X, A, B, C) ! FUNCTION TO EVALUATE A QUADRATIC POLYNOMIAL OF THE FORM ! QUADF = A * X ** 2 + B * X + C IMPLICIT NONE ! DECLARE ARGUMENTS REAL, REAL, REAL, REAL, INTENT(IN) INTENT(IN) INTENT(IN) INTENT(IN) :: :: :: :: X A B C

! EVALUATE EXPRESSION QUADF = A * X ** 2 * B * X * C

68

END FUNCTION

Observao: O valor a ser retornado deve estar associado pelo menos uma vez, ao nome da funo.
PROGRAM TEST_QUADF IMPLICIT NONE REAL :: QUADF REAL :: A, B, C, X WRITE(*,*) READ (*,*) WRITE(*,*) READ (*,*) "ENTER QUADRATIC COEFFICIENTS A, B, C: " A, B, C "ENTER LOCATION AT WHICH TO EVALUATE EQUATION:" X

! WRITE OUT RESULT WRITE (*,100) "QUADF(', X, ")', QUADF(X,A,B,C) 100 FORMAT (A,F10.4,F12.4) END PROGRAM

8.4 SUBROTINAS EXTERNAS


Unidade de programa que pode retornar vrios resultados para o programa solicitante. A forma do programa solicitante ativar uma determinada subrotina atravs do comando CALL Sintaxe: SUBROUTINE <nome da subrotina> (<lista de parmetros>) ......... BLOCO DE COMANDOS ......... RETURN END

69

Exemplo
C SUBROTINA PARA INVERTER UM VETOR CONTENDO N ELEMENTOS SUBROUTINE INVERTE_VETOR(A, N) INTEGER :: N, TEMP, I INTEGER, DIMENSION(N) :: A DO I=1,N/2 TEMP=A(N+1-I) A(N+1-I) = A(I) A(I)= TEMP END DO END C PROGRAMA QUE CHAMA A ROTINA INVERT INTEGER A(50), DIM DIM=10 WRITE(*,*) DIGITE VALORES PARA ELEMENTOS DO VETOR A READ(5,*) (A(I), I=1, DIM) WRITE(*,*) VALORES CONTIDOS NO VETOR A ANTES SUBROUTINE WRITE(6,*) (A(I), I=1,DIM)

CALL INVERTE_VETOR(A, DIM) WRITE(*,*) VALORES CONTIDOS NO VETOR A DEPOIS SUBROUTINE WRITE(6,*) (A(I), I=1,DIM) STOP END

8.5 - Sub-programas Internos


So similares aos sub-programas j conhecidos (functions e subroutines), porm devendo ser inseridos dentro do programa principal ou de outros subprogramas. A declarao CONTAINS separa um sub-programa interno, do programa que o contm. Um fator limitante que este tipo de subprograma s pode ser chamado a partir da unidade dentro da qual ele est especificado. Por outro lado, este tipo de sub-programa herda as variveis do programa que o contm no sendo necessria a passagem de parmetro, uso de common-blocks ou qualquer outra estratgia para disponibilizar o valor de uma varivel a ser utilizada neste sub-programa. Ou seja, as variveis do programa host, so consideradas globais para o sub-programa.

70

Exemplo 1 Observe que a varivel X no precisou ser passada como parmetro!


SUBROUTINE OUTER REAL X, Y ..... CALL INNER ..... CONTAINS SUBROUTINE INNER REAL Y Y = X + 1 END SUBROUTINE INNER END SUBROUTINE OUTER

Exemplo 2
PROGRAM TRIANGULO REAL A, B, C PRINT *, 'ENTRE COM OS TRES LADOS DO TRIANGULO' READ *, A, B, C PRINT *, 'AREA DO TRIANGULO: ',AREATRIANGULO (A, B, C) CONTAINS FUNCTION AREATRIANGULO (A, B, C) REAL AREATRIANGULO REAL, INTENT(IN) :: A, B, C REAL THETA REAL ALTURA THETA = ACOS( (A**2 + B**2 - C**2) / (2.0*A*B) ) ALTURA = A * SIN(THETA) AREATRIANGULO = 0.5 * B * ALTURA END FUNCTION AREATRIANGULO

71

8.6 - MDULOS
Os mdulos podem substituir todos os usos de declaraes include, common e funes declarao, disponibilizando variveis, estruturas e subprogramas entre unidades. Mais abrangentes do que os common block, podero ser feitas especificaes de parmetros, variveis e/ou tipos; Pode-se ainda, ter um subprograma contido no mdulo. Um subprograma de uso global, se existente, dever ser iniciado pela declarao CONTAINS e estar em forma de SUBROUTINE ou FUNCTION. Subprogramas especificados dentro de mdulos recebem o nome especial de MODULE PROCEDURE.

Sistemas Microsoft: os mdulos quando utilizados dentro de um projeto, significa


que ser comum ao programa principal e a todas as rotinas que chamarem o mesmo (use). Para que no d erro na compilao do projeto, o mdulo necessita ser compilado antes do programa principal (para que seja gerado o arquivo modulo.mod). Nos sistemas UNIX/LINUX, os mdulos tambm devem ser compilados antes do programa principal, da seguinte forma: demo% f95 -c mod_one.f90 mod_two.f90 demo% f95 -c main.f90 demo% f95 -o main main.o mod_one.o mod_two.o

Ao compilar o programa principal main.f90, o compilador procura pelos objetos mod_one.mod e mod_two.mod . Os mdulos devem ser compilados antes de quaisquer arquivos que faam referncia a eles, atravs de declaraes USE. Os mdulos podem substituir todos os usos de declaraes include, common e funes declarao, disponibilizando variveis, estruturas e subprogramas entre unidades. Mais abrangentes do que os common block, podero ser feitas especificaes de parmetros, variveis e/ou tipos; Pode-se ainda, ter um subprograma contido no mdulo. Um subprograma de uso global, se existente, dever ser iniciado pela declarao CONTAINS e estar sob forma de SUBROUTINE ou FUNCTION. Subprogramas especificados dentro de mdulos recebem o nome especial de MODULE PROCEDURE. As variveis ou subprogramas contidos no mdulo sero globais a todas as unidades que solicitarem o seu uso. Esta solicitao pode ser feita atravs do comando USE. Observao: SUBROUTINES e/ou FUNCTIONS contidas no mdulo podero ter, por sua vez, subprogramas internos. Dica: Variveis que no devem ser globais ( que devem estar disponveis somente dentro do mdulo e ocultas para qualquer unidade de programa que utilize o mdulo ) podero utilizar o atributo PRIVATE. Por default, todos os dados so do tipo PUBLIC. INTEGER, PRIVATE :: N, X

72

Importante: Um mdulo pode conter arrays alocveis globais

USE
A declarao USE, torna um mdulo disponvel, proporcionando acesso a todos os objetos de dados pblicos, tipos derivados, interfaces e subprogramas, contidos no mdulo nomeado. Sintaxe: USE <nome do mdulo>

Exemplo 1 - Observe que, apesar de no serem utilizadas nem as listas de


argumentos, nem o common, a subrotina "reconhece" os valores das variveis a e b. Estes valores esto sendo compartilhados atravs do module. MODULE VARIAVEIS INTEGER A, B END MODULE PROGRAM TROCA USE VARIAVEIS A = 10 B = 20 CALL SUB PRINT *, A, B END PROGRAM SUBROUTINE SUB USE VARIAVEIS INTEGER CTEMP CTEMP = A A = B B = CTEMP END SUBROUTINE

! Valor Impresso pelo programa: 20, 10

73

Exemplo 2
MODULE MatrixVectorOperations INTEGER, PARAMETER :: N = 3 ! n=3 -> constante global CONTAINS FUNCTION MatrixVectorMultiply ( A, B ) RESULT (C) IMPLICIT NONE REAL, DIMENSION (:, :), INTENT (IN) :: A REAL, DIMENSION (:), INTENT (IN) :: B REAL, DIMENSION(SIZE(B)) :: C INTEGER N INTEGER I N = SIZE(B) C = 0.0 DO I = 1, N C = C + B( I ) * A ( :, I ) ENDDO END FUNCTION MatrixVectorMultiply END MODULE MatrixVectorOperations

PROGRAM MatrixVector USE MatrixVectorOperations IMPLICIT NONE REAL, DIMENSION ( N, N ) :: A REAL, DIMENSION ( N ) :: B, C ! Preenche A e B com entradas randmicas CALL RANDOM_NUMBER (A) CALL RANDOM_NUMBER (B) ! Calcula o produto A * B C = MatrixVectorMultiply ( A, B) PRINT *, O produto e : , C END PROGRAM MatrixVector

74

8.7 COMPARTILHANDO SUBPROGRAMAS

DADOS

COM

No FORTRAN 77, o compartilhamento de valores entre programa principal e subprogramas (ou entre subprogramas), podia ser realizado de duas formas: a) Atravs de lista de Argumentos b) Utilizando-se o COMMON Block No Fortran 90, alm destas duas formas, existe uma terceira que a utilizao de mdulos, conforme foi visto em exemplo anterior. Em todos estes casos, o compartilhamento de dados realizado atravs de passagem por referncia (Pass-by_Reference Scheme); Isto significa que as alteraes realizadas sobre um determinado argumento dentro de um subprograma so definitivas, retornando ao programa solicitante com valor alterado. A lista de variveis e/ou subprogramas inseridos dentro de um mdulo tornam-se globais todas as unidades que utiliz-lo. O uso de mdulos fortemente recomendado em substituio s declaraes COMMON. Utilizando-se o COMMON Block , preciso que se tenha um controle rigoroso para garantir que todas as variveis aparecem na mesma ordem, tendo o mesmo tipo e tamanho em todas as unidades que o contm. A seguir, so mostrados exemplos utilizando as opes COMMON, lista de argumentos e mdulos.

Opo 1 Lista de Argumentos


C programa exemplo utilizando lista de argumentos SUBROUTINE ROTINA(X) X = X + 20 END SUBROUTINE INTEGER C C = 15 CALL ROTINA(C) PRINT *, C= , C END Valor Impresso: C= 35

75

Opo 2 - COMMON
C programa exemplo utilizando COMMON SUBROUTINE ROTINA COMMON /VARIAVEL/ X X = X + 20 END SUBROUTINE INTEGER C COMMON /VARIAVEL/ C C = 15 CALL ROTINA PRINT *, C= , C END Valor Impresso: C= 35

Opo 3 - Mdulos
MODULE SHARE INTEGER C END MODULE SUBROUTINE ROTINA USE SHARE C = C + 20 END SUBROUTINE C programa exemplo utilizando MODULE USE SHARE C = 15 CALL ROTINA PRINT *, C= , C END Valor Impresso:

C= 35

76

8.8 - Passando arrays para Sub-Programas


H pelo menos cinco diferentes formas de passar arrays de tamanho desconhecido para sub-programas. Trs delas, foram herdadas do Fortran 77 e duas, so implementaes novas do Fortran 90. Considere a seguinte declarao e inicializao de um array 2 x 3: program unknown integer, parameter :: n = 2 integer, parameter :: m= 3 integer :: length = n*m integer, dimension(n,m) :: table table = reshape ((/1, 2, 3, 4, 5, 6/), (/n, m/) ) print *, Programa Principal print 100, table format ( , 3i5)

100

Resultado: 1 2 3 4 5 6

UTILIZANDO O ARRAY DECLARADO, SERO MOSTRADAS DIFERENTES FORMAS DE UTILIZ-LO EM SUBROTINAS


Passagem de Arrays para Sub-Rotinas - Tcnicas Tradicionais 1) Declarando array como vetor de um elemento, dentro da subrotina
Chamada no Programa Principal Subrotina

length = m*n subroutine ones (table, length ) call ones ( table, length) integer table(1) , length do I = 1, length table(I) = table(I) + 6 enddo print 100, ( table(I), I= 1, length ) 100 format (ones, 3i5 ) end subroutine ones

Resultado: 7 8 9 10 11 12

77

Esta tcnica esconde a forma (shape) do vetor na sub-rotina, mas preciso conhecer o nmero total de elementos para poder realizar qualquer operao com o array , tais como no do-loop e print. Ou seja, neste caso, no possvel escrever simplesmente (o sub-programa no sabe que o array possui seis elementos ): table = table + 6 ou print 100, table Alm disso, nenhuma das construes de array ou intrnsecas do Fortran90 podem ser utilizadas, pois table tem o mesmo tamanho, tanto no programa principal quanto na subrotina ONES, mas no tem a mesma forma (shape)

Compartilhando array de tamanho desconhecido atravs do caracter *.


O uso de um asterisco no dimensionamento de um array dentro de uma rotina, serve para defini-lo como sendo um array assumed size, ou seja, de tamanho conforme o que foi definido no programa principal. Chamada no Programa Principal Subrotina

length = m*n subroutine star(table, length) call star ( table, length ) integer table(*), length do I = 1, length table(I) = table(I) + 6 enddo print 100, (table(I), I = 1, length ) 100 format( star , 3i5 ) end subroutine star

Resultado: star 13 14 15 star 16 17 18

Tambm neste caso, o tamanho do array permanece desconhecido, porm nenhuma operao com arrays proveniente do Fortran 90 est disponvel

78

3) Declarando explicitamente o array, exceto para a ltima dimenso


O shape utilizado, mas o ltimo tamanho no especificado. Ou seja, estes arrays so declarados com tamanho explcito em todas as dimenses, exceto na ltima, que deixada ilimitada. Chamada no Programa Principal
length = m*n call asize ( table, length, n )

Subrotina
subroutine asize (table, length, n) integer table (n,*), length k = length/n do j = 1, k do I = 1, n table(I,j) = table(I,j) + 6 enddo print 100, ((table(I,j), I=1,n), j=1,k) 100 format (Assumed Size , 3i5) end subroutine asize

Resultado: Assumed Size 19 Assumed Size 22

20 23

21 24

Todas as restries discutidas para os dois exemplos anteriores ainda se aplicam a este caso. Somente as funes LBOUND, UBOUND, SIZE do Fortran90 so permitidas dentro da subrotina, mesmo assim para as dimenses declaradas explicitamente

Passagem de Arrays para Sub-Rotinas Tcnicas do Fortran90


No Fortran90, foram introduzidas duas tcnicas para esconder o shape e size de um array dentro de um subprograma. Tal escolha depende do fato de o sub-programa ser declarado como interno ou externo.

79

Sub-Programa Interno
Conforme foi visto, a declarao CONTAINS sinaliza o incio de um sub-programa interno. Os arrays nos subprogramas internos devem sempre ter o mesmo nmero de dimenses definido n programa principal, mas cada dimenso pode ter um nmero o qualquer de elementos

Exemplo 1 - Programa Principal com Subrotina Interna


program unknown . . call inside(table) . . contains subroutine inside(table) integer, dimension(:, :) :: table table = table + 6 print 100, table 100 format ('Assumed Shape ', 3i5) end subroutine inside end program unknown Resultado: Assumed Shape Assumed Shape

25 28

26 29

27 30

Neste sub-programa o formato(shape) do array table fixado em duas dimenses, concordando com o programa solicitante, enquanto que o tamanho de cada dimenso herdado dele. Todas as operaes do FORTRAN 90 para a manipulao de arrays so permitidas neste caso.

80

Sub-Programa Externo
Para os tradicionais subprogramas externos, a tcnica para array de tamanho assumido requer uma outra nova implementao do FORTRAN 90, a Interface Block. Tais blocos fazem a interface explcita entre procedures. program unknown interface subroutine ashape(table) integer, dimension(:,:) :: table end subroutine ashape end interface integer, parameter :: n = 2 integer, parameter :: m= 3 integer :: length = n*m integer, dimension(n,m) :: table . . call ashape(table) . end program unknown

81

8.9 Permisses de Acesso para parmetros passados para Mdulos e Sub-Programas


PUBLIC X PRIVATE
PUBLIC(default): especifica que elementos contidos em um mdulo so globais. Podero ser acessados fora do mdulo atravs da declarao USE PRIVATE: tornam os objetos contidos em um mdulo, acessveis somente dentro deste. No esto disponveis para o programa que acessa o mdulo via declarao USE Pode-se ter Tipos Derivados declarados dentro de mdulos com atributo PUBLIC, que contenham campos do tipo PRIVATE

Exemplo
MODULE M PRIVATE, REAL :: R, K, TEMP(100) ! R, K, TEMP so PRIVATE REAL, PUBLIC :: A(100), B(100) ! A e B so PUBLIC END MODULE M

INTENT
Este atributo especifica a forma de acesso aos parmetros passados para um subprograma (leitura, gravao, leitura e gravao); permite controle e proteo aos dados compartilhados entre unidades, sendo til na criao de bibliotecas e rotinas externas.

Argumentos utilizados na especificao deste atributo: IN : Os parmetros passados para o subprograma no podem ter seus valores alterados OUT : O parmetro ser definido dentro do subprograma e ter seu valor retornado para o programa principal INOUT : O parmetro ser utilizado para comunicao de informaes entre o programa principal e o subprograma, fornecendo valores a este e retornando com novos dados Obs: A declarao INTENT s pode ser utilizada dentro de sub-programas e Interfaces.

82

Exemplo
SUBROUTINE MOVE (FROM, TO) USE PERSON_MODULE TYPE(PERSON), INTENT(IN) TYPE (PERSON), INTENT(OUT) ....... SUBROUTINE SUB(X, Y) INTEGER, INTENT(INOUT)

:: ::

FROM TO

::

X, Y

OPTIONAL
Com este atributo, parmetros podem ser passados ou no para a procedure, dependendo de uma condio especfica. A funo Intrnseca PRESENT pode ser usada para testar a presena de um parmetro opcional dentro da procedure; este teste pode ser usado para controlar o processamento na procedure.

Exemplo
CALL SORT_X ( X = VECTOR_A ) ..... SUBROUTINE SORT_X (X, SIZEX, FAST) REAL, INTENT (INOUT) :: X (:) INTEGER, INTENT(IN), OPTIONAL :: SIZEX LOGICAL, INTENT(IN), OPTIONAL :: FAST ..... INTEGER TSIZE ..... IF (PRESENT(SIZEX) ) THEN TSIZE = SIZEX ELSE TSIZE = SIZE(X) END IF IF (.NOT. PRESENT(FAST) .AND. TSIZE > 1000 ) THEN CALL QUICK_SORT(X) ELSE CALL BUBBLE_SORT(X) END IF .... &

83

8.10 RECURSIVE FUNCTIONS RECURSIVIDADE EM SUBROTINAS E FUNES - FORTRAN 90


Os sub-programas tradicionais escritos em Fortran, no possuem caracterstica recursiva. Existem certos problemas que so mais facilmente resolvidos de forma recursiva. Como exemplo, a funo fatorial pode ser definida como:

n( n 1 )! ; n >= 1 N! = 1; n = 0
Esta definio pode ser implementada recursivamente, atravs de um procedimento que calcula N!, chamando a ele mesmo para calcular (N-1)! , que por sua vez calcula (N-2)! , etc, at calcular 0!. Para a resoluo de tais problemas, o Fortran permite que funes e subrotinas sejam declaradas como recursivas. Ou seja, se uma subrotina ou funo for declarada como recursiva, o compilador ir implement-la de forma que ela possa chamar a ela mesma, direta ou indiretamente. Para a utilizao da recursividade, uma FUNCTION ou SUBROUTINE dever ter sintaxe diferente daquela normalmente utilizada, contendo uma nova palavra-chave: RECURSIVE A declarao RECURSIVE, serve para que o compilador possa preparar a funo ou subrotina adequadamente para a sua auto-chamada ( atravs do uso de stacks para as variveis locais). O uso de uma function recursiva, ainda permite o uso da palavrachave RESULT, que servir para armazenar o valor final a ser retornado pela funo.

Sintaxe: <tipo> recursive function <nomedafuno> ( argumentos ) result ( varivel ) ou recursive <tipo> function <nomedafuno> ( argumentos ) result ( varivel )

Exemplo: Implementao de Funo Recursiva para calcular fatorial


recursive function fact(n) result(answer) integer :: n, answer if ( n >= 1 ) then answer = n * fact(n-1) else answer = 1 endif end function fact

84

9 ESTRUTURAS DINMICAS DE DADOS - Arrays e Pointers


No Fortran tradicional, somente era permitida a alocao de memria esttica, sequencial. Em muitas circunstncias, este modelo de alocao tornava-se dispendioso, sobretudo quando no era possvel precisar a priori, a quantidade de elementos que iriam ser utilizados no decorrer do programa. A utilizao de declaraes tais como o COMMON e o EQUIVALENCE, ajudava a resolver tal problema, permitindo o uso compartilhado de reas de memria por unidades diferentes de programa. No entanto, tais implementaes, alm de no resolver definitivamente o problema de alocao de recursos, ainda so consideradas inseguras: Um pequeno deslize na programao pode causar superposio e destruio indesejada de valores contidos na memria. J o Fortran90 oferece a possibilidade de uso de memria dinmica, permitindo a alocao de unidades de memria no decorrer da execuo do programa. Isto possvel atravs das seguintes implementaes: Arrays tipo allocatable Pointer Arrays tipo automatic arrays tipo assumed-shape

85

9.1 - ARRAYS ALOCVEIS ( ALLOCATABLE ARRAYS )


Se o nmero de elementos para a dimenso de um array no for especificado, isto significa que este dever ter o atributo Allocatable ou Pointer. O uso do atributo allocatable, exige que um array seja declarado com dimenses definidas e limites indefinidos. Ou seja, os limites de uma dada dimenso estabelecida durante a execuo do programa. Isto evita o tradicional super-dimensionamento de arrays no incio dos programas. Um array declarado com este atributo, somente estar disponvel aps a utilizao da declarao ALLOCATE. INTEGER N REAL, DIMENSION (:), .... N = 50 ALLOCATE ( WORK(N) ) .... .... .... END

ALLOCATABLE

::

WORK

Exemplo
Temperatura medida nas escalas: Fahrenheit, Celsius e Kelvin. A alocao do array com limites que variam em cada escala, pode ser feita da forma a seguir: program temperatura integer, dimension( : ), allocatable :: graus integer :: erro integer, dimension(3, 2) :: limites = & / -460, 0, -274, 212, 100, 374 / integer :: escala = 0 logical :: true_false print *, 'Fahrenheit, Centigrados ou Kelvin? ( 1, 2, 3 ) ' read (*,*) escala allocate ( graus(limites(escala,1):limites(escala,2),stat=erro) if (erro.eq. 0) then print *, 'Erro de Alocao: ') else print *, 'GRAUS alocado de ', & limites(escala,1) ', 'ate ',limites(escala,2) endif end program temperatura

86

Observao: Ateno disposio dos valores iniciais no array limites!


Se por algum motivo, a memria no puder ser alocada, o status do comando allocate devolver algum valor positivo

ALLOCATED
Informa se um array j foi alocado ou no Exemplo: true_false = allocated(graus) if ( true_false ) then print *, 'Array GRAUS ja foi alocado' else print *, ' Array nao possui limites definidos' endif

DEALLOCATE
Libera memria anteriormente alocada para um array.

Exemplo 1 - utilizao do comando deallocate


deallocate ( graus, stat=erro ) if ( erro .ne. 0 ) then print *, 'Erro! Array nao foi alocado anteriormente! ' endif

Exemplo 2 - utilizao do comando deallocate ao final do uso do array


program query_array_size integer, dimension(:), allocatable integer :: array_length :: array

write (*, 100, ADVANCE='NO') 100 format ( ' ', 'Entre com o tamanho do array : ' read (*, *) array_length allocate ( array(array_length)) ... ! operacoes com o array.... deallocate(array) end program query_array_size

87

Arrays alocveis no podem aparecer definidos em um COMMON. Sendo assim, como ento passar arrays alocveis para sub-programas? A soluo atravs da estrutura MODULE que deixa o array disponvel para subprogramas da seguinte forma: module global integer, dimension(:) , allocatable end module global
Para disponibilizar o mdulo em um programa, utilize a declarao USE:

::

graus

use global

Observao: O resultado (RESULT) de uma funo recursiva no pode ser um array alocvel. Esta implementao pode ser substituida por POINTERs e TARGETs.

9.2 - POINTERS
Pointers (ponteiros) so tipos especiais de variveis que contm o endereo de memria de outra varivel que contm um valor. Uma vez que novas variveis podem ir sendo endereadas dinamicamente, estas estruturas so teis quando necessrio criar e destruir variveis durante a execuo do cdigo e quando no conhecido o nmero total de variveis a serem utilizadas. O uso de ponteiros possibilita a criao de: Sees dinmicas de arrays Estruturas de dados ajustveis Listas linkadas rvores Grafos

Exemplo 1
REAL, TARGET :: REAL, POINTER :: A => B B(10,10) A( :, : )

88

Exemplo 2
program point integer, pointer :: p, q integer, target :: n integer m n = 5 p => n q => p allocate (p) p = 4 m = p + q + n print *, m=, m end program point

O significado do atributo TARGET


Um pointer uma varivel, que contm a locao de memria de outra varivel, com atributo target. O target uma varivel comum, de mesmo tipo do pointer. Se o target uma varivel comum, por que necessrio associar este atributo especial para a mesma? Outras linguagens tais como o C, no trabalham desta forma. A razo deve-se forma como os compiladores FORTRAN funcionam. O FORTRAN normalmente usado para problemas numericamente intensivos e os compiladores contm implem entaes para produzir resultados o mais rpido possvel. Estes compiladores incluem um otimizador como parte do processo de compilao do algoritmo. O otimizador examina o cdigo, re-arranja, desmembra loops, elimina subexpresses comuns e etc., a fim de aumentar a velocidade final de execuo. Como parte deste processo de otimizao, algumas variveis no programa original podem desaparecer no processo de compilao, tendo sido combinadas ou substitudas por valores temporrios nos registradores. Ento, o que aconteceria se uma varivel que desejamos apontar, fosse otimizada, deixando de existir? Ocorreria um erro ao apont-la! possvel para o compilador, analisar um programa e determinar quando ou no cada varivel individual ser utilizada como um target, mas o processo pouco prtico. Sendo assim, o atributo target diz ao compilador que uma determinada varivel ser utilizada por um pointer e que por isto, no deve ser eliminada durante o processo de compilao do cdigo.

89

Exemplo 3 - Exemplo de POINTER associado a um TARGET, durante a execuo do programa.


program switch integer, target :: a(2, 2) integer, target :: b(3, 3) integer, pointer :: p( :, : ) a = reshape ( / 1, 2, 3, 4 /), (/ 2, 2 /) b = reshape (/ 5, 6, 7, 8, 9, 10, 11, 12, 13 /), ( / 3, 3 /) write ( *, 100, advance = 'NO ') 100 format ( ' ', Selecione a(2,2) ou b( 3,3 ) ,& digite a ou b : ' ) read (*,*) choice if ( choice .eq. 'a' ) p => a if ( choice .eq. 'b' ) p => b print *, ' Ponteiro direcionado para array ', choice, ': ' print *, ' P = ', p nullify (p) end program switch

O atributo target informa ao computador quais so as variveis que podem ser utilizadas por ponteiros O smbolo => associa um target a um pointer Um pointer tem trs estados possiveis: Associated, Disassociated ou Undefined Veja o exemplo de uso de POINTER no cdigo HEAT.F95

Exemplo Cdigo completo: Insero e remoo de elementos de uma lista de ponteiros


PROGRAM POINT TYPE LISTA INTEGER :: NUM TYPE(LISTA), POINTER :: PROXIMO END TYPE LISTA TYPE(LISTA), POINTER ALLOCATE(INICIO) :: INICIO, PROX, TEMP

PROX => INICIO DO PRINT *, 'ENTRE COM UM NUMERO:' READ *, PROX%NUM

90

IF (PROX%NUM == 0) EXIT ALLOCATE(PROX%PROXIMO) PROX => PROX%PROXIMO ENDDO NULLIFY(PROX%PROXIMO) ! IMPRESSAO DOS NUMEROS DIGITADOS PROX => INICIO DO IF (.NOT. ASSOCIATED(PROX%PROXIMO)) EXIT WRITE(*,*) PROX%NUM PROX => PROX%PROXIMO ENDDO ! ROTINA PARA INSERIR ELEMENTO NA LISTA (APS 4. ELEMENTO) CALL INSERE ! ROTINA PARA RETIRAR ELEMENTO DA LISTA (O 4. ELEMENTO) CALL REMOVE CONTAINS SUBROUTINE INSERE PROX => INICIO I = 1 DO WHILE (I < 4) PROX => PROX%PROXIMO I = I + 1 ENDDO ALLOCATE(TEMP) PRINT *, 'DIGITE NUMERO A SER INSERIDO:' READ *, TEMP%NUM TEMP%PROXIMO => PROX%PROXIMO PROX%PROXIMO => TEMP ! IMPRESSAO DOS NUMEROS DA LISTA PROX => INICIO DO IF (.NOT. ASSOCIATED(PROX%PROXIMO)) EXIT WRITE(*,*) PROX%NUM PROX => PROX%PROXIMO ENDDO END SUBROUTINE INSERE

! SUBROTINA PARA REMOCAO DE NUMERO

91

SUBROUTINE REMOVE PROX => INICIO I = 1 DO WHILE (I < 4) PROX => PROX%PROXIMO I = I + 1 ENDDO PROX = PROX%PROXIMO ! DEALLOCATE (PROX%PROXIMO) ! IMPRESSAO DOS NUMEROS DA LISTA
PROX => INICIO DO IF (.NOT. ASSOCIATED(PROX%PROXIMO)) EXIT WRITE(*,*) PROX%NUM PROX => PROX%PROXIMO ENDDO END SUBROUTINE REMOVE ! OBS: OBRIGATORIO A ESPECIFICACAO: SUBROUTINE <NOME> END ! FIM PROGRAMA PRINCIPAL

9.3 - ESTRUTURAS DINMICAS DE DADOS LISTAS LINKADAS

A tcnica bsica para a utilizao de uma lista linkada criar um tipo derivado que consistir de um ou mais elementos de dados e pelo menos um ponteiro. Sendo assim, a memria alocada para conter o dado e o ponteiro setado para a prxima ocorrncia de dado. Se houver apenas um ponteiro a lista simplesmente linkada e poder ser percorrida em apenas uma direo.

Exemplo 1 Cdigo completo: Insero de elementos na lista linkada


Program lista_link type person integer :: age character(len=50) :: name type (person), pointer :: forward end type person type (person), pointer :: inic, prox

92

type (person) :: temp integer :: io temp % age = 0 temp % name= ' ' nullify ( temp%forward ) allocate( inic ) if (.not. associated (inic)) stop "erro de alocacao" ! primeiro passo - le para a lista prox => inic do prox = temp read (*,*,iostat=io) prox%age, prox%name if ( io < 0 .or. prox%age .eq. 0) exit allocate(prox%forward) if ( .not. associated (prox%forward)) stop "erro" prox => prox % forward end do 100 continue ! imprime prox => inic do if (.not. associated ( prox%forward ) exit write (*,*) prox%age, prox%name prox => prox%forward end do end

9.4 - AUTOMATIC ARRAYS


Os arrays criados so locais e temporrios. A memria para o array alocada quando o subprograma inicia e liberada ao final da execuo do mesmo.

Exemplo
SUBROUTINE SOMA(I,J,K) REAL, DIMENSION(I,J,K) :: X ou SUBROUTINE SOMA(I,J,K) REAL :: X(I,J,K)

93

10 - MIXED LANGUAGE PROGRAMMING


A seguir, so mostrados alguns exemplos de interao entre cdigos escritos em FORTRAN e outras linguagens (C, Visual Basic, Delphi).

10.1 Visual Basic x FORTRAN90


Programa Principal em VISUAL BASIC e Subrotina em FORTRAN 90. A Subrotina em FORTRAN salva como DLL e chamada dentro do VISUAL BASIC para clculos.

I - PARTE FORTRAN (DLL)


subroutine ROTINA_FORTRAN (IEP, NMAT, rT1, rT2, RCALOR, TRMAX1) !DEC$ ATTRIBUTES DLLEXPORT :: ROTINA_FORTRAN !DEC$ ATTRIBUTES ALIAS:' ROTINA_FORTRAN ' :: ROTINA_FORTRAN

IMPLICIT NONE INTEGER NDIV parameter (ndiv = 10)

! DEFINICAO DAS VARIAVEIS EXTERNAS - RECEBIDAS DO VISUAL BASIC

INTEGER, INTENT(IN) REAL(8), INTENT(IN) REAL(8), INTENT(IN)

:: :: ::

IEP, NMAT rT1, rT2 rCALOR(*)

DEFINICAO DAS VARIAVEIS ENVIADAS PARA O VISUAL BASIC

REAL(8), INTENT(OUT) :: TRMAX1(40,2)

94

II - PARTE VISUAL BASIC DECLARACOES PUBLICAS DA ROTINA E CHAMADA. FOI CRIADO UM MODULE DENTRO DO PROJETO VB
'Declarao da DLL Declare Sub ROTINA_FORTRAN Lib "ROTINA_FORTRAN.dll" Alias " ROTINA_FORTRAN " (ByVal dir As String, ByVal nc As Long)

10.2 FORTRAN90 X C
I PROGRAMA PRINCIPAL EM FORTRAN QUE CHAMA SUBROTINA EM C
NO VISUAL FORTRAN NECESSRIO CRIAR INTERFACE PARA COMPARTILHAR VARIAVEIS QUE SERO PASSADAS COMO PARAMETROS PARA AS ROTINAS EM C. NOS SISTEMAS LINUX, BASTA COMPILAR OS PROGRAMAS SEPARADAMENTE E DEPOIS LINK-EDIT-LOS, TENDO O CUIDADO DE COMPATIBILIZAR OS TIPOS DE VARIVEIS ENTRE AS LINGUAGENS.

INTERFACE SUBROUTINE routine1(a, b, c) !DEC$ ATTRIBUTES C :: routine1 INTEGER real(8) C A(*), B(*)

END SUBROUTINE routine1 END INTERFACE

REAL(KIND=8), DIMENSION(3) :: A = (/1., 2.,3./) REAL(KIND=8), DIMENSION(2) :: B = (/100.,200./) INTEGER :: C = 1000 CALL ROUTINE1(A,B,C) print * END

95

#include <stdio.h> void routine1 (a, b, c) double *a, *b; int c; { int x; printf ("%d\n",c); for(x=0;x< 1;x++); { printf("%d,%f\n",x,a[x]); } }

10.3 PROGRAMA PRINCIPAL EM DELPHI FUNO EM FORTRAN90


I - PROGRAMA .PAS DELPHI
unit Calldvf1; interface uses SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, DVFRoutines; type TFCallDvf = class(TForm) LGetInteger: TLabel; LGetFloat: TLabel; LGetString: TLabel; EGetInteger: TEdit; EGetFloat: TEdit; EGetString: TEdit; BCallFortran: TButton; LPutInteger: TLabel; LPutFloat: TLabel; LPutString: TLabel; EPutInteger: TEdit; EPutFloat: TEdit;

96

EPutString: TEdit; BOk: TButton; BClear: TButton; procedure BCallFortranClick(Sender: TObject); procedure BOkClick(Sender: TObject); procedure BClearClick(Sender: TObject); private { Private declarations } public { Public declarations } end; var FCallDvf: TFCallDvf; implementation {$R *.DFM} procedure TFCallDvf.BCallFortranClick(Sender: TObject); var tmpInt1 : Longint; tmpInt2 : Longint; tmpSingl1 : Single; tmpSingl2 : Single; tmpPChar2 : array[1..80] of Char; tmpPCharLen : Longint; begin tmpInt1 := strToInt(EGetInteger.Text); tmpInt2 := FortFunInt(tmpInt1); EPutInteger.Text := intToStr(tmpInt2); tmpSingl1 := strToFloat(EGetFloat.Text); tmpSingl2 := FortFunSingle(tmpSingl1); EPutFloat.Text := FLoatToStr(tmpSingl2); tmpPCharLen := 80; FortFunString(@tmpPChar2, tmpPCharLen, PChar(EGetString.Text)); EPutString.Text := tmpPChar2; BOk.default := true; end; procedure TFCallDvf.BOkClick(Sender: TObject); begin close; end; procedure TFCallDvf.BClearClick(Sender: TObject);

97

begin EGetInteger.clear; EGetFloat.clear; EGetString.clear; EPutInteger.clear; EPutFloat.clear; EPutString.clear; BCallFortran.default := true; BOk.default := false; end; end.

II - PROGRAMA FORTRAN COM INTERFACE PARA DELPHI


! This Fortran code is intended to be called from another language ! In this sample, that is Borland Delphi ! There are three routines in this file: ! Function FortFunInt (integer*4 IArg) ! returns 2xIarg as Integer*4 ! Function FortFunSingle (real*4 FArg) ! returns SQRT(Farg) or 0 if Farg < 0 ! Function FortFunString (string Sarg) ! returns a string with the case inverted ! The string argument is passed by reference only ! and the return argument is returned in hidden ! first and second arguments. ! This project is provided as x86-only INTEGER*4 Function FortFunInt (iArg) !DEC$ ATTRIBUTES STDCALL, DLLEXPORT :: FortFunInt !DEC$ ATTRIBUTES ALIAS : "_fortfunint" :: FortFunInt integer iArg; FortFunInt = 2*iArg return end function FortFunInt Real*4 Function FortFunSingle (fArg) !DEC$ ATTRIBUTES STDCALL, DLLEXPORT :: FortFunSingle !DEC$ ATTRIBUTES ALIAS : "_fortfunsingle" :: FortFunSingle Real *4 fArg if (fArg .le. 0) then FortFunSingle = 0

98

else FortFunSingle = SQRT(fArg) endif return end function FortFunSingle Character *(*) function FortFunString (sArg) Implicit none !DEC$ ATTRIBUTES STDCALL, DLLEXPORT :: FortFunString !DEC$ ATTRIBUTES ALIAS : "_fortfunstring" :: FortFunString character(255) sArg !Passed in as a null-terminated string !DEC$ ATTRIBUTES REFERENCE :: sArg Integer lenInput integer lenOutput Integer i, j lenInput = index(sArg, char(0)) lenOutput = len(FortFunString)-1 i = min(leninput, lenoutput) do j=1, i if (sArg(j:j) .le. 'z' .and. sArg(j:j) .gt. 'a') then FortFunString(j:j) = char (ichar(sArg(j:j)) - 32) else if (sArg(j:j) .le. 'Z' .and. sArg(j:j) .gt. 'A') then FortFunString(j:j) = char (ichar(sArg(j:j)) + 32) else FortFunString(j:j) = sArg(j:j) endif endif enddo FortFunString(i+1:i+1) = char(0) return end

99

11- REFERNCIAS
Stephen J. Chapman; Fortran 90/95 for Scientists and Engineers, Mc -Graw-Hill, Boston, USA, 1998 James Kerrigan; Migrating to Fortran90, OReilly & Associates, Inc. William Press [et al.]; Numerical Recipes in Fortran, Cambridge University Press, 1992 http://www.nsc.liu.se/~boein/FORTRAN 77to90 - Tutorial and Exercises http://acesgrid.org/ - The Alliance for Computational Earth Science (ACES) at M.I.T focuses on developing and deploying advanced computational technologies to address challenging problems of Earth science. ACES is a platform for cross-disciplinary collaboration between Earth science researchers and computer science researchers at MIT. Several different groups are participating in the ACES effort - you can read about some of their projects on this web site.

http://www.kcl.ac.uk/kis/support/cit/fortran/engfaq.html - Fortran 90 Frequently Asked about News http://www.openmp.org/drupal/ - The OpenMP Application Program Interface (API) supports multi-platform shared-memory parallel programming in C/C++ and Fortran on all architectures, including Unix platforms and Windows NT platforms. Jointly defined by a group of major computer hardware and software vendors, OpenMP is a portable, scalable model that gives shared-memory parallel programmers a simple and flexible interface for developing parallel applications for platforms ranging from the desktop to the supercomputer. http://www.posc.org/ - POSC, the Petrotechnical Open Standards Consortium, is an international, not-for-profit, membership organization. POSC is uniquely designed to unite industry people, issues and ideas to collaboratively address E&P information challenges and opportunities. POSC's energy eStandards are open specifications for improving E&P business performance by leveraging Internet technologies in the integration of oil and gas business processes.

100

Você também pode gostar