You are on page 1of 88

INTRODUO AO VISUAL FORTRAN CVF

Wilton, Cleide e Cleiton Diniz P. S. e Silva

Programador:

Aula n 1 - Apresentao, O Developer Studio, Forma Fixa e Forma Livre,


Entrada e Sada de Dados, Variveis e Formatos, Abertura e Leitura de Dados:
o IOSTAT, Programa: programa fonte, programa objeto (compilao) e programa
executvel (linking), O Help do Estdio. Ento, o CVF ser aberto com a seguinte aparncia:

1 - Apresentao
FORmula TRANslation: primeira linguagem de alto nvel.

Proposta: clculos matemticos.

Fortran 77 original: sem recursos visuais; pobre interface com o usurio.

Fortran 90/95: muitos recursos grficos. Possibilita a criao de softwares


com interface amigvel. Permite a compilao de programas desenvolvidos em
Fortran com subprogramas desenvolvidos em C, gerando um nico executvel.

2 - O ambiente do Developer Studio (ou do PowerStation)

Para acessar o estdio Compaq Visual Fortran (CVF) voc deve clicar em
Iniciar e ento escolher Programas. Depois, voc deve selecionar Compaq
Visual Fortran e, em seguida, clicar em Developer Studio, conforme mostra
a figura a seguir:

O estdio de desenvolvimento do Compaq Visual Fortran (CVF) tem o seguinte


aspecto geral, visto atravs de uma figura copiada de um projeto chamado
Teste:
b) A janela de edio (programas, funes, subrotinas, mdulos, cones,
bitmaps, dilogos): lado direito.
Alm dos menus e das barras de ferramentas, vistos na parte superior da
figura, pode-se observar tambm trs janelas principais, a seguir destacadas.

Trs janelas principais:

a) A janela com os componentes do projeto (Programa principal, subprogramas,


informaes do editor de recursos, pasta com informaes sobre dependncias,
etc.): lado esquerdo. Veja, a seguir, uma figura mostrando tal janela,
recortada de um projeto chamado Equation:

c) A janela de informaes sobre compilao e link entre o programa


principal e os subprogramas (subroutine e function): parte inferior.
Impresso:

WRITE(2 , 15) B

A declarao anterior significa: escreva o valor de "B" na unidade 2 no


formato definido no endereo (label) 15.

Default para read e write:

READ(* , *) J

e
3 - Forma Fixa e Forma Livre para o Cdigo Fonte de um Programa WRITE(* , *) B
Forma fixa: extenso FOR, muitas restries: As declaraes anteriores significam:
a) o cdigo escrito da coluna 7 at a 72. Para continuar um comando em 1) leia o valor de "J" informado via teclado, no formato default,
outra linha, a linha de continuao deve ter um caractere na coluna 6,
indicando que se trata de uma continuao de linha. 2) escreva o valor de "B" na tela no formato padro.
b) variveis com at 6 caracteres maisculos (em alguns compiladores). O
primeiro no pode ser numrico.

c) as colunas de zero a cinco so reservadas para os endereos numricos 5 - Variveis e Formatos


(label) dos comandos.
Variveis inteiras:

Forma livre: extenso F90, poucas restries: Iniciadas por I, J, K, L, M e N, ou por qualquer letra se declaradas, no
incio do programa, assim:
a) o primeiro caractere de uma varivel no pode ser numrico.
INTEGER A, BC
b) continuao de linha: usa-se o smbolo & (e comercial), que deve ser
colocado no fim da linha a ser continuada. Lembre-se que a declarao deve ser feita no incio do programa.

Formato para variveis inteiras:


4 - Entrada e Sada de Dados
10 FORMAT(In)
Abertura de um arquivo para ler ou escrever dados:
A declarao anterior significa que o formato definido no endereo 10 de
um inteiro com n algarismos (mas n deve ter um valor definido l na
OPEN(UNIT = 1, FILE ='NAME.EXT')
declarao).
NAME.EXT o nome do arquivo e sua extenso.
Exemplo:

10 FORMAT(I3)
Leitura:
No caso desse exemplo, o inteiro pode ter at 3 algarismos como, por exemplo,
READ(1 , 10) J
325
A declarao anterior significa: leia o valor de "J" na unidade 1 no formato
definido no endereo (label) 10.
Variveis reais:
Fechamento de um arquivo aps o fluxo de informaes: Iniciadas por qualquer letra exceto I, J, K, L, M e N ou, se iniciadas por
essas letras, forem definidas assim: REAL I, JAB.
CLOSE(UNIT = 1)
Formato exponencial para variveis reais: OPEN(UNIT = 4, FILE = 'DADOS.TXT', STATUS = 'OLD', IOSTAT = IERR)

15 FORMAT(Em.n) O comando anterior manda abrir a unidade 4, que o arquivo dados.txt, e sua
situao old, significando que ele j existe. Caso o arquivo exista mesmo,
A declarao anterior significa que o formato definido no endereo 15 o de o inteiro IERR ser igual a zero. Se no, IERR ser diferente de zero, mas a
um real que tem n algarismos significativos (m e n tm que serem definidos execuo do programa no interrompida.
na declarao). Ateno: m-n = 6 o nmero de dgitos necessrios somente
para simbolizar o formato exponencial.
Leitura de variveis
Exemplo:
Ao dar o comando
15 FORMAT(E16.10)
READ(* , * , IOSTAT = IERR) A
No exemplo anterior de FORMAT o real ter 10 algarismos significativos, mas
para escrev-lo sero necessrios 16 dgitos como no exemplo: espera-se que o programa leia um valor real para A (a menos que "A" tenha
sido declarado de outra forma). Devido ao uso do IOSTAT, se for teclada uma
0.5214558972E+05 letra, e no um real, a execuo do programa prossegue, mas IERR diferente
de zero, e o programador pode ter previsto uma ao a ser tomada pelo
Ateno: para evitar a declarao FORMAT voc pode, no programa, ler ou programa nesse caso.
escrever uma varivel assim:

READ(3 , "(e16.10)") a

WRITE(* , "(I4)") iba


7 - Problema: desenvolver um programa, que ser descrito a
seguir.
Note que o formato inserido (entre aspas) no local onde o endereo do
format seria definido. Antes mesmo de saber do que se trata, necessrio dar alguns passos
iniciais para o desenvolvimento do programa.
OBS: muito embora em Fortran voc possa declarar, de forma implcita,
variveis inteiras e reais atravs da letra inicial da varivel, Passos iniciais:
recomendvel que todas as variveis sejam declaradas (o que elimina o risco
de escrever uma varivel com erro na digitao). Para que o compilador no 1) No menu File do Compac Visual Fortran (CVF), clique em New.
aceite a declarao implcita do tipo de varivel voc deve declarar, no
incio do programa, o seguinte:

IMPLICIT NONE

Embora estejamos fazendo essa recomendao, no projeto que desenvolveremos


ao longo das lies, ns no faremos uso dessa declarao.

6 - Avanos na Abertura de Arquivos e Leitura de Variveis:


IOSTAT (Situao da Entrada ou da Sada)
Abertura de um arquivo

Status de um arquivo: o STATUS define a situao do arquivo. Se j existe,


ele tem

STATUS = 'OLD'

Se est, na abertura, sendo criado, ele tem


Vai aparecer uma caixa de dilogo chamada New.
STATUS = 'NEW'
2) Na caixa de dilogo chamada New, com a aba em Projects selecione
Se houver uma informao errada do status, a execuo do programa 'Fortran Standard Graphics or QuickWin Application' e, na caixa de edio
interrompida. Para contornar o problema, um arquivo pode ser aberto assim: chamada project name d o nome 'Equation' ao projeto. Clique em 'OK'.
Lembre-se que QuickWin o tipo de aplicao que estudaremos (programao
simplificada para Windows). passos para criar um projeto no PS.

3) No menu File clique em New e depois, com a aba da caixa de dilogo New
em 'Files' selecione 'Fortran Free Format Source Files' para escrever o
programa fonte. Na edit Box File name d o nome Teste1 (a extenso ser,
automaticamente, .f90) ao arquivo do programa fonte e clique em OK para
ativar a janela de edio do programa fonte.

Naturalmente, voc poderia alterar a locao para a criao do projeto


atravs da edit Box chamada Location, mas recomendvel trabalhar na
locao default criada pelo prprio compilador.

Assim, se voc estiver trabalhando no PowerStation (PS), um subdiretrio foi


aberto em

C:\MSDEV\PROJECTS\EQUATION 8 - O Programa Fonte


com o nome Equation. Faremos o primeiro programa nele (os arquivos j 4) Na janela de edio de programas fonte que surgir (a janela da
criados pelo compilador no momento da criao do projeto e o arquivo que direita), desenvolva o fonte de um programa que leia os reais A, B e C,
criaremos com o programa fonte ficaro nesse subdiretrio). informados a partir do teclado, e que escreva na tela os valores lidos.
Inicie o seu programa com a declarao
Se voc estiver trabalhando no Digital Visual Fortran (DVF), o subdiretrio
foi aberto em PROGRAM TESTE1

C:\Program Files\DevStudio\MyProjects\Equation (teste1 s o nome dado, pode ser qualquer nome). Para o computador parar,
aps os comandos serem executados pelo programa (ou em um determinado ponto
J se voc estiver trabalhando no Compaq Visual Fortran (CVF) o subdiretrio qualquer), d o comando
foi aberto em
STOP
C:\Program Files\Microsoft Visual Studio\MyProjects\Equation
No final do programa fonte, d o comando
Ateno: existem pequenas diferenas no processo de abertura, de uma verso
para outra, e apresentamos aqui os passos referentes verso CVF. No END
resumo da lio (primeiro item do menu 'Tutorial') so apresentados os
informando ao compilador o final fsico do arquivo com os comandos.

5) No menu File, salve o programa fonte clicando em Save. O nome do fonte 10 - Linking
j foi dado anteriormente:
9) Com a compilao, foi gerado um programa objeto chamado teste1.obj. Para
TESTE1.F90 criar um programa executvel (se no houver erros de compilao), clique no
menu Build e selecione o item Build Equation.exe. Depois, para executar o
(.f90, forma livre). Se no incio do processo voc tivesse optado pela forma programa, clique no menu Build e selecione o item Execute Equation.exe.
fixa, ao invs da livre, o nome do arquivo seria TESTE1.FOR, e voc deveria Genericamente, ao clicar no item Build Equation.exe, voc ligar (link)
ter seguido regras mais rgidas para criar o seu programa fonte.
todas as peas de seu programa, gerando um nico programa executvel (que
ter o nome do projeto). Conforme ser visto em lies futuras, seu software
6) O programa fonte j est no diretrio criado e, no caso do CVF, j faz
constitudo das seguintes peas: um programa principal (desenvolvido por
parte do projeto. (Se voc tivesse trabalhando no PS ainda deveria incluir o
voc) e de subrotinas e funes que sero desenvolvidas por voc, ou que j
arquivo no projeto. Para tal, no menu Insert voc clicaria em 'Files into
estaro disponveis no estdio, e que voc vai apenas usar. A ligao dessas
project...', selecionando o programa fonte e clicando no boto Add).
unidades de programa j compiladas (programas objeto) em um nico executvel
conhecida como operao de linking (link).

9 - Compilao
7) Para observar que o seu programa realmente j faz parte do projeto,
11 - Idia Global no Desenvolvimento de um Programa
clique na caixinha 'Equation files' na janela esquerda, que contm os
elementos do projeto. Clicando, depois, em Source Files (a primeira dentre Para desenvolver um programa, por mais simples que ele seja, as seguintes
as trs caixinhas amarelas) dever aparecer o arquivo teste1.f90, que j etapas so sempre seguidas:
pode ser compilado. A compilao uma operao que visa detectar erros de
programao (de sintaxe e de estrutura dos comandos) e, na ausncia de
erros, h a criao do programa objeto correspondente ao programa fonte.

8) Para compilar o programa fonte marque o arquivo que o contm (d um


clique com o mouse sobre o arquivo, na janela da esquerda): teste1.f90. O
nome do arquivo fica marcado em azul. Depois clique no menu Build e
selecione o item Compile teste1.f90.
O(s) programa(s) fonte(s) (so) constitudo(s) pelo conjunto de cdigos
escritos pelo programador. Ao compilar o(s) programa(s) fonte(s), o
compilador cria programa(s) objeto(s) correspondente(s) ao(s) programa(s)
fonte(s). Programa(s) objeto(s) (so) o(s) arquivo(s) intermedirio(s) que
(so) ligado(s) para gerar o programa executvel.

12 - Comentrios
Veja, a seguir, o programa fonte do problema proposto. Nele, tem coisas do
tipo:

a) WRITE(*,*) ' Valor de A'

Esse comando escreve, na tela, o string ' Valor de A'. Na tela, os


apstrofes no aparecem.

b) WRITE(*,*) ' ' ! Linha em branco

A exclamao indica que aquilo que vem a seguir um comentrio, no um


comando executvel.

c) Ao executar o programa voc deve ter notado que:

Acompanhe a compilao na janela retangular inferior mostrada anteriormente. 1 - O mouse j faz parte do programa,
2 - Ainda no temos um cursor,

3 - No frame temos um menu default,

4 - A child window ainda preta e tem o nome genrico


de Graphic1,

5 - O nome do frame o do executvel (do projeto).

6 - O programa executvel foi criado quando voc, no menu


'Build', clicou no item 'Build Equation.exe'. Esse
programa executvel est disponvel num subdiretrio
chamado Debug, na pasta aberta pelo Developer Studio
quando voc criou o projeto (workspace) Equation.

7 Para compreender cada comando em detalhes voc deve utilizar o


HELP do seu estdio. l que est a totalidade das informaes
online que voc pode acessar.

13 - O Help do Estdio CVF


O menu Help do CVF 6 tem o seguinte aspecto geral

Para obter mais informaes, voc pode investigar os outros itens da lista,
apontando o mouse e dando um duplo clique no item apontado.

14 - Esboo do Programa Proposto


!Programa que l e escreve na tela os reais A, B e C.
program teste1 !Esta a abertura do programa

write(*,*) 'Escreva o valor de A'


Suponha que voc queira investigar um comando. Ento, voc deve clicar em
Search que o Help, propriamente dito, ser disponibilizado pelo CVF. read(*,*)a !Leia o valor de A
Ento, com a aba de seleo clicada em ndice (ao invs de Search, voc
poderia clicar direto em Index...), voc deve escrever a palavra-chave que write(*,*) 'Escreva o valor de b'
deseja localizar. Digitando-se READ, por exemplo, vo aparecer vrios temas
que mencionam a palavra-chave. D um duplo clique read(*,*)B !Leia o valor de b
na primeira palavra da lista (em maisculas) que coincida com a sua e, na
janela do lado direito, as informaes sero disponibilizadas. No nosso write(*,*) 'Escreva o valor de C'
caso, para a palavra READ, tem-se:
read(*,*)C !Leia o valor de C

write(*,*)' ' !Linha em branco

write(*,*)' '

write(*,*)' Valores de A, B e C:'


write(*,*)' '
1) Na sada de dados do programa, mude cada write(*,*)constante para um
write(*,*) a, B, C formato especfico como, por exemplo:

!ateno: as trs linhas anteriores poderiam write(*,'(E13.7)')A


!ser substitudas pelas duas seguintes:
!write(*,10) a, B, C
!10 format(1x,'A = ',e12.6,3x,'B = ',e12.6,3x,'C = ',e12.6)
16 - Avance Mais ainda: O Uso do IOSTAT
!ou ainda pela seguinte linha:
2) Execute o programa que voc fez e informe um valor literal para os seus
!write(*,"(1x,'A = ',e12.6,3x,'B = ',e12.6,3x,'C = ',e12.6)") a, B, C dados. Veja o que acontece. Modifique o seu programa para ler os dados
usando o recurso do iostat, conforme visto anteriormente:
stop !pare a execuo (acabou as tarefas)
Read(*,*,iostat = ierr)a
end !final fsico desse arquivo que contm o programa
Faa a mesma coisa para ler tambm b e c e, depois de cada read, mande
escrever na tela o valor de ierr. Reexecute o programa informando valores
reais para os parmetros, e observe o valor correspondente para ierr.
Depois da execuo do programa tem-se uma tela com o seguinte aspecto: Depois, execute o programa informando valores literais para os parmetros e
veja, nesse caso, o valor de ierr. Voc deve ter concludo que ierr = 0
significa algo como zero erro, isto , a operao de leitura foi feita com
sucesso.

3) Crie um arquivo de texto e chame-o de dados. Para tal, no menu File


cicle em New. A caixa de dilogo New vai aparecer com a aba em Files.
Selecione a ltima opo, Text File, conforme mostrado a seguir:

A janela preta no primeiro plano (Graphic1) recebe o nome genrico de Child


Window enquanto que a janela de fundo chamada de Frame Window.

15 - Avance um Pouco Mais: O Uso de Format


Clique OK e, ento, na janela de edio, escreva os valores de A, B e C no
arquivo:

Ento, salve o arquivo de dados, que ter o nome Dados.txt (porque a


criao foi de um arquivo de texto).

Modifique o seu programa para abrir o arquivo de dados e ler os valores de


A, B e C. Lembre-se de abrir o arquivo de dados com o comando

OPEN(UNIT = 4, FILE = 'DADOS.TXT', STATUS = 'OLD', IOSTAT = IERR)

Como o arquivo dados.txt foi referenciado com o nmero 4 (unit = 4), a


leitura de A, por exemplo, deve ser feita assim:

Read(4,*,iostat = ierr)A
Write(*,*)ierr
Aps escolher a opo todos os arquivos (*.*) (na figura, destacada em
Execute o programa e veja os valores de ierr para cada comando. azul) selecione o arquivo resultados.dat clicando, finalmente, no boto
Abrir. Voc ver, ento, o valor da soma S escrito no arquivo.

4) Modifique o status da abertura do arquivo de old para New (que


significa: o arquivo novo, ser criado agora, na execuo). Como de fato o
arquivo j existe, execute o programa e inspecione o valor de ierr referente
abertura do arquivo.

17 Continue avanando: CRIAO DE ARQUIVO PELO PROGRAMA


Lembre-se que voc criou um arquivo (dados.txt) e escreveu alguns dados para
ser lido pelo programa. Agora, suponha que queiramos que o programa crie um
arquivo para escrever um resultado, digamos A+B+C. Para tal, acrescente o
seguinte cdigo fonte antes do comando STOP:

S = A + B + C
open(unit = 1, file = 'resultados.dat')
write(1,*)S
close(unit = 1)

Ao executar o programa novamente, ele criar um arquivo chamado '


resultados.dat' e escrever o valor S nele. assim que, normalmente, um
software armazena seus resultados: em arquivos por ele criado.
Para acessar este arquivo voc pode clicar em File, depois em Open. Vai
aparecer uma caixa de dilogo chamada Abrir:
read(text , *)R

Utilize o HELP de seu estdio para estudar o assunto substring. Investigue,


por exemplo, o seguinte: definida a varivel caractere

P = 'PEDRO'
INTRODUO AO VISUAL FORTRAN CVF
qual seria o significado das expresses: p(1:1), p(:) e p(2:3). Uma forma de
Wilton, Cleide e Cleiton Diniz P. S. e Silva responder a isso at mesmo sem consultar o HELP seria fazendo um pequeno
programa definindo P = 'PEDRO' e dando os comandos a seguir:

write(*,*)p(1:1)
Programador: write(*,*)p(:)
write(*,*)p(2:3)

Naturalmente, analisando o que for escrito pelo programa,


Aula n 2 - Tipos de Dados (inteiro, real, complexo, literal e lgico),
Operadores (atribuio, aritmticos, concatenao, lgicos e relacionais),
If, Goto, Do, Select Case, Dimension, Alocao Dinmica de Memria, Programa
Simples

1 - Tipos de Dados
a) Inteiros - Declarados assim:
ficar bvio o significado das expresses desejadas.
INTEGER A, JCA

d) Lgicos - Declarados assim:


b) Reais
LOGICAL VB1, IA
b1) Preciso simples (8 algarismos) declarada assim:
Obs: uma varivel lgica pode assumir a situao de
REAL IA, ABE
.TRUE.
b2) Preciso dupla (16 algarismos) declarada assim:
ou de
DOUBLE PRECISION A, B
.FALSE.

c) Caractere (literal) - Declarado assim: Assim, em um programa, podemos ter algo escrito do
seguinte modo:
CHARACTER (5) P
VB1 = .true.
P pode ter at 5 caracteres. Exemplo:
IA = .false.
P = 'PEDRO'
Caso a varivel lgica seja lida (na tela ou em um
- Leitura de strings - Formato A, leitura definida assim: arquivo) o seu valor deve ser informado assim:

read(* , '(a)')nome T (verdadeiro)

- Converso de um real "R" em um caractere "text": ou

write(text , *)R F (falso).

- Converso de um caractere "text" em um real "R":


e) Complexos Declarados assim:
Ainda: como um espao em branco tambm no sentido pelos compiladores
COMPLEX AB, V9, S Fortran, tanto faz escrever o comando anterior das duas formas mostradas ou,
ainda, do seguinte modo:
Um exemplo de variveis complexas pode ser dado do seguinte modo:
y = y+ b
AB = (3,2)
V9 = (5.4,3.2)
b) Aritmticos: + (adio),
sendo o primeiro valor do par a parte real e o segundo a parte - (subtrao),
imaginria. Em um programa, dados esses valores e o comando * (multiplicao),
/ (diviso),
S = AB + V9 ** (potncia)

teramos, como valor para S o seguinte resultado: A prioridade das operaes a mesma da aritmtica comum e, para mudar esta
prioridade, deve-se usar parntesis. Como exemplo, devemos observar que na
S = (8.400000,5.200000) expresso:
OBS: caso a varivel complexa seja definida (a parte real e a imaginria) a Z = 5.0*4.0**2+ 1.0
partir de clculos efetuados no programa, que determina, por exemplo, a
varivel real pr para parte real e a varivel real pi para a parte imaginria o valor de z calculado elevando inicialmente 4.0 ao quadrado (16.0) e
, ento, tal varivel complexa definida assim: multiplicando a resposta por 5.0 (80.0) e, a esse resultado parcial, deve-se
somar 1.0, o que d 81.0.
VC = cmplx(pr,pi)
J se tivssemos
Muito embora demos exemplos com preciso simples, a varivel complexa tambm
pode ter dupla preciso. Utilize o HELP de seu estdio para estudar esse Z = 5.0*4.0**(2+ 1.0)
assunto.
a primeira operao a ser efetuada seria (2+1.0) e o resultado final para z
seria z = 320.
Ateno: todas as declaraes de tipos de variveis devem ser feitas no
incio do programa, logo abaixo da declarao: No caso de vrios parntesis (ninho), a prioridade a dos parntesis mais
internos.
PROGRAM NOME
c) Concatenao (juno) de strings: //

2 - Operadores O valor de uma varivel ou constante caractere uma string (valor


literal) e, para juntar duas strings, formando uma terceira, deve-se usar a
a) Atribuio: = concatenao. Como exemplo, vejamos a seqncia dos dois comandos abaixo:
A varivel ou constante que estiver esquerda do sinal de atribuio dado
Vc1 = 'Univers'
por = recebe o valor da expresso que estiver direita.
Vc2 = 'idade'
Varivel ou constante = Expresso Assim, se tivermos o seguinte comando

Vc3 = Vc1 // Vc2


Em Fortran, a expresso
o valor de Vc3 ser
Y = Y + B
Vc3 = 'Universidade'
correta e consistente, significando que o valor da varivel Y (a ser
atualizado) igual ao valor de Y at ento, acrescentado do valor de B. ou
Assim, se at antes do comando Y = Y + B o valor de Y for 3.4 e o de B for
1.2, aps este comando o novo valor de Y ser 4.6. Vc3 = 'Univers idade'
Como o Fortran no case sensitive, isto , no h diferena entre letra e uma forma ou outra s depende da quantidade de caracteres definida para
maiscula e minscula, o comando anterior idntico a Vc1 no incio do programa. Se for dada a declarao
y = y + b
Character (7) Vc1 END IF

o resultado da concatenao o primeiro. J se tivermos


c) Alternativa:
Character (13) Vc1
IF(condies) THEN
o resultado da concatenao o segundo.
comandos1
Para contornar o possvel problema apresentado no segundo caso, bastaria
eliminar os espaos em branco de Vc1 (s tem 7 caracteres, e ser escrito ELSE
com 13). Essa eliminao feita com o uso do comando TRIM:
comandos2
Vc3 = TRIM(Vc1)//Vc2
END IF
e, no caso, Vc1 poderia ser definido com 13 (ou at mais) caracteres tendo
como resultado:

Vc3 = 'Universidade' 4 - Desvio: o Comando GOTO


O comando
d) Lgicos: .AND. (uma condio E outra(s)),
.NOT. (se A for .true., .not.A .false.), GOTO label
.OR. (uma condio OU outra(s)),
.IAND. (incluso de uma nova condio E outra(s)), desvia as aes seqenciais na execuo de um programa, e usado assim:
.IOR. (incluso de uma nova condio OU outra(s)),
GOTO 10

e) relacionais: == ou .EQ. (igual), O significado desse comando bvio: v para o endereo (label) 10. O
/= ou .NE. (diferente), computador no executaria a instruo da linha subseqente linha do GOTO,
< ou .LT. (menor que), e sim, a declarao do endereo 10, e continuaria a executar as instrues a
<= ou .LE. (menor que, ou igual a), partir desta linha. No label 10 pode haver uma instruo qualquer, mas, em
> ou .GT. (maior que), geral, usa-se a seguinte:
>= ou .GE. (maior que ou igual a).
10 CONTINUE

A declarao anterior tem um significado que obvio: continue a executar o


Os operadores definidos nos itens d e e sero melhores compreendidos no programa a partir deste comando.
decorrer do restante dessa e das prximas lies. Mas uma busca no HELP do
seu estdio imprescindvel para compreender todos os detalhes.

5 - Estrutura de Repetio (Loop)


3 - Estruturas do Comando IF Suponha que se queira repetir uma seqncia de comandos at que uma condio
(ou condies) seja(m) atingida(s). Pode-se usar os comandos
a) Um comando:
IF
IF(condies) comando
e
Ex 1: IF(A>B) WRITE(*,*) 'A maior que B'
GOTO
Ex 2: IF(J == -1) A = A + DELTA
para fazer isso. Veja o fragmento de programa:
b) Vrios comandos:
...
IF(condies) THEN ...
20 CONTINUE
comandos
IF(condies) GOTO 30
seqncia de comandos que j indica a varivel cujo valor deve ser investigado. A seguir, vem o
comando que estabelece o valor da varivel e os comandos (decises) que
GOTO 20 devem ser dados, caso a varivel assuma o valor indicado entre parntesis:
30 CONTINUE Case(valor da varivel)
... Comandos
...
O conjunto anterior pode ser repetido para todos os valores distintos da
varivel, para os quais uma ou vrias decises devem ser tomadas.
Quando o computador executar o fragmento anterior, repetir a execuo da
seqncia de comandos (GOTO 20) at que as condies sejam satisfeitas (GOTO Para prevenir o caso em que nenhum dos valores testados satisfaa a uma dada
30). condio, deve-se dar o comando

case default
Comandos
Loop: DO
Depois, a estrutura encerrada com o comando
Como a estrutura de repetio apresentada anteriormente muito freqente em
programas, ela foi pr-definida em Fortran do seguinte modo: End Select

DO I = N1, N2, N3 Um programa exemplo pode ser visto logo a seguir, e voc pode copi-lo
(selecione-o, clique com o boto direito do mouse sobre a rea de seleo e
Seqncia de comandos depois clique em copiar). Depois, cole o programa em um arquivo dentro de
um workspace criado para esse fim. Execute-o e analise as possibilidades de
END DO uso do Select Case.

Exemplo 1
Na primeira linha do LOOP temos: faa a seqncia de comandos com o contador
I variando do valor N1 at o valor N2, com passo igual a N3 (I varia de N3 Um exemplo simples da utilizao dessa estrutura pode ser visto a seguir,
em N3). Quando o passo for 1 (variao de 1 em 1) pode-se iniciar o LOOP para uma varivel lgica vj que, obviamente, s pode assumir os valores
assim: .true. e .false.:

DO I = N1, N2 Program teste1_select

logical vj
Uma generalizao dessa estrutura foi feita da seguinte forma:
write(*,*)'informe vj ( f ou t )'
DO WHILE (condio) read(*,*) vj
Seqncia de comandos Select Case(vj)
END DO case(.true.)

write(*,*)'vj verdadeiro'
O DO WHILE pode ser melhor estudado no Help do seu estdio.
case(.false.)

write(*,*)'vj falso'
6 - A estrutura Select Case
case default
Uma estrutura que facilita a codificao de um programa, quando se procura
selecionar o valor de uma varivel (inteira, lgica ou character) dentre write(*,*) 'aqui no ser executado'
muitas possibilidades a estrutura chamada Select Case. O comando inicial
dessa estrutura End Select

Select Case(varivel) End Program


...
...
Deve-se observar que vj foi definida como uma varivel lgica e, como tal,
case(1000:)
s pode assumir dois valores: t ou f. Caso voc informe um valor a = b/c
diferente, haver um erro de execuo porque o recurso do iostat no foi case(2000:)
usado na leitura. a = d/c
...
Para generalizar, devemos destacar ainda as seguintes possibilidades de case: ...

case(v) testa se a varivel igual a v O primeiro case testa se a varivel maior ou igual a 1000 enquanto que o
case(:v) testa se a varivel menor ou igual a v segundo testa se a mesma varivel maior ou igual a 2000. Obviamente a
case(v:) testa se a varivel maior ou igual a v interseo no um conjunto vazio: para a varivel igual a 2100, por
case(v1:v2) testa se a varivel est entre v1 e v2 (inclusive) exemplo, os dois case seriam satisfeitos, e teramos um erro de lgica.
case(v1,v2,...,vn) testa se a varivel igual a v1, v2, ..., vn

Exemplo 2 7 - Array: DIMENSION Vetores e Matrizes


A seguir, apresentaremos mais um exemplo que pode ser considerado como A declarao
auto-explicativo:
DIMENSION
Program teste2_select , de fato, uma declarao de quantos endereos memria sero reservados
para armazenar dados de mesmo nome (vetores e matrizes), especificados por
write(*,*) 'escreva um valor inteiro' ndices. Por exemplo: se numa tabela de dados tivermos 6 valores da grandeza
x, definidos por x1, x2, ..., x6, podemos usar, no incio do programa, a
read(*,*)i1 declarao:
select case(i1) DIMENSION X(6)
case(:5) Com essa declarao o programa alocar 6 posies de memria para armazenar
x1, x2, ..., x6 que, no programa, devem ser denotados por
write(*,*) 'menor ou igual a 5' X(1), X(2), ..., X(6).
case(10,20) Da mesma forma que um vetor, uma matriz pode ter seus elementos armazenados
numa varivel x atravs de uma declarao do tipo
write(*,*) 'igual a 10 ou 20'
DIMENSION X(6,3)
case(30:40)
e isso significaria poder armazenar os elementos de uma matriz com 6 linhas
write(*,*) 'entre 30 e 40 (inclusive)' e trs colunas.
case default Uma alternativa ao DIMENSION, visando economia na alocao de memria, o
COMMON, que voc poder estudar, no HELP de seu estdio, durante o estudo da
write(*,*) 'nem menor ou igual a & lio n 3.
5, nem 10 e nem 20 e &
tampouco est entre 30 e 50' Ateno:
end select
1) pode-se usar INTEGER, REAL e DOUBLE PRECISION para um fazer um
End program dimensionamento, isto , uma alocao de memria, da mesma forma que o
DIMENSION.

Deve-se tomar muito cuidado para que duas condies no sejam 2) O comando DIMENSION, no programa principal, faz uma alocao esttica
simultaneamente satisfeitas na estrutura do select case pois, neste caso, h de memria: uma vez alocada a memria para um vetor ou matriz, no
um erro erro de lgica na construo de tal estrutura. Veja o fragmento de cabealho de declaraes, com uma declarao do tipo
programa a seguir:
Dimension x(20)
no h como desalocar o espao alocado. necessrios no programa, deve-se dar o comando

3) O comando DIMENSION, em uma funo ou em uma subrotina pode servir DEALLOCATE (A , B)


como uma espcie alocao dinmica de memria da maneira que ser
mostrada a seguir: e o programa pode, ento, prosseguir normalmente, mas os valores de A e B j
no estaro mais disponveis.
Subroutine calcula (n,x,xbarra,desv_pad)
Dimension x(n) Um programa exemplo pode ser visto logo a seguir, e voc pode copi-lo
(selecione-o, clique com o boto direito do mouse sobre a rea de seleo e
Assim que a subrotina calcula for chamada, a unidade de programa que a depois clique em copiar). Depois, cole o programa em um arquivo dentro de
evocou repassa o inteiro n para o dimension x(n). um workspace criado para esse fim. Execute-o e analise as vantagens da
alocao dinmica. Veja o programa:

8 - Array: Alocao Dinmica de Memria Vetores e Matrizes program tst


allocatable A(:),B(:,:)
A desvantagem da declarao DIMENSION que, em geral, se reserva mais
w = 15.0
espao de memria que o necessrio, por precauo, e uma vez alocados os z = 2.0
espaos de memria no programa principal, com o DIMENSION, no h como
desalocar. Para evitar esse inconveniente pode-se fazer uma alocao dinmica n=6
de memria. O significado para alocao dinmica o seguinte: aloca-se i=4
espaos de memria para variveis ao longo do cdigo fonte, quando houver ALLOCATE(a(n),b(2,i))
necessidade e, quando no for mais necessrio, tambm ao longo do cdigo
fonte, a alocao desfeita. Vejamos o que ser mostrado a seguir. a(5) = 3.0
a(2) = 4.0
Para um programa chamado tst, logo aps a declarao b(2,4) = 5.0

program tst write(*,*)a(2),a(n-1),b(2,i)

deve ser feita a declarao de quais so as variveis que sero alocadas DEALLOCATE(A, B)
dinamicamente, ao longo da execuo do programa, o que feito assim:
!para perceber a "desalocao", tire o comentrio
allocatable A(:),B(:,:) !do comando abaixo, compile e execute o programa.
!write(*,*)a(2),a(6),b(2,4)
A declarao anterior significa que sero alocados dinamicamente espaos de
memria para o vetor A e para a matriz B, de dimenso 2. O smbolo (:) write(*,*)w*z
significa que, a priori, A pode ser dimensionado com qualquer inteiro
maior que zero. O smbolo (:,:) tem o mesmo significado para B que tem do while (.true.)
duas dimenses. O programa , ento, desenvolvido normalmente, a partir da,
e vamos destacar um fragmento de cdigo mostrado a seguir: end do

... end program


...
n=6
i=4 Uma outra importante ferramenta envolvendo alocao de memria o ponteiro
... (POINTER) e fica a sugesto para que voc estude esse assunto no HELP do seu
... estdio.

suponha que, aps esse fragmento de cdigo, haja a necessidade da alocao


de memria para armazenar valores das variveis indexadas a (vetor) e b
(matriz de dimenso 2). Ento, nesse ponto, deve-se dar um comando do tipo 9 - Estrutura de um Programa Simples
ALLOCATE (a(n) , b(2,i)) Seqncia bsica
A partir de ento, e at que se declare o contrrio, o programa aloca os Um programa simples, visando clculos matemticos, tem a seguinte estrutura
espaos de memria necessrios para armazenar os valores de A (com 6 seqencial bsica:
elementos, j que n=6) e de B (com 8 elementos, por ser 2X4, posto que i=4).
Depois que os valores do vetor A e da matriz B no forem mais
b) Testar se o discriminante maior que zero (razes reais).

c) Testar se o discriminante menor que zero (razes complexas).

d) Testar se A(1) e A(2) so simultaneamente zero (dados incoerentes).

Obs.: continue chamando o novo programa de PROGRAM TESTE1.

11 - Abertura do Projeto
Para abrir o projeto clique no menu File e em seguida selecione o item 'Open
Workspace'.

Estrutura de codificao

Quanto estrutura da codificao, a primeira declarao a que identifica


do que se trata, isto , a unidade de programa, o que feito assim:

Program Teste

Em seguida, no cabealho so escritas as declaraes determinando o uso de


mdulos e de incluso de arquivos (essas declaraes ainda sero estudadas)
e todas as declaraes de tipo de variveis.

Na seqncia so escritos os comandos, propriamente ditos, relativos


entrada de dados, clculos matemticos e sada de resultados.

Esquematicamente, temos:

Program Teste

Declaraes (use, include, tipos)

Comandos (dados, clculos e resultados)

Stop

End Program

10 - Programa Vai aparecer o browse (Open Workspace):


Faa as modificaes necessrias no programa da aula 1 para que ele
identifique se o tipo de dado informado na execuo ou no correto e, em
caso de erro, informe o erro ao usurio, para as devidas correes. Ao invs
de A, B e C, chame as constantes de A(1), A(2) e A(3). Suponha que as
constantes sejam os coeficientes de uma equao do 2 grau. Ento, determine
e informe as razes ao usurio. Lembre-se de fazer os seguintes testes:

a) Testar se A(1) = 0.0 (nesse caso temos uma equao do primeiro grau).
write(*,*)' A*X**2+B*X+C=0. Escreva os valores de A, B e C'

read(*,*,iostat = ierr) (a(i), i = 1,3) !leitura com DO implcito

if(ierr /= 0) then !ierr diferente de zero: houve erro na leitura

write(*,*)' Erro lendo os valores de A, B e C. '

goto 10 !ir para o endereo 10 refazer as leituras

end if

if(a(1) == 0.0) then !testa se a equao do segundo grau

if(a(2) == 0.0) then !testa se equao do primeiro grau

write(*,*)' '
write(*,*)' '
write(*,*)' '
write(*,*)'Os dados no so coerentes.'

stop !encerra a execuo


e voc deve localizar o subdiretrio do projeto Equation.
end if
Caso voc esteja trabalhando no PowerStation (PS), deve procurar o projeto
em: x1 = -a(3)/a(2) !calcula a raiz da equao do primeiro grau
C:\MSDEV\PROJECTS\EQUATION write(*,*)' '
write(*,*)' '
Se voc estiver trabalhando no Digital Visual Fortran (DVF), o subdiretrio write(*,*)' '
deve ser procurado em: write(*,20)x1
C:\Program Files\DevStudio\MyProjects\Equation 20 format(' A equao do primeiro grau: x = ',e12.6)
J se voc estiver trabalhando no Compaq Visual Fortran (CVF) o subdiretrio stop !pra o programa
deve ser procurado em:
end if
C:\Program Files\Microsoft Visual Studio\MyProjects\Equation
delta = a(2)**2 - 4.0*a(1)*a(3) !clculo do discriminante
Uma vez localizado o subdiretrio do projeto, selecione o arquivo
Equation.dsw (se for o PowerStation, o arquivo tem o seguinte nome: if(delta < 0.0)then !testa se o discriminante maior que zero
Equation.mdp). Depois, clique em Abrir.
pr = -a(2)/(2.0*a(1)) !parte real
Ateno: Voc sempre deve abrir o workspace e, dentro dele, voc pode abrir pi = sqrt(abs(delta))/(2.0*a(1)) !parte imaginria
o arquivo que desejar. Para abrir um arquivo utilize o menu File e selecione xc1 = cmplx(pr,pi) !comando para escrever varivel complexa
o item 'Open...'. Na caixa que vai aparecer selecione o arquivo desejado xc2 = cmplx(pr,-pi) !segunda raiz: conjugado
(ele fica azul) e clique em Abrir. write(*,*)' '
write(*,*)' '
write(*,*)' '
write(*,*)'Raizes complexas:'
write(*,*)' '
12 - Esboo do Programa write(*,*)'x1 = ',xc1
write(*,*)'x2 = ',xc2
program teste1 !com as modificaes recomendadas
else
real a(3) !dimensionamento usando a declarao REAL
complex xc1,xc2 !variveis para razes complexas x1 = -a(2)/(2.0*a(1)) + sqrt(delta)/(2.0*a(1))
x2 = -a(2)/(2.0*a(1)) - sqrt(delta)/(2.0*a(1))
10 continue write(*,*)' '
write(*,*)' '
write(*,*)' '
write(*,*)'Raizes reais:' Desenvolva um programa para determinar o fatorial de um nmero inteiro dado.
write(*,*)' '
write(*,*)'x1 = ',x1
write(*,*)'x2 = ',x2

end if

stop

end program

13 - Locao do executvel

Assim que o aplicativo criado, j est disponvel para ser usado fora do
ambiente em que foi criado, isto , fora do estdio. O executvel deste
programa que acabamos de criar, por exemplo, pode ser encontrado, via
explorer, na pasta chamada DEBUG na locao escolhida para o projeto e que
indicada pela figura dada a seguir:

Alm de alguns arquivos intermedirios, observamos tambm o executvel


Equation.exe que pode ser utilizado em qualquer outro micro,
independentemente de ter ou no o CVF instalado.

14 - Avance um Pouco Mais:


Select case
Execute os exemplos de select case dados nesta lio e, depois,
desenvolva um outro exemplo com varivel caractere.

Comando DO
execuo do aplicativo, e a prpria aparncia desse aplicativo, no programa
principal. Os dois programas j estudados nas lies anteriores so
exemplos de programa principal.

Um programa principal (ou um subprograma) chama (evoca) uma subrotina


(detalhada a seguir, mais frente) atravs do comando:

INTRODUO AO VISUAL FORTRAN CVF CALL NOME(argumentos)

O comando CALL significa chame e NOME o nome atribudo subrotina.


Wilton, Cleide e Cleiton Diniz P. S. e Silva
J argumentos so os parmetros com dados de entrada e de sada dessa
subrotina.

Programador: Um programa principal (ou um subprograma) chama (evoca) uma funo


(detalhada a seguir, mais frente) simplesmente escrevendo-a em uma
expresso aritmtica, com os seus argumentos. Exemplo:

Y = 4*F(argumentos)**2
Aula n 3 - Programas complexos - Programa principal e Subprogramas:
Function (funes numricas, grficas e definidas pelo programador), Nessa expresso "F" o nome atribudo funo e "argumentos" so os
Subroutine (grficas e definidas pelo programador) parmetros de entrada (dados) da funo. No caso do exemplo, o valor de Y
ser o qudruplo do quadrado do valor que "F" assumir para os argumentos
dados.
1 - Introduo
Quando um programa fica fisicamente muito grande, torna-se til 3 - Estrutura de um Programa Principal Simples
subdividi-lo em subprogramas mais simples e compreensveis, o que facilita
a sua criao, compilao (em partes) e manuteno. Em Fortran, um
programa completo (projeto) pode ser composto de 1 programa principal e de PROGRAM NOME
subprogramas
declaraes de tipo e outros
Programa principal <- S pode haver um nico programa principal em um comandos
projeto.
STOP
Subprogramas <- Em Fortran existem dois tipos de subprogramas que so:
funo e subrotina. END

Subrotina: um subprograma evocado pelo programa principal ou por outros


subprogramas. Pode retornar vrios valores ao programa ou subprograma que
a evocou, atravs de seus argumentos. 4 - Estrutura de um Subprograma FUNCTION
Funo: tambm evocada pelo programa principal ou por outros
subprogramas. Retorna um nico valor ao programa ou subprograma que a FUNCTION NOME(parmetros)
evocou, no local da evocao.
declaraes de tipo e outros
Ateno: 1) pode haver vrias subrotinas e funes em um programa. A
seguir, definiremos cada unidade de um programa, e mostraremos as comandos
diferenas entre subrotina e funo.
RETURN
2) os subprogramas (subrotinas e funes) so compilados
independentemente uns dos outros e, para perceber isso de forma clara, END
basta criar cada unidade de programa em um arquivo prprio, em separado
dos demais.

Uma funo s retorna 1 valor para o comando do programa ou subprograma


que a chamou, e no local em que tal funo foi escrita.
2 - Programa Principal
Exemplo - suponha que tenhamos os seguintes comandos de um programa
Em geral, um programa principal contm os comandos de leitura e de sada principal (ou de um subprograma):
de dados, e tambm os comandos que chamam os subprogramas. Em quickWin
Application pode-se estabelecer toda a configurao do micro para a
... Exemplos:
...
D = 10.0 setcolor(i),
setcolorrgb(#hexadecimal),
Z = 3.0 * SOMA(10.0 , 2.0 , 5.0) - D setbkcolor(i),
... setbkcolorrgb(#hexadecimal),
... lineto(x,y),
setwsizeqq(qwin$framewindow, winfo),
setwsizeqq(0, winfo),
Seja a funo "soma" definida da seguinte forma: initializefonts(),
ellipse($gborder, x1, y1, x2, y2),
rectangle($gfillinterior, x1, y1, x2, y2),
FUNCTION SOMA(X,Y,W) setfont('t' 'arial' 'h18w10i'),
messageboxqq('texto'c,'ttulo'c,mb$ok.OR.mb$defbutton1),
SOMA = X+Y+W**2 ellipse($gfillinterior, x1, y1, x2, y2),
rectangle($gborder, x1, y1, x2, y2),
RETURN runqq('write.exe', 'doc.rtf')
WinExec('explorer.exe mailto:wiltops@uol.com.br',sw_show),
END WinExec('explorer.exe http://www.extensao.hpg.com.br',sw_show),
WinExec('notepad.exe arquivo.txt',sw_maximize),
PlaySound('arquivo.wav'C,0,snd_filename),
Ento, retornado SOMA = 37.0 ao programa principal (ou subprograma) LoadImage('arquivo.bmp',ix,iy),
porque, ao se evocar soma(10.0 , 2.0 , 5.0), est-se informando que etc,
x=10.0, y=2.0 e w=5.0. Como soma = x+y+w**2, ento soma(10,2,5)=37.0.
Naturalmente, o valor de z, no fragmento de programa mostrado
anteriormente, ser 101.0. As funes WinExec e PlaySound so do Windows Application e, para
utiliz-las no QuickWin Application deve-se declarar, no incio do
programa, o seguinte:

5 Exemplos de FUNES Use MSFWIN

FUNES NUMRICAS (INTRNSECAS) ou ento

J fazem parte da linguagem Fortran (funes internas, intrnsecas). USE DFWIN

Todas as outras funes apresentadas esto no mdulo MSFLIB ou DFLIB e,


Exemplos: para compreender o propsito de cada uma dessas funes, utilize o "HELP"
do seu Developer Studio e busque por essas funes.
sin(x),
cos(x),
sqrt(x), Funes que iniciam e estabelecem um dilogo em uma caixa de dilogo
log(x) <- neperiano,
log10(x) <- base 10, DLGINIT(IDD_DIALOG,DLG)
exp(x),
float(i), A funo lgica dlginit inicia uma caixa de dilogo e ser usada
ifix(x), posteriormente, numa lio para construo de caixa de dilogo.
abs(x),
etc,
DLGMODAL(DLG)

A funo dlgmodal estabelece um dilogo retornando um valor inteiro, e


FUNES GRFICAS E OUTRAS tambm ser estudada e utilizada posteriormente.

Definidas em mdulos (biblioteca de subrotinas e funes) como, por


exemplo, MSFLIB (PS) ou DFLIB (DVF e CVF). Para utilizar as funes Ateno: 1) utilize o HELP de seu estdio de desenvolvimento para
grficas deve-se declarar, imediatamente depois de conhecer o propsito de cada uma dessas funes e tambm para saber como
evoc-las.
PROGRAM NAME
2) as funes de dilogo requerem a utilizao do mdulo
o seguinte: (biblioteca de subrotinas e funes) DIALOGM, o que feito com a seguinte
declarao no incio do programa (ou subprograma):
USE MSFLIB
USE DIALOGM
mas isso ser estudado mais frente.
TYPE (XYCOORD) POS
3) As funes de dilogo requerem a utilizao de uma varivel
que deve ser declarada no incio do programa (ou subprograma) assim: POS uma varivel que identifica, ao longo programa, o tipo de
coordenadas que foi definido: no caso de "xycoord" trata-se de pixels.
TYPE (DIALOG) DLG
Se tivssemos declarado
DLG uma varivel chamada de "varivel de dilogo"; e isso ser detalhado
na quinta aula. TYPE (RCCOORD) POS

a varivel POS indicaria que as coordenadas seriam definidas em linhas (R


ows) e colunas (Columns).
6 - Estrutura de um Subprograma SUBROUTINE
Outros exemplos: outgtext('texto'),
SUBROUTINE CALCULA(N, XBARRA, DESVIO_PADRAO) clearscreen($gclearscreen),
beepqq(freq, idura),
declaraes sleepqq(idura),
setvieworg(ix,iy,pos)
COMMON X(50) etc.

Clculo de XBARRA Mais uma vez, bom enfatizar que o propsito de cada uma dessas
subrotinas pode ser facilmente conhecido utilizando-se o HELP do seu
Clculo de DESV_PAD estdio.

RETURN
Subrotinas que encerram uma caixa de dilogo
END
dlguninit(dlg) e dlgexit(dlg)

Neste exemplo esquemtico de subrotina podem entrar como dados o parmetro Para usar essas subrotinas deve-se declarar, no incio do programa:
N, por exemplo, (argumento) e os valores de X (em common). Uma vez
calculados os parmetros XBARRA E DESVIO_PADRAO (que so argumentos da TYPE (DIALOG) DLG
subrotina), os seus valores retornam ao programa ou subprograma que chamou
a subrotina. Tais valores passam a ficar disponveis na unidade de Essas subrotinas encerram uma caixa de dilogo (iniciada pela funo
programa que evocou a subrotina, a partir do ponto em que houve a evocao. lgica de dilogo "dlginit") e esse assunto ser detalhado na quinta lio.

A principal diferena entre SUBROUTINE e FUNCTION que a primeira pode


retornar vrios valores de parmetros (via argumentos, disponveis do Ateno: Ao desenvolver um programa em QuickWin Application, nem tudo ser
ponto de evocao at o fim da unidade que a evocou), enquanto que a criado pelo programador. No Developer Studio j existem mdulos
segunda s retorna o valor da funo evocada (atravs do nome da funo, (biblioteca de subrotinas e funes) que voc pode utilizar em seu
na expresso aritmtica em que foi evocada). programa e, para isso, basta utilizar a declarao USE. Por exemplo: a
maioria das funes e subrotinas grficas j desenvolvidas em Fortran
esto num mdulo chamado MSFLIB (PowerStation) ou DFLIB (Visual Fortran).
Assim, para que essas subrotinas e funes automaticamente faam parte de
7 Exemplos de SUBROTINAS GRFICAS E OUTRAS seu programa (e, conseqentemente, para que voc possa evoc-las) basta
declarar, imediatamente aps a declarao
Definidas em mdulos (bibliotecas de subrotinas e funes) como, por
exemplo, MSFLIB (PS) ou DFLIB (DVF ou CVF). Para utilizar as subrotinas e PROGRAM NOME
funes deve-se declarar:
o seguinte:
USE MSFLIB
USE MSFLIB
no incio do programa, logo aps a declarao inicial:
(isso no caso do PowerStation) ou
PROGRAM NOME
USE DFLIB

no caso do Visual Fortran.


Exemplos de subrotinas disponveis em MSFLIB (ou DFLIB):

moveto(x,y,pos)

que move o cursor para a posio (x,y). Para usar a subrotina "moveto" 8 RECURSIVIDADE: Subrotina Recursiva
necessita-se declarar, no incio do programa ou subprograma, o seguinte:
Uma subrotina chamada de recursiva quando ela pode evocar a si mesmo, o read(1,*)(x(i), i = 1, n) !l, a partir da segunda linha, o vetor x
que s vezes muito til. Para tal, basta, ao declarar a subrotina,
atribuir a ela a propriedade da recursividade, o que feito com a palavra close(unit = 1) !fecha o arquivo aberto
recursive antes da declarao subroutine nome. Veja o programa exemplo
a seguir: call calcula(n,xbarra,desv_pad) !Chamada da subrotina calcula.
!O programa Teste3 informa
!o valor de n (via argumento)
PROGRAM TST !e os valores de x (em common).
!A subrotina determina xbarra e
i = 0 !valor inicial !desv_pad e retorna os valores
n = 20 !valor final !ao programa principal atravs
CALL Inc (i,n) !dos dois ltimos argumentos.
END PROGRAM write(*,*)xbarra, desv_pad !escreve, na tela, xbarra e desv_pad

stop
RECURSIVE SUBROUTINE Inc (i,n) end
i = i + 1
WRITE (*,*) I
IF (i < n) CALL Inc (i,n)
Subroutine calcula(n,xbarra,desv_pad)
END SUBROUTINE Inc
common x(10)
Para compreender melhor, crie um workspace e execute este exemplo. xbarra = soma1(n)/float(n) !evoca a funo soma1 (e
!float) para calcular
!o valor mdio chamado
!de xbarra.
9 - Programa
desv_pad = sqrt((soma2(n) - soma1(n)**2/n)/(n-1)) !evoca soma1
Crie um novo Workspace chamado Desv_pad. Faa um programa que leia um !e soma2 para
conjunto de dados em um arquivo chamado dados.dat, calcule o valor mdio !calcular
e o desvio padro dos dados e informe os resultados na tela. O programa !desv_pad.
deve ter a seguinte estrutura:
return !retorna ao programa principal
!com xbarra e desv_pad calculados.
1) Programa principal chamado PROGRAM TESTE3 que l os dados, chama a
subrotina CALCULA (onde o valor mdio e o desvio padro sero calculados) End Subroutine calcula
e informa os resultados na tela.

2) Subrotina chamada SUBROUTINE CALCULA que evoca as funes SOMA1 (que


soma os valores dos dados) e SOMA2 (que soma os quadrados dos valores dos
dados) ao fazer os clculos do valor mdio e do desvio padro, retornando function soma1(n) !calcula o somatrio de x
os resultados ao programa principal. !e retorna o resultado na
!varivel soma1.
3) Funo chamada FUNCTION SOMA1 que faz o somatrio dos dados. common x(10)

4) Funo chamada FUNCTION SOMA2 que faz o somatrio do quadrado dos soma1 = 0.0
dados.
do i = 1,n
soma1 = soma1 + x(i)
end do
10 - Esboo do Programa
return
program teste3 end function soma1
common x(10) !armazena x numa rea comum aos subprogramas

open(unit = 1, file = 'dados.dat') !abre o arquivo dados.dat


function soma2(n) !calcula o somatrio dos quadrados de x
read(1,*)n !l, na primeira linha do arquivo, o valor de n !e retorna o resultado na varivel soma2.
abertura do arquivo e leitura dos dados, temos:
common x(10)

soma2 = 0.0
11 - O Arquivo de Dados
do i = 1,n
soma2 = soma2 + x(i)**2 Veja o fragmento do nosso programa:
end do
...
return ...
open(unit = 1, file = 'dados.dat') !abre o arquivo dados.dat
end function soma2
read(1,*)n !l, na primeira linha do arquivo, o valor de n

read(1,*)(x(i), i = 1, n) !l, a partir da segunda linha, o vetor x


Ateno: Voc poderia criar um nico arquivo para todas as unidades de ...
programa, mas crie 4 quatro arquivos independentes. Um arquivo chamado ...
principal.f90, outro chamado calcula.f90, o terceiro com o nome de
soma1.f90 e o ltimo com o nome de soma2.f90. Adicione os 4 arquivos ao Ento, devemos ter um arquivo dados.dat no diretrio do projeto com, por
projeto. A janela com os componentes do projeto ter o seguinte aspecto: exemplo, a seguinte estrutura de dados:

A cada linha deve corresponder um comando READ do cdigo fonte. Ento, a


primeira linha informa o nmero de dados a serem lidos (no caso 5 dados) e
a segunda linha informa os valores desses dados, um a um.

12 Sada de Resultados: Tela Final

Para o comando final de sada de dados de program teste3 temos o


seguinte fragmento:

...
...
write(*,*)xbarra, desv_pad !escreve, na tela, xbarra e desv_pad
...
...

e, portanto, teremos a seguinte tela final:


Compile cada componente separadamente. Basta clicar com o mouse sobre o
arquivo e, quando ele ficar azul, clicar tambm no primeiro item (
Compile...) do menu Build para fazer a compilao. Depois, ligue os 4
programas objeto clicando em "Build Desv_pad.exe" no menu Build.

Importante: Para executar o programa, clique em "Execute Desv_pad.exe" no


menu Build. No se esquea de adicionar o arquivo dados.dat no diretrio
do projeto com os dados a serem tratados. Seno, o programa acusar um
erro de execuo quando for abrir o arquivo dados.dat (inexistente ou
vazio): o programa no dispe de nenhuma proteo para evitar o erro de
execuo durante as leituras.

No programa principal (program teste3), para as linhas referentes


subrotinas e funes, mas apenas evoc-las. Vejamos, agora, como criar um
mdulo.

15 - Problema Complementar:
Criao de um Mdulo para a Subrotina e as Duas Funes Desenvolvidas

Para compreender melhor como criar um mdulo, faamos o seguinte: depois


que o aplicativo desenvolvido nessa lio j estiver funcionando,
transforme a subrotina CALCULA e as funes SOMA1 e SOMA2 em um mdulo.

Para criar tal mdulo, devemos criar um arquivo para colocar a subrotina e
as funes. Proceda da maneira usual: no menu File clique em New.
Ento, selecione Fortran Free Format Source File e d um nome ao
arquivo, por exemplo modulo_teste. Ao clicar OK, inicie a construo do
seu mdulo, que deve ter a seguinte estrutura:

module modulo_teste

contains

Subrotinas e funes

end module modulo_teste

No presente caso, onde est escrito Subrotinas e funes devemos colar a


subrotina CALCULA e as funes SOMA1 e SOMA2, que devem ser recortadas do
13 - Avance um Pouco Mais: O programa apresentado no tem seu local original (cuidado para no haver duplicata desnecessria!).
proteo para a leitura de dados. Faa isso usando o iostat. Assim, teremos:

Testes
module modulo_teste
1) Coloque um teste para sabe se N menor ou igual a 1, informando ao
usurio a incompatibilidade destes valores com o propsito destes contains
clculos.
Subroutine calcula(n,xbarra,desv_pad)
2) Como no utilizamos alocao dinmica de memria, faa um teste common x(10)
para saber se o valor de N maior que a dimenso declarada para X, xbarra = soma1(n)/float(n)
e informe ao usurio o valor mximo para N. desv_pad = sqrt((soma2(n) - soma1(n)**2/n)/(n-1))
return
Nos dois testes anteriores, caso haja alguma violao, encerre o programa End Subroutine calcula
aps as mensagens com a informao de tal violao.
function soma1(n)
common x(10)
soma1 = 0.0
do i = 1,n
14 - Avance Mais Ainda: Criao de um Mdulo soma1 = soma1 + x(i)
end do
Um mdulo um componente de um projeto que contm subrotinas e funes return
que o usurio pode usar em seus programas. Conforme j vimos, para end function soma1
utilizar um mdulo j existente, no incio do programa principal ou do
subprograma em que tal mdulo ser usado basta declarar o seguinte: function soma2(n)
common x(10)
USE nome soma2 = 0.0
do i = 1,n
onde nome o nome do mdulo. O estdio que usamos (CVF) j contm soma2 = soma2 + x(i)**2
vrios mdulos para fins especficos tais como interface grfica (dflib), end do
construo de caixas de dilogo (Dflogm), informaes sobre a performance return
da mquina (dfport), etc. Assim, o usurio no precisa desenvolver end function soma2
end module modulo_teste

Certifique-se de que apagou os arquivos originais da subrotina e das


funes para no haver duplicata desnecessria e, depois, compile o
mdulo. Alm do arquivo intermedirio modulo_teste.obj criado tambm o
arquivo modulo_teste.mod (na pasta DEBUG). Uma vez compilado o mdulo, a
subrotina e as funes j passam a fazer parte do projeto e o executvel
pode, ento ser criado. Naturalmente, para no haver erros, logo depois da
declarao

Program teste3

devemos ter, no programa principal, a declarao Nota-se alguns arquivos intermedirios e o arquivo executvel, que pode
ser copiado em disquete e executado em qualquer micro, fora do ambiente do
Use modulo_teste CVF. Naturalmente, na mesma pasta do executvel, devemos ter o arquivo de
dados.
A janela (com os componentes do projeto) fica, ento, com o seguinte
aspecto:

16 Locao do Executvel
Na pasta DEBUG (que est dentro da pasta do projeto), aps a operao de
linking, temos os seguintes arquivos:
3 - Definio do Menu Inicial
Em QuickWin Application um menu criado por uma funo lgica chamada
INTRODUO AO VISUAL FORTRAN CVF INITIALSETTINGS()

Wilton, Cleide e Cleiton Diniz P. S. e Silva Clicando num item de menu de um aplicativo desenvolvido QuickWin
ns podemos executar dois tipos de subrotinas, chamadas genericamente de
subroutine callback:

Programador:
1) Podemos executar as subrotinas internas, pr-definidas em MSFLIB (ou
DFLIB), o que requer declarar

Aula n 4 - Estruturao de um Projeto em QuickWin Application - USE MSFLIB


Programa Principal, Funo Initialsettings: definio do menu inicial,
Subroutines Callbacks: execuo de tarefas. logo depois da declarao da funo initialsettings().

Exemplos de subrotinas internas: winexit,


winindex,
winusing,
1 - Programa Principal de um Projeto QuickWin Application winprint,
etc.
Em um projeto QuickWin Application pode-se executar vrios programas
independentes, como subroutines callbacks, utilizando a estrutura que ser Para mais detalhes sobre essas funes, busque pela funo lgica "
estudada a seguir, e que est disponvel no menu do VFortran Tutorial e appendmenuqq" no HELP de seu estdio. Uma forma eficiente (mas no
tambm ao longo desta lio. documentada no HELP) de se usar as callbacks internas em um dado ponto de
um programa atravs da funo
No programa principal da estrutura pode-se obter as informaes gerais
sobre a configurao do sistema (como nmero de pixels em x e em y, nmero i = clickmenuqq(loc(callback interna))
de linhas e de colunas da tela, etc). Voc tambm pode modificar essa
configurao do sistema durante a execuo do programa, e ainda definir o
nome da "janela filhote" (child window). 2) Atravs do menu tambm podemos evocar e executar as subrotinas externas
que so, na verdade, os programas desenvolvidos por ns, o que requer a
Pode tambm definir os tamanhos da "janela principal" (frame) e da "janela seguinte declarao
filhote" (child window), etc. Por ltimo, no final do programa principal
voc pode dar um "loop infinito" para que o programa no seja encerrado ao EXTERNAL NOME1, NOME2
final de uma execuo. A maneira de se fazer todas essas coisas est
indicada na estrutura que ser apresentada ao final da lio, e cada logo aps as declaraes de USE feitas na funo initialsettings, que
comando dessa estrutura seguido de um comentrio explicativo. de onde tais subrotinas sero chamadas. Naturalmente, nome1 e nome2
so os nomes das subrotinas externas que o programador criou para executar
as tarefas do aplicativo. Ao criar as subrotinas callback externas,
devemos cuidar para que elas tenham um argumento lgico. Isso porque
2 - Esboo de Programa Principal de um Projeto em QuickWin quando o mouse for clicado sobre o menu, a subrotina correspondente
Application chamada ( como se fosse dado o comando call). Depois de sua execuo a
callback retorna (back) o controle com uma informao para a funo
"initialsettings":
program Prog_QW !nome do programa
.true.
use msflib !tem funes grficas e do QuickWin
se ocorreu tudo bem, e
outros USE, INCLUDE e declaraes de tipo
.false.
comandos
em caso contrrio.
do while (.true.) !Loop infinito: programa sempre ativo

end do
4 - Funo Initialsettings - Definio do Menu Inicial: Um
end program !fim do programa principal Exemplo
RESULT = MODIFYMENUFLAGSQQ(1,2,$MENUGRAYED)
Em quickWin Application um menu pode ser criado com a funo lgica
initialsettings(). Num programa, essa funo executada em paralelo com o Aqui, $MENUGRAYED um atributo que suspende, no caso, o item 2 do menu 1
programa principal, em loop infinito, e nem sequer precisa ser evocada. (ele fica "cinza", indisponvel). Para reabilitar o item 2 do menu 1
Veja, seguir, um exemplo simples de uso da funo: deve-se dar o comando:

RESULT = MODIFYMENUFLAGSQQ(1,2,$MENUENABLED)
LOGICAL(4) FUNCTION INITIALSETTINGS()
!Declarao da funo lgica que define o menu inicial No caso, a palavra que define o item 2 do menu 1 (C string) volta a ficar
"preta", indicando que menu foi reabilitado. Veja, no final dessa aula, um
USE MSFLIB !DFLIB mais atual, mas MSFLIB tambm funciona. programa exemplo (estrutura) com todos esses detalhes.
LOGICAL(4)result Observe, a seguir, a figura do menu de um programa em que vrios itens
esto habilitados e um deles est desabilitado:
EXTERNAL subr1, subr2 !declara as subrotinas callback externas
!que sero chamadas do menu.

result = APPENDMENUQQ(1, $MENUENABLED, '&Arquivo'C, NUL )


!Cria o menu 'Arquivo'

result = APPENDMENUQQ(1, $MENUENABLED, 'Programa &1'C, subr1)


!cria o item 'Programa1' que chama subr1 (no menu arquivo)

result = APPENDMENUQQ(1, $MENUENABLED, 'Programa &2'C, subr2)


!cria o item 'Programa2' que chama subr2 (no menu arquivo)

result = APPENDMENUQQ(1, $MENUENABLED, 'Sair'C, WINEXIT )


!chama, de msflib, a callback interna
!"winexit" que encerra o programa.

INITIALSETTINGS = .TRUE.

END FUNCTION INITIALSETTINGS !fim da funo lgica que


!define o menu inicial.
Nessa figura percebe-se que o item 13 (Help: File menu) do menu 1 (File)
Vale salientar que o e comercial (&) colocado antes da letra A (de foi desabilitado. Deve-se observar que cada linha horizontal de separao
Arquivo) e antes dos nmeros 1 (de Programa 1) e 2 (de Programa 2) tambm um item do menu e, na funo initialsettings, tal item
declarado assim:
definem as teclas de atalho para esses itens. Se no for definido nada,
como em Sair, a primeira letra ser considerada como tecla de atalho. result = APPENDMENUQQ(1, $MENUSEPARATOR, ''C, NUL)
Observe o resultado para a funo initialsettings() dada anteriormente:
O nmero 1 significa que ser adicionado um item no menu 1. J o atributo
$MENUSEPARATOR significa que ser adicionado um trao separador. O C
string vazio ''C quer dizer que nada ser escrito enquanto que NUL
significa que nenhuma callback ser chamada.

6 - Estrutura de uma Subroutine Callback


subroutine subr1(ia)!A callback deve ter um argumento lgico
5 - Subroutines Callback
USE MSFLIB
Subroutine callback uma subrotina chamada pela funco Initialsettings()
e executada como se fosse um programa independente. Entretanto, deve-se Outros USE, INCLUDE e demais declaraes de tipo
lembrar que a subrotina executada pode compartilhar, virtualmente, o mesmo
espao (at dados) com as demais subrotinas externas. Mesmo quando a sua logical ia, result
execuo termina e o comando volta para o menu, os valores j calculados
para as constantes continuam na memria. Assim, h que se tomar cuidado declaraes
para que esses valores no sejam equivocadamente utilizados quando
qualquer outra callback (ou a mesma) for executada. Pode-se impedir que ia = .true.
duas callback sejam executadas simultaneamente com um comando dado atravs
da seguinte funo lgica: result=MODIFYMENUFLAGSQQ(1,1,$MENUGRAYED)!suspende o item 1
!do menu 1.
Copie todo o programa desenvolvido na aula 3, chamado TESTE3, e cole-o em
chamada de uma subrotina ou subr2. Mais uma vez, lembre-se que o "ex-programa" agora uma subrotina e
comandos do ex-programa
que, portanto, haver alteraes como, por exemplo, a posio das funes
result=MODIFYMENUFLAGSQQ(1,1,$MENUENABLED)!reabilita o item 1 e da subrotina do ex-programa, que no podem ficar dentro da subrotina
!do menu 1. callback (e sim logo depois do END da subrotina callback). Na verdade,
seria at melhor inserir s o ex-programa principal na callback, e
return !retorna ao menu adicionar ao projeto trs arquivos distintos, um para cada subprograma (
subrotina calcula, funo soma1 e funo soma2). Compile, ligue e execute
end subroutine a estrutura.

Ateno: seria melhor ainda se, ao invs de colocar o programa principal


fisicamente na callback, voc o transformasse em uma subrotina, num
7 - Projeto Completo: Criao do Aplicativo vazio arquivo prprio, o adicionasse ao projeto, e simplesmente evocasse a
subrotina (ex-programa principal), no ponto em que o cdigo deveria ser
colocado.
Crie um novo Workspace chamado Pro_QW. Nele, copie a estrutura previamente
preparada e que est disponvel no menu Tutorial do VFortran Tutorial
(voc deve ter escolhido Fortran Free Format Source File e deve chamar o
arquivo que receber o cdigo da estrutura de Pro_QW). A estrutura
composta do "programa principal", da "funo initialsettings" e de 5 " 10 - Estrutura de um Projeto Simples em QuickWin Application
subroutine callbacks". Tal estrutura tambm apresentada no final desta
lio. Aps copiar o cdigo da estrutura no projeto Pro_QW voc deve Ateno: a estrutura dada a seguir pode ser usada para que voc desenvolva
salvar o novo arquivo. Estude essa estrutura porque ela , apesar de seus programas nela, como subroutine callback, no ambiente PowerStation ou
simples, uma estrutura completa que pode ser usada como um modelo em todos Visual Studio, em QuickWin Application. Colocamos 5 subroutine callback
os seus programas futuros. Depois compile e link pro_QW.f90. Execute nela, com os nomes de subroutine subr1, ..., subroutine subr5. Na
pro_QW.exe e veja que j temos um programa para Windows, apesar de no estrutura tem comentrios explicando como inserir seus programas.
termos nenhum clculo disponvel nele (ainda).
Naturalmente que, quem j tiver experincia, deve personalizar suas
Ateno: essa estrutura apropriada para a execuo de programa rpidos, prprias estruturas. Para usar esta, s copiar toda a estrutura (ela
que no demandam muito tempo de execuo. Essa observao se deve ao fato est disponvel no diretrio em que o VFortran Tutorial foi instalado, num
de que, da forma como a estrutura foi preparada, todas as opes do arquivo chamado modelo.wri) e col-la no arquivo de extenso F90 que deve
aplicativo, mesmo que no estejam grayed ficam indisponveis durante a ter sido criado para que o programa seja desenvolvido. Caso se sinta mais
execuo de uma callback, isto , o programa fica esttico. Isto ocorre confortvel, copie a estrutura apresentada logo a embaixo mesmo.
porque quando se clica num item do menu, a funo initialsettings chama
a callback evocada e s volta a ficar ativa quando tal callback evocada Uma observao: existem algumas convenes mostrando como escrever cada
retornar o controle para a funo initialsettings. Entretanto, com comando, o que deve ser maisculo, o que deve ser minsculo, e outras
modificaes simples, tal inconveniente pode ser facilmente evitado, e a convenes como, por exemplo, a identao. Aqui, no seguimos essas
estrutura geral que ser apresentada pode ser utilizada de forma ampla. convenes.

Para que voc possa compreender cada componente do projeto mais


facilmente, vamos identific-los, aqui, com cores diferentes. Ao ser
copiado aqui, e colado l no arquivo Pro_QW, previamente criado no seu
8 O Primeiro Problema projeto, essas cores desaparecero dando lugar s cores normais de cada
palavra do cdigo.
Copie o programa desenvolvido na aula 2, chamado TESTE1, e cole-o na
subroutine callback subr1 da estrutura. Lembre-se que o seu antigo
programa agora uma subrotina e que algumas mudanas devem ser feitas
como, por exemplo,
!programa principal, chamado Prog_QW. Mude o nome, se for o caso
1) trocar STOP por RETURN, program Prog_QW

2) apagar a linha PROGRAM TESTE1, use msflib !biblioteca com muitas funes grficas e outras.

3) mudar a posio do "dimension" para o incio da callback subr1, etc. TYPE (windowconfig) wc !define uma varivel para as informaes sobre a
configurao do micro.
Compile e link novamente pro_QW.f90. Depois, veja se o programa que TYPE (qwinfo) winfo !define uma varivel para informaes sobre o
determina as razes de uma equao do segundo grau est funcionado dimensionamento do frame e child window.
corretamente, agora como a callback subroutine subr1. TYPE (XYCOORD) XY !define uma varivel para estabelecer uma posio no
vdeo atravs de coordenadas em pixels.
LOGICAL status

9 O Segundo Problema ! Maximiza a tela principal


winfo.TYPE = QWIN$MAX
ires = SETWSIZEQQ(QWIN$FRAMEWINDOW, winfo)
!as tarefas que sero executadas.
! obtm dados do sistema: nmero de pixels, etc.
wc.numxpixels = -1 !chama a callback subr1 (externa, feita pelo programador e
wc.numypixels = -1 !por isso foi declarada no incio da funo initialsettings)
wc.numtextcols = -1 result = APPENDMENUQQ(1, $MENUENABLED, 'Programa1'C, subr1)
wc.numtextrows = -1
wc.numcolors = -1 ! coloca um trao separando o primeiro item do segundo item
! a "janela filhote" se chamar "PROGRAMAS" mas o nome pode ser !do menu
!mudado para o desejado. result = APPENDMENUQQ(1, $MENUSEPARATOR, ''C,NUL )
wc.title= "PROGRAMAS"C ! ttulo da "janela filhote" (child window)
wc.fontsize = -1 result = APPENDMENUQQ(1, $MENUENABLED, 'Programa2'C, subr2)
status = SETWINDOWCONFIG(wc) ! estabelece a configurao do micro como result = APPENDMENUQQ(1, $MENUSEPARATOR, ''C, NUL )
aquela obtida anteriormente.
result = APPENDMENUQQ(1, $MENUENABLED, 'Programa3'C, subr3)
!colore a "janela filhote"
I=SETBKCOLORRGB(#909090) result = APPENDMENUQQ(1, $MENUSEPARATOR, ''C, NUL )
call clearscreen($gclearscreen)
result = APPENDMENUQQ(1, $MENUENABLED, 'Programa4'C, subr4)
!maximiza a "janela filhote"
Iresult=SETWSIZEQQ(0, winfo) result = APPENDMENUQQ(1, $MENUSEPARATOR, ''C, NUL )
inumfonts = INITIALIZEFONTS( ) !disponibiliza os tipos de fontes do result = APPENDMENUQQ(1, $MENUENABLED, 'Programa5'C, subr5)
micro.
result = APPENDMENUQQ(1, $MENUSEPARATOR, ''C, NUL )
!escolha do tipo de letras a serem usadas.
ifontnum = SETFONT ('t''Arial''h30w20i')! h30 a altura das letras na ! chama a subrotina winexit (interna, definida em msflib)
tela e w20 a largura. O i refere-se a itlico. !que termina a execuo do programa em loop infinito
result = APPENDMENUQQ(1, $MENUENABLED, 'Sair'C, WINEXIT)
! se ifontnum for -1, a fonte requerida no existe. Ento, deve-se
escolher outra fonte.
if(ifontnum.eq.-1) ifontnum = SETFONT ('t''times new roman''h30') !Cria um menu 2 chamado Informaes.
if(ifontnum.eq.-1) ifontnum = SETFONT ('t''courier new''h30') result = APPENDMENUQQ(2, $MENUENABLED, '&Informaes'C, NUL )
if(ifontnum.eq.-1) ifontnum = SETFONT ('t''tahoma''h30')
if(ifontnum.eq.-1) ifontnum = SETFONT ('t''cac futura casual''h30') !chama a callback WININDEX (subrotina interna, definida em
!MSFLIB) com ajuda sobre o QuickWin Application
!cor da palavra a ser escrita na tela (se voc quiser escrever)
result = APPENDMENUQQ(2, $MENUENABLED, 'Ajuda QuickWin'C, WININDEX)
i= setcolor(10)! de 0 a 15
result = APPENDMENUQQ(2, $MENUSEPARATOR, ''C, NUL )
!voc pode alterar as coordenadas onde a palavra ser escrita
call moveto (50,170,xy) ! coordenadas (em pixels) de onde ser escrita a
!chama a callback WINUSING (interna, definida em MSFLIB) com ajuda
palavra ou frase a seguir.
!sobre o uso do windows
call outgtext(' ') !escreva entre os apstrofes uma palavra ou frase para
result = APPENDMENUQQ(2, $MENUENABLED, 'Usando a Ajuda'C, WINUSING)
aparecer na tela
result = APPENDMENUQQ(2, $MENUSEPARATOR, ''C, NUL )

!chama a subrotina WINABOUT (interna, definida em MSFLIB) com


!Loop infinito: mantm o programa funcionando depois de executado
!informaes sobre o Power Station.
do while (.true.)
result = APPENDMENUQQ(2, $MENUENABLED, 'Sobre o Power Station'C, WINABOUT)
end do
result = APPENDMENUQQ(2, $MENUSEPARATOR, ''C, NUL )
end program ! fim do programa principal
!chama a callback leiame (externa, feita pelo programador e deve
!ser declarada no incio da funo initialsettings)
result = APPENDMENUQQ(2, $MENUENABLED, 'Leiame'C, leiame)
!//////////////////////////////////////////////////////////////////////////
INITIALSETTINGS= .true.
!Funo onde se define os itens do menu.
LOGICAL(4) FUNCTION INITIALSETTINGS()
END FUNCTION INITIALSETTINGS !fim da subrotina lgica que cria o menu.
USE MSFLIB
LOGICAL(4)result
external subr1, subr2, subr3, subr4, subr5, leiame
!//////////////////////////////////////////////////////////////////////////
!Cria um menu 1 chamado Arquivo
!subrotinas callbacks:
result = APPENDMENUQQ(1, $MENUENABLED, '&Arquivo'C, NUL )
!subrotinas callbacks onde voc pode colocar programas (5 subrotinas):
!Ateno: os nomes programa1, programa2, ..., programa5
subroutine subr1(ia)
!nos strings a seguir devem ser alterados de acordo com
USE MSFLIB subroutine subr2(ia)
logical ia
USE MSFLIB
ia = .true. !argumento da subrotina callback subr1 logical ia

CALL CLEARSCREEN($GCLEARSCREEN) !apaga o que estiver escrito na tela ia = .true.

!para abrir uma nova child window d os comandos abaixo (basta tirar !suspende todo o menu 1 durante a execuo desta subrotina
!o smbolo de comentrio "!") result = MODIFYMENUFLAGSQQ (1, 0, $MENUGRAYED)
!open(unit = 1, file = 'user', title = 'programa1') !ateno: se voc
!abrir, lembre-se de fechar antes do return. CALL CLEARSCREEN($GCLEARSCREEN)
!i = setbkcolor(12) ! colore a child window de vermelho
!call clearscreen($gclearscreen) !limpa a tela !PARA FAZER SEUS CLCULOS, CHAME UMA SUBROTINA OU...
!i= displaycursor($gcursoron) !ativa cursor !INSIRA O SEU CDIGO AQUI, E APAGUE A LINHA A SEGUIR
message = messageboxqq('Este item est indisponvel no
momento!'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1)
!suspende os itens do menu 1 durante a execuo desta subrotina
result = MODIFYMENUFLAGSQQ (1, 1, $MENUGRAYED) !reativa todo o menu aps a execuo desta subrotina
result = MODIFYMENUFLAGSQQ (1, 2, $MENUGRAYED) result = MODIFYMENUFLAGSQQ (1, 0, $MENUENABLED)
result = MODIFYMENUFLAGSQQ (1, 3, $MENUGRAYED)
result = MODIFYMENUFLAGSQQ (1, 4, $MENUGRAYED)
result = MODIFYMENUFLAGSQQ (1, 5, $MENUGRAYED) return
result = MODIFYMENUFLAGSQQ (1, 6, $MENUGRAYED)
result = MODIFYMENUFLAGSQQ (1, 7, $MENUGRAYED) end subroutine
result = MODIFYMENUFLAGSQQ (1, 8, $MENUGRAYED)
result = MODIFYMENUFLAGSQQ (1, 9, $MENUGRAYED)
!Obs: para suspender o menu 1 inteiro (e no item por item) bastaria !//////////////////////////////////////////////////////////////////////////
!dar o comando:
!result = MODIFYMENUFLAGSQQ (1, 0, $MENUGRAYED) subroutine subr3(ia)

USE MSFLIB
!PARA FAZER SEUS CLCULOS, CHAME UMA SUBROTINA OU... logical ia
!INSIRA O SEU CDIGO AQUI, E APAGUE A LINHA A SEGUIR
message = messageboxqq('Este item est indisponvel no ia = .true.
momento!'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1)
!suspende todo o menu 1 durante a execuo desta subrotina
result = MODIFYMENUFLAGSQQ (1, 0, $MENUGRAYED)
!reativa os itens do menu aps a execuo desta subrotina
result = MODIFYMENUFLAGSQQ (1, 1, $MENUENABLED) CALL CLEARSCREEN($GCLEARSCREEN)
result = MODIFYMENUFLAGSQQ (1, 2, $MENUENABLED)
result = MODIFYMENUFLAGSQQ (1, 3, $MENUENABLED) !PARA FAZER SEUS CLCULOS, CHAME UMA SUBROTINA OU...
result = MODIFYMENUFLAGSQQ (1, 4, $MENUENABLED) !INSIRA O SEU CDIGO AQUI, E APAGUE A LINHA A SEGUIR
result = MODIFYMENUFLAGSQQ (1, 5, $MENUENABLED) message = messageboxqq('Este item est indisponvel no
result = MODIFYMENUFLAGSQQ (1, 6, $MENUENABLED) momento!'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1)
result = MODIFYMENUFLAGSQQ (1, 7, $MENUENABLED)
result = MODIFYMENUFLAGSQQ (1, 8, $MENUENABLED) !reativa todo o menu aps a execuo desta subrotina
result = MODIFYMENUFLAGSQQ (1, 9, $MENUENABLED) result = MODIFYMENUFLAGSQQ (1, 0, $MENUENABLED)
!Obs: para ativar um menu inteiro desativado com o comando result =
MODIFYMENUFLAGSQQ (1, 0, $MENUGRAYED) basta dar o comando: return
!result = MODIFYMENUFLAGSQQ (1, 0, $MENUENABLED)
end subroutine

!message = messageboxqq('Este programa


terminou'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1) !//////////////////////////////////////////////////////////////////////////
!i= displaycursor($gcursoroff) !desativa cursor
!close(unit = 1) subroutine subr4(ia)

return USE MSFLIB


logical ia
end subroutine
ia = .true.

!////////////////////////////////////////////////////////////////////////// !suspende todo o menu 1 durante a execuo desta subrotina


result = MODIFYMENUFLAGSQQ (1, 0, $MENUGRAYED)
CALL CLEARSCREEN($GCLEARSCREEN) !//////////////////////////////////////////////////////////////////////////

!PARA FAZER SEUS CLCULOS, CHAME UMA SUBROTINA OU...


!INSIRA O SEU CDIGO AQUI, E APAGUE A LINHA A SEGUIR
message = messageboxqq('Este item est indisponvel no 11 Aparncia do Projeto Vazio
momento!'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1)
Depois de ser compilado e ligado, ao ser executado, o programa ter o
!reativa todo o menu aps a execuo desta subrotina seguinte aspecto (com reduo de 30% na tela):
result = MODIFYMENUFLAGSQQ (1, 0, $MENUENABLED)

return

end subroutine

!//////////////////////////////////////////////////////////////////////////

subroutine subr5(ia)

USE MSFLIB
logical ia

ia = .true.

!suspende todo o menu 1 durante a execuo desta subrotina


result = MODIFYMENUFLAGSQQ (1, 0, $MENUGRAYED)

CALL CLEARSCREEN($GCLEARSCREEN)

!PARA FAZER SEUS CLCULOS, CHAME UMA SUBROTINA OU...


!INSIRA O SEU CDIGO AQUI, E APAGUE A LINHA A SEGUIR
message = messageboxqq('Este item est indisponvel no
momento!'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1)

!reativa todo o menu aps a execuo desta subrotina


result = MODIFYMENUFLAGSQQ (1, 0, $MENUENABLED)

return

end subroutine
Voc percebeu alguma incoerncia nas teclas de atalho dos itens do menu
!////////////////////////////////////////////////////////////////////////// Arquivo?

subroutine leiame(ia)
Importante:
USE MSFLIB
logical ia 1) Conforme j comentamos, essa estrutura que estudamos
inicial, apropriada somente para a execuo de tarefas rpidas, e isso
ia = .true. ser resolvido na lio n 8. Alm disso, a estrutura contm uma funo
chamada runqq, para a execuo de programas externos, e essa funo trava
!Quando j existir um arquivo leiame, apague os dois o seu aplicativo durante a execuo de tal programa. Entretanto, isso pode
!prximos comandos de sua aplicao ser resolvido com o uso da funo WinExec (estude-a no HELP) em
message = messageboxqq('Este item est indisponvel no
substituio a runqq. Duas formas de uso da funo WinExec (DFWIN) foram
momento!'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1)
dadas na lista de funes da lio n 3.
return

i = runqq('write.exe','leiame.doc') 2) a estrutura estudada no dispe de uma toolbar e nem de


um pop-up menu. A propsito, QuickWin Application no dispe dessas opes
return (o Windows Application dispe) mas, depois da lio nmero 8, ns mesmos
criaremos uma estrutura completa que contenha todas essas opes, e que
end subroutine elimine os inconvenientes da estrutura atual.
12 - Avance um Pouco Mais: Construo e Insero de cones
Para substituir o cone do Windows tanto na Child quanto na Frame Window,
os cones substitutos inicialmente devem ser criados. Para criar, faa o
seguinte:

1) Clique no menu Insert e em seguida no item Resource...:

2) Vai aparecer a caixa Insert Resource. Ento, selecione Icon (a


palavra fica azul) e clique em New, conforme mostrado a seguir:

4) Para que tal cone aparea na Frame Window d um duplo clique na parte
branca do editor de cones e o identifique com a ID "Frameicon" (entre
aspas, primeira letra maiscula) conforme mostra a figura a seguir:

3) Aps clicar em New vai aparecer o editor de cones e voc deve


desenhar o seu. Veja um cone desenhado na figura a seguir: 5) Ao fechar a caixa Icon Properties e, depois, no menu File clicar em
Save para salvar as alteraes, dois arquivos foram criados pelo
compilador: 1) resource.fd e 2) script1.rc. NO MUDE OS NOMES DESSES
ARQUIVOS. Adicione-os ao projeto (Project, Add to Project, Files,
selecionando os dois arquivos na caixa Insert Files into Project e,
finalmente, clicando OK). Voc deve, ento, criar um novo executvel. Ao
execut-lo, perceber que o novo cone j est na Frame Window:

6) Para criar um cone para a Child Window o procedimento o mesmo


mostrado anteriormente, s que a identificao do cone deve ser ID:
"Childicon" (entre aspas, primeira letra maiscula). Atente para o fato de
que os arquivos resource.fd e script1.rc so automaticamente alterados
com a criao do segundo cone, mas eles no devem mais ser inseridos no
projeto, pois isso j foi feito na criao do primeiro cone. Ao executar
o aplicativo, a sua nova aparncia ser:
INTRODUO AO VISUAL FORTRAN CVF

Wilton, Cleide e Cleiton Diniz P. S. e Silva

Programador:

Aula n 5 - Dilogos: Tipos, Construo e Ativao de uma Caixa de


Dilogo

1 - Tipos de Dilogo
Dentre os tipos de dilogo utilizados em uma caixa, podemos destacar os
13 Avance Mais Ainda: Correo das Teclas de atalho seguintes:
Note que existe uma incoerncia nas teclas de atalho dos itens do menu 1) Static Text: retngulo (invisvel) para escrever mensagens estticas
Arquivo (os 5 primeiros itens seriam evocados com a seqncia alt + P diretamente na caixa de dilogo. Static Text aquele que em todas as
). Corrija essa falha na funo initialsettings, conforme as informaes execues do programa o texto o mesmo e o usurio no pode mudar.
contidas nesta lio. Entretanto, o prprio aplicativo pode mudar tal texto.

2) Edit Box: usada pelo usurio para informar dados a serem lidos pelo
programa.

3) Group Box: uma linha retangular de contorno que destaca partes da


caixa de dilogo.

4) Button: botes que permitem ao usurio tomar uma deciso dentre vrias
possibidades, encerrando o dilogo.

5) Check Box: pequenos quadrados (com opes) que permitem ao usurio


escolher vrias opes dentre as opes disponveis.

6) Radio Button: pequenos crculos (com opes) que permitem ao usurio


escolher uma nica opo dentre as opes disponveis.

Tais tipos de dilogos podem ser vistos na seguinte caixa:


Existem outros tipos de dilogo, conforme veremos ao longo da lio, no
Editor de Recursos (controls), e esses que foram mostrados aqui so os Vamos clicar na opo Dialog e, em seguida, em New. Vai aparecer uma caixa
mais comuns. Consulte, no Help de seu estdio, os vrios tipos de dilogo de dilogo j pronta, que voc pode modificar:
e, para tal, busque por dialog box. Ao longo desta lio utilizaremos
alguns dos dilogos apresentados, sendo que o Check Box e o Radio
Button sero estudados em lies futuras.

2 - Construo de uma Caixa de Dilogo


Para construir caixas de dilogo em um determinado projeto, abra o seu
workspace. No nosso caso, ns vamos implementar os dilogos nas subrotinas
callback do projeto Pro_QW. Para tal, certifique-se de que os clculos do
valor mdio e do desvio padro de uma srie de leituras (feitos na lio
anterior, em subr2) estejam corretos. Depois, verifique se os clculos das
razes de uma equao, feitos em subr1, tambm esto corretos.

3 - Procedimentos para a Construo


Inicialmente vamos construir uma caixa de dilogo para comunicar os
resultados do valor mdio e do desvio padro de uma srie de leituras
lidas em um arquivo de dados. Para tal, vamos seguir os seguintes passos:

1) Depois de abrir o projeto, clique no menu 'Insert' e, ento, clique no


item 'Resource...'.

2) Aparecero algumas opes na caixa Insert Resource:


Observe que o editor de recursos (Controls) aparece ( direta) junto com a
caixa de dilogo que modificaremos, que est do lado esquerdo. Evite
fechar o editor de recursos Controls mas, se fechar, abra-o novamente
dando um clique na barra de menus com o boto direito do mouse, e ativando
a opo Controls. Existem vrios tipos de dilogo, mas nem todos esto
disponveis em QuickWin Application. Passando o mouse sobre os dilogos,
no editor de recursos, tem-se uma informao resumida sobre cada um (para
uma informao mais detalhada, consulte o HELP).

3) D um duplo clique sobre a caixa de dilogo em construo. Veja que


aparece uma caixa (Dialog Properties), onde podemos definir as propriedades
da caixa em construo.
Note que o editor de recursos j atribuiu uma identificao, isto , uma
ID para a caixa em construo: IDD_DIALOG1. Podemos manter ou alterar esta
identificao. Vamos manter. O nome default da caixa de dilogo Dialog
e pode ser alterado em Caption mas tambm vamos mant-lo.

4) Por enquanto, a caixa de dilogo tem dois botes: Cancel e OK. D um Na caixa Insert Files into Project que vai aparecer, voc ver vrios
duplo clique no boto OK e observe que a caixa 'Push Button Properties' arquivos do projeto, inclusive o arquivo script1.rc.
aparece, e voc pode modificar ou atribuir propriedades ao boto. Veja que
ele tambm j tem uma constante identificadora (ID): IDOK. Vamos manter
esse nome e, em 'Caption', podemos alterar o texto que vai parecer no
boto. Vamos apenas sublinhar a letra O. Para tal, coloque o smbolo & (e
comercial) antes do O.

Feche a caixa de propriedades 'Push Button Properties'. A caixa de dilogo


j est parcialmente pronta, mas ainda no funcionaria se o executvel do
programa fosse criado agora: falta evocar a caixa em um dado ponto do
programa, onde tal caixa deve aparecer.
Clique nesse arquivo (ele fica azul) e depois no boto 'OK'. O arquivo
script1.rc ser automaticamente adicionado ao projeto. Enquanto a caixa de
dilogo foi construda, o compilador criou um outro arquivo (resource.fd)
4 - Caixa de Dilogo: Salvamento e Incluso no Projeto. com informaes sobre todos os elementos (botes, radiobutton, check box,
etc.) de toda(s) a(s) caixa(s) de dilogo. Na verdade, trata-se de uma
5) Para funcionar, a caixa deve ser salva. Para salv-la, faa o tabela relacionando os elementos das caixas (identificados por smbolos
seguinte: no menu 'File' selecione o item 'Save'. Caso voc ainda no alfanumricos) a nmeros inteiros identificadores. Essas informaes devem
tenha includo nenhum recurso no projeto, no primeiro salvamento pedido ser includas nos programas e subprogramas com dilogos (no cabealho,
o nome do script: aparece um nome default, script1.rc. NO MUDE ESSE NOME pois trata-se de declarao de constantes). Assim, ao longo do programa,
. O arquivo script1.rc foi criado pelo prprio compilador Fortran com as pode-se referir a essas constantes de forma apropriada, em comandos,
informaes sobre o(s) dilogo(s) e demais recursos, e deve ser adicionado visando a identificar uma ao do usurio em uma caixa. Insira resource.fd
no projeto. no projeto, da mesma forma que voc inseriu script1.rc.

6) Para adicionar script1.rc ao projeto, faa o seguinte: clique no menu ' 7) Agora, sua janela com os componentes do projeto deve ter ficado assim:
Project' e depois no item 'Add To Project' e, finalmente, em 'Files...':
alteraes deveriam ser feitas na seo de declarao, o que seria um
grande inconveniente.

Agora, precisamos definir uma varivel para o argumento da funo lgica


que inicia o dilogo (dlginit), declarando:

TYPE (DIALOG) DLG

logo abaixo do "include resource.fd". A varivel DLG chamada de varivel


derivada de tipo dilogo (relembre-se que as variveis bsicas da
linguagem so: inteira, real, lgica, literal e complexa). Como o dilogo
inicializado, no programa, por uma funo lgica (dlginit), devemos
declarar tambm:

LOGICAL RETLOG

logo abaixo do "type (dialog) dlg". RETLOG uma varivel lgica de


retorno da funo que inicia o dilogo (.true. significa que a
inicializao teve sucesso e .false. que no).

6 - Ativao da Caixa: Evocao do Dilogo


Para que um dilogo seja efetivamente estabelecido num determinado ponto
do programa, devemos dar a seguinte seqncia de comandos, no local do
5 - Ativao da Caixa de Dilogo no Programa: Primeiros Passos programa onde tal dilogo deve aparecer:

Ns vamos utilizar a caixa de dilogo parcialmente construda para RETLOG = DLGINIT(IDD_DIALOG1,DLG)


comunicar os resultados dos clculos efetuados para o valor mdio e o
desvio padro da srie de leituras, em subr2. Entretanto, no nos "dlginit" a funo lgica que inicia o dilogo. J "idd_dialog1" a
preocuparemos com isso agora. Inicialmente, vejamos o cdigo para evocar a identificao (ID) da caixa que construmos parcialmente. Tal
identificao poderia ter sido alterada, mas no o fizemos. Na verdade,
caixa de dilogo num dado ponto do programa.
"idd_dialog1" uma constante criada pelo CVF para identificar a caixa de
Para que o programa disponibilize a caixa de dilogo, durante a sua dilogo e, em resource.fd, declarada assim (veja em resource.fd):
execuo, necessrio utilizar uma biblioteca (mdulo) com funes
e subrotinas que possibilitem essa disponibilizao, integrando o integer, parameter :: IDD_DIALOG1 = 101
conjunto Programa-Dilogo. Para isso, na callback subr2 (onde ns usaremos
o dilogo parcialmente construdo) declare, alm de Assim, em todo comando que contiver o argumento IDD_DIALOG1 podemos
escrever simplesmente o valor 101, e isso vale para a lista inteira
USE MSFLIB contida em resource.fd. Entretanto, para uma lista grande, muito mais
cmodo escrever os smbolos do que os seus valores (definidos quando
o seguinte: declaramos, no cabealho, include resource.fd).

USE DIALOGM J a varivel "dlg" a chamada varivel derivada de tipo dilogo pois,
conforme j enfatizamos, as variveis bsicas da linguagem so: inteira,
O mdulo dialogm contm funes e subrotinas que usaremos para real, lgica, literal e complexa.
estabelecer o dilogo.
Em subr2, o comando
Para utilizar as informaes contidas em resource.fd, d o comando:
RETLOG = DLGINIT(IDD_DIALOG1,DLG)
INCLUDE 'RESOURCE.FD'
deve ser colocado imediatamente depois dos clculos do valor mdio e do
logo aps a declarao "use dialogm". A declarao include inclui, no desvio padro (antes do comando write).
local em que ela aparece, todas as declaraes contidas em um arquivo
feito em separado pelo prprio compilador durante a construo da caixa. Aps o comando dlginit deveramos anotar os comandos que escrevem os
Conforme mencionamos, o prprio compilador Fortran cria um arquivo com um resultados calculados pelo programa na caixa de dilogo, mas tais comandos
conjunto de declaraes de valores de parmetros, correspondentes aos sero vistos mais frente. Por hora, vamos dar o comando:
recursos de dilogo que foram usados. Muito embora no seja recomendvel,
voc poderia copiar todas as declaraes de valores de constantes do IRET = DLGMODAL(DLG)
arquivo resource.fd e colar na seo de declaraes, em substituio
declarao INCLUDE 'RESOURCE.FD'. S que, quando o arquivo resource.fd for "dlgmodal" uma funo inteira que estabelece, de fato, o dilogo. Em
alterado, pela adio de novos dilogos (ou alterao dos existentes) as QuickWin Application uma caixa de dilogo sempre modal (enquanto a caixa
estiver ativa, todo o resto fica suspenso, espera da ao do usurio na
caixa). Um outro tipo de caixa de dilogo a modeless, que possibilita ao
8 - Inserindo Static Text na Caixa de Dilogo em Construo
usurio desenvolver outras aes no aplicativo, mesmo com a caixa de
dilogo ativa. QuickWin Application no possibilita a construo de caixas Para enviar dados caixa de dilogo, ns devemos especificar reas da
de dilogo do tipo modeless. caixa (endereos) para esse fim. Para acessar novamente a caixa de dilogo
d um duplo clique no arquivo script1.rc, disponvel na janela que mostra
Na seqncia, deveramos dar os comandos que lem dados na caixa de dilogo os arquivos do projeto (essa janela do lado esquerdo). Depois, d um duplo
, para serem usados no programa. Tais comandos sero vistos mais frente. clique sobre pasta "dialog" (na janela com os componentes do projeto) e,
Por enquanto, para encerrar o dilogo, devemos escrever: finalmente, um duplo clique em IDD_DIALOG1. A caixa de dilogo e o editor
de recursos (controls) vo aparecer. Para escrever textos e resultados na
CALL DLGUNINIT(DLG) caixa de dilogo, vamos utilizar a caixa 'Static Text' (boto identificado
no editor de recursos pelo smbolo Aa). Proceda assim:
"dlguninit" uma subrotina que finaliza o dilogo.
1) Clique no boto Aa do editor de recursos (controls) e depois clique na
Obs: IRET um inteiro (retorno de dlgmodal) igual ao valor estabelecido posio desejada da caixa de dilogo onde o Static Text deve aparecer.
pelo CVF em 'resource.fd' para o boto clicado, e o seu valor deve ser Ento, vai aparecer uma caixa de 'Static Text'.
usado pelo programador para que o programa identifique qual foi o boto
clicado na caixa de dilogo.

7 Problema
Inserir a caixa de dilogo identificada por IDD_DIALOG1 em subr2 para
apresentar os resultados obtidos pela callback que calcula o valor o mdio
e o desvio padro de uma srie de dados.

Ateno: Aps os clculos efetuados pela callback subr2 (valor mdio e


desvio padro dos dados), devemos evocar a caixa de dilogo identificada
por IDD_DIALOG1 (inteiro, cujo valor, conforme vimos, 101). Para tal,
lembre-se dos comandos:
2) D um duplo clique em cima da caixa de 'Static Text' (ou um clique o
retlog = dlginit(idd_dialog1,dlg) boto direito do mouse, selecionando properties no pop-up menu). Vai
aparecer a caixa 'Text Properties', j com uma constante de identificao
aqui deveria ter os comandos que escrevem na caixa os resultados (ID) chamada IDC_STATIC para a static text. Mantenha esse nome para a
calculados pelo programa (nada aqui, por enquanto) constante e, em 'Caption', apague o texto existente. No lugar, escreva:
Valor Mdio: VM =. A caixa 'Text Properties' fica com o seguinte aspecto:
iret = dlgmodal(dlg)

aqui deveria ter os comandos que lem na caixa os dados


informados pelo usurio (nada aqui, por enquanto)

call dlguninit(dlg)

Depois de escrever os trs comandos indicados anteriormente (logo aps os


clculos do valor mdio e do desvio padro), compile e execute o programa.
Observe se os dois botes da caixa de dilogo (OK e Cancel) esto
funcionando corretamente. Para tal, aps o comando

CALL DLGUNINIT(DLG)

d um comando (provisrio, s para teste) para imprimir o valor de IRET na Feche essa caixa.
tela. Execute o programa vrias vezes, clicando em OK e em Cancel, e
observe, em cada situao, o valor de IRET. Veja que ao clicar no boto OK 3) Clique em outra caixa 'Static Text' no editor de recursos e coloque-a
, temos IRET = 1. Ao clicar em Cancel, temos IRET = 2 (esses so dois na frente da primeira. D um duplo clique sobre a segunda 'Static Text'
valores default. Qualquer outro boto adicionado caixa ter o seu valor para ativar a caixa 'Text Properties'. Utilize a caixa de propriedades
definido em resource.fd, pelo prprio compilador). Podemos usar estes para identificar (ID) a segunda static text com o nome IDC_STATIC1.
valores constantes num programa para que ele reconhea e tome as decises nela que o programa vai escrever o valor de XBARRA, que j deve ter sido
impostas pelo usurio atravs do boto clicado. calculado em subr2. Feche a caixa 'Text Properties' e aumente um pouco o
comprimento de IDC_STATIC1. O aspecto da caixa agora o seguinte:
9 - Insero de um Bitmap na Caixa de Dilogo
Suponha que tenhamos o seguinte bitmap em um diretrio, e que queiramos
inseri-lo na caixa de dilogo em construo:

Agora que o bitmap est adicionado ao projeto, ele pode ser inserido na
caixa de dilogo IDD_DIALOG1. Para tal, na janela com os componentes do
Para tal, devemos importar o bitmap para o projeto, o que requer, no menu projeto (veja na figura anterior), d um duplo clique em IDD_DIALOG1 que a
Insert, clicar no item Resource.... Como anteriormente, vai aparecer a caixa em construo vai aparecer. Ento, clique em Picture no editor de
caixa Insert Resource. Voc deve selecionar Bitmap e depois clicar no recursos (controls) e depois d outro clique na posio da caixa onde o
boto Import. Vai aparecer uma caixa chamada Import Resource e, via bitmap deve aparecer. A caixa em construo ter o seguinte aspecto:
browse, localize o arquivo com o bitmap:

Ento, aponte o mouse para a linha do retngulo picture e d um duplo


clique no boto esquerdo do mouse que a caixa Picture Properties vai
aparecer. Em seguida, com a opo Type em Bitmap selecione, na opo
Image, o nome genrico do bitmap no projeto: IDB_BITMAP1:

Em seguida, basta clicar no boto Import que o arquivo ser incorporado


ao projeto com a identificao IDB_BITMAP1. No menu File clique em Save
all para salvar a nova configurao do projeto. Quanto aos recursos,
agora temos:
1) como reservamos 256 caracteres para escrever nmeros com uns poucos
caracteres, devemos eliminar os espaos em branco da varivel "text" e
isso feito com a funo TRIM. Para ajustarmos os nmeros as serem
escritos no lado esquerdo de "IDC_STATIC1" e "IDC_STATIC2", usamos a
funo ADJUSTL ("ADJUST" = ajustar e o "L" de left = esquerdo).

2) Os comandos anteriores, que enviam resultados do programa para uma


caixa de dilogo, devem ficar entre o comando que inicia e o que estabelece
o dilogo:

RETLOG = DLGINIT(IDD_DIALOG1,DLG)

comandos para escrever XBARRA e DESV_PAD

IRET = DLGMODAL(DLG)

3) Os comandos que lem dados de uma caixa de dilogo (a serem processados


pelo programa) devem ficar entre o comando que estabelece e o que encerra
o dilogo:

IRET = DLGMODAL(DLG)

comandos que lem dados na caixa

CALL DLGEXIT(DLG)
Ao fechar a caixa de propriedades Picture Properties, salve o projeto.

4) No final desta lio pode-se encontrar o cdigo para a leitura dos


coeficientes de uma equao do segundo grau informados em 3 edit boxes
10 - Final da Ativao da Caixa de Dilogo em Construo (idc_edit1, idc_edit2 e idc_edit3) de uma caixa de dilogo identificada
por IDD_DIALOG2. Por enquanto, apenas compile e execute o aplicativo.
Depois de repetir alguns dos ltimos passos para escrever tambm DESV_PAD Clicando-se em Programa2 no menu arquivo de nosso aplicativo temos,
em IDC_STATIC2, apague o boto Cancel. Utilize o menu File e clique em S finalmente:
alve para salvar as alteraes feitas na caixa de dilogo. Para
efetivarmos a sada de dados, necessitamos de uma varivel do tipo
caractere para escrever os resultados nas 'Static Text'. Isto necessrio
para transformar os valores reais em textos, que sero escritos em
idc_static1 e em idc_static2 (tudo deve ser escrito na caixa de
dilogo como um texto). Por isso, no incio de subr2, na seo de
declaraes, isto , cabealho), devemos declarar:

CHARACTER (256) TEXT

Os comandos para escrever XBARRA e DESV_PAD so os seguintes:

WRITE(TEXT,*) XBARRA !escreve o real XBARRA na


!varivel caractere TEXT

RETLOG = DLGSET(DLG, IDC_STATIC1, TRIM(ADJUSTL(TEXT)))


! escreve o caractere TEXT na static text idc_static1

Deve ser observado que o arquivo dados.dat j deve estar no diretrio do


WRITE(TEXT,*) DESV_PAD projeto conforme foi mencionado na lio n 3 (seno teramos um erro de
execuo). Por outro lado, ao apagar o boto Cancel, o X no canto
RETLOG = DLGSET(DLG, IDC_STATIC2, TRIM(ADJUSTL(TEXT))) direito e superior da caixa deixa de funcionar (faa o teste e verifique
isso). Tire-o da caixa (descubra como) e depois centralize-a na child
window.
Ateno:
Ateno: Caso voc queira manter o X, ento, para faz-lo funcionar,
proceda da seguinte forma: d um duplo clique sobre o boto OK para que reescreva o valor errado (se no conseguir, veja como isso feito no
a caixa de propriedades de tal boto aparea. Em Caption, mantenha o projeto completo pro_QW, disponvel na pasta de instalao do VFortran
texto OK, mas na identificao (ID) troque o IDOK por IDCANCEL (o X Tutorial).
deve ser associado ao IDCANCEL). Depois, salve as alteraes, compile e
execute o aplicativo.
Veja que o cdigo aqui apresentado obtm valores informados pelo usurio (
dlgget) em trs edit Box: idc_edit1, idc_edit2 e idc_edit3. Lembrando que
o usurio deve identificar quais so os coeficientes a serem informados (e
11 - Avance um Pouco Mais: Cdigo para Leitura (Via Caixa onde inform-los), a caixa que voc ir criar pode ter o seguinte aspecto:
de Dilogo) dos Coeficientes da Equao do Segundo Grau
Observe que, no fragmento de programa mostrado logo a seguir, temos os
comandos para ler os coeficientes A(1), A(2) e A(3) da equao do segundo
grau (programa colocado em subr1, lio n 2) em uma nova caixa de dilogo
identificada por idd_dialog2. Implemente isso no seu projeto e crie tambm
uma terceira caixa de dilogo para apresentar os resultados das razes da
equao do segundo grau. Veja o que vem a seguir.

O cdigo para leitura dos coeficientes.

10 continue

retlog = dlginit(idd_dialog2,dlg)
!inicia o dilogo idd_dialog2
Para completar, a sua caixa de dilogo para a sada de resultados poderia
iret = dlgmodal(dlg) ter o seguinte aspecto:
!estabele o dilogo (iret tem o valor do boto cliclado)

if(iret == 2) then !foi clicado o boto Cancel


call dlguninit(dlg) !encerra o dilogo
return !retorna para initialsettings()
end if

iproblema = 0 !varivel auxiliar na deteco de erro na leitura

retlog = dlgget(dlg,idc_edit1,text) !obtenha o texto de edit1


read(text,*,iostat = ierr)a(1) !leia, em text, o real a(1)
if(ierr /= 0) iproblema = 1 !iproblema = 1, erro na leitura

retlog = dlgget(dlg,idc_edit2,text) !obtenha o texto de edit2


read(text,*,iostat = ierr)a(2) !leia, em text, o real a(2)
if(ierr /= 0) iproblema = 1

retlog = dlgget(dlg,idc_edit3,text) !obtenha o texto de edit3


read(text,*,iostat = ierr)a(3) !leia, em text, o real a(3) 12 - Avance Mais Ainda: O Projeto j Pronto
if(ierr /= 0) iproblema = 1
Na pasta em que o Vfortran Tutorial foi instalado voc pode encontrar o
call dlguninit(dlg) ! encerra o dilogo projeto completo (pro_QW.zip ou pro_QW_English.zip), desenvolvido ao longo
dessas cinco lies. J que voc chegou at aqui, bom observar como
if(iproblema == 1) then ficaria o projeto completo, com a incluso de alguns recursos adicionais,
message = messageboxqq('Erro na no tratados nessas lies. Veja o aspecto geral:
leitura!'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION)
goto 10 !v para o endereo 10 reler os dados
end if

Ateno - o cdigo fonte apresentado acima apresenta o seguinte


inconveniente: se um valor for digitado errado na caixa de dilogo, o
aplicativo detecta e manda o usurio reescrever, s que o usurio deve
reescrever todos os valores. Modifique o cdigo para que o usurio s
Veja o menu Arquivo
Observe que, nesta tela, h a abertura de uma nova janela, chamada dados
similares, e esse recurso de abertura de janelas s ser abordado em
detalhes na lio n6. Este recurso de abertura de novas janelas muito
importante por possibilitar escrever em uma tela, preservando-se a tela
original: assim que a janela aberta for fechada, tem-se a tela original,
intacta.

Esperamos que tal projeto lhe seja til, mas ressaltamos que ele s
interessante para a execuo de tarefas rpidas, pois ainda contm alguns
defeitos, apontados na lio n 4. Nessa lio mencionamos tambm que um
projeto muito mais abrangente ser apresentado na lio n 8, e desejamos
que voc tenha disposio para chegar at l.

e note que possvel abrir o arquivo dados.dat a partir do prprio


aplicativo, para a informao ou modificao do conjunto de dados. Para
isso, foi usada a funo runqq, atravs do comando

i = runqq('write.exe', 'dados.dat')

sendo que a funo runnqq definida no mdulo MSFLIB (ou DFLIB). Voc
poderia utilizar, ainda, uma funo do Windows Application, definida em
(MSFWIN ou DFWIN):

i = WinExec('notepad.exe dados.dat',sw_show)

Depois de informar os dados, clicando-se no item Tratamento de Dados,


tem-se a seguinte tela mostrando os resultados:
INTRODUO AO VISUAL FORTRAN CVF

Wilton, Cleide e Cleiton Diniz P. S. e Silva

Programador:

Aula n 6 Animaes Simples: Idia Bsica, Abertura de Janelas, Caixa


de Dilogos: check box e radio button, Dlgsetsub: evocao de callbacks
via caixa de dilogo, Recursive Callback, Grficos 2D e 3D: Noes

1 - Introduo
Voc pode mudar a origem do sistema de eixos para outro local atravs da
O princpio de uma animao muito simples e se baseia na superposio subrotina SETVIEWORG e a forma de fazer isto pode ser vista no HELP do seu
imagens em determinados intervalos de tempo. As imagens a serem estdio.
superpostas por um programa em Fortran podem ter duas origens:

1) podem ter sido feitas por outro software, como bitmaps, e o programa
Fortran somente apresentar essas imagens na seqncia adequada, 2 - Criao de uma Animao Simples

2) podem ser geradas por linhas de cdigo no prprio programa Fortran. Para criar a nossa animao simples, vamos dividir o cdigo em um programa
principal chamado
Alm dessas duas possibilidades, um programa Fortran ainda pode exibir
vdeos, mas concentraremos nossa ateno na opo de nmero 2. Para tal, PROGRAM ANIMA
necessrio conhecermos os tipos de sistemas de coordenadas para a tela. Em
QuickWin Application temos dois sistemas bsicos de coordenadas: o com as definies para as janelas (tamanho, cor da tela, etc) e em uma
primeiro baseado em linhas (Rows) e colunas (Columns) e o segundo, em subrotina que cria o movimento em si, que denominaremos
pixels (h um terceiro tipo, semelhante ao segundo, mas no falaremos
nele). Para utilizar este segundo sistema de coordenadas necessrio SUBROUTINE MOVIMENTO(IY)
definir, no cabealho do programa, uma varivel do tipo derivada para este
fim, declarando: O argumento IY define a coordenada Y onde a estrada ser desenhada.

TYPE (xycoord) pos

a varivel "pos" aquela que, em um comando, identifica o sistema de 3 - O programa Principal Definies Gerais
coordenadas que deve ser utilizado (naquele comando). A origem do sistema
de eixos da Child Windows no canto superior esquerdo da tela, sendo que Naturalmente, vamos criar um programa principal que contenha elementos
x cresce para a direita e y para baixo: grficos, o que requer as seguintes declaraes iniciais:

USE MSFLIB

ou dflib, que biblioteca que contm elementos grfico no DVF e no CVF.


Para definir o sistema de coordenadas declararemos

TYPE (XYCOORD) POS

Convm lembrar que esta coordenada definida para o posicionamento em


pixels do cursor na tela.

J para maximizar a tela necessria a seguinte declarao, no cabealho:


TYPE (QWINFO) WINFO

Com essas declaraes iniciais, j podemos comear o programa em si, dando


os dois comandos para a maximizao da tela:

winfo.TYPE = QWIN$MAX

i =SETWSIZEQQ(QWIN$FRAMEWINDOW, winfo) Para apresentar a janela no estilo TILE, use a funo

I = CLICKMENUQQ(QWIN$TILE)
Para colorir a tela (Child Window) de branco utilize a funo
Para disponibilizar as fontes do micro deve-se dar o comando
i = SETBKCOLOR(15)
i = INITIALIZEFONTS( )
cujas cores vo do nmero 0 (preto) at 15 (branco), ou ento d o comando
J para utilizar uma das fontes disponibilizadas, com o objetivo de se
i = SETBKCOLORRGB(#ffffff) escrever mensagens na tela, deve-se dar um comando do tipo

que estabelece a cor branca para a tela, em hexadecimal (veja no HELP as i = SETFONT ('t''Arial''h30')
funes setbkcolorrgb e setcolorrgb).
Nesse comando fica claro que vamos escrever mensagens com a fonte Arial e
Na seqncia do comando que colore a tela, chame a subrotina que limpa a a altura das letras 30 pixels. A largura tambm poderia ser
cor anterior da tela inteira: especificada, bem como outros detalhes (negrito, sublinhado, etc), o que
pode ser visto no HELP de seu estdio.
CALL CLEARSCREEN($GCLEARSCREEN)
Cada uma das funes apresentadas retorna um valor que pode ser
interpretado como a resposta do sistema ao comando, e essa reposta informa
Pode-se eliminar a barra de status (parte inferior da Frame Window), se o comando foi ou no executado. Como exemplo, ao dar o comando i =
mostrada no exemplo a seguir, setfont('t''Arial''h30'), se tivermos i = 1, porque o micro no dispe
daquela fonte (Arial com altura de 30 pixels) e outra deve ser escolhida.
Estude, no HELP de seu estdio, as possveis respostas de cada uma das
funes que ns apresentamos.

4 - O programa Principal Desenho de um Carrinho Ba


Aps as definies gerais dadas anteriormente, vamos criar um carrinho de
brinquedo cuja carroceria um retngulo, a cabine outro retngulo, e os
com o uso da funo pneus so crculos. O carrinho deve estar inicialmente do lado esquerdo da
pista e, ao ser acionado, deve se deslocar para a direita. Vejamos um
I = CLICKMENUQQ(QWIN$STATUS) fragmento do cdigo:
Com o uso de clickmenuqq(qwin$status), a parte inferior da frame window
fica assim:
...
...
i = setcolor(5) !cor magenta

call moveto(150,5,pos)
!leva cursor para as coordenadas indicadas

call outgtext('Tecle "Enter" para iniciar')


Uma tela pode ser apresentada no estilo normal, como este a seguir !escreve o texto indicado em x = 150 e y = 5

i = setcolor(9) !a pista azul

call moveto(10,250+iy,pos)
!leva cursor para as coordenadas indicadas

i = lineto(590,250+iy)
ou no estilo tile, conforme a figura !traa um linha at a posio indicada
!caminho: ix a varivel para mudar a posio do caminho Uma vez teclado ENTER, o caminho deve partir. Assim, aps o comando
read(*,*), que espera pelo sinal de partida, deve-se chamar a subrotina
i = setcolor(14) que vai produzir o movimento:
!cor da carroceria do caminho ba (amarela)
CALL MOVIMENTO(IY)
i = rectangle($gfillinterior,20+ix,215+iy,60+ix,242+iy)
!"$gfillinterior" significa pintar todo o interior do retngulo Depois disso, o programa principal deve ser encerrado, com os comandos

i = setcolor(10) !cor da cabine do caminho ba (verde) STOP

i = rectangle($gfillinterior,61+ix,225+iy,75+ix,242+iy) e

i = setcolor(5) END
!cor do contorno da cabine e da carroceria (magenta)

i = rectangle($gborder,20+ix,215+iy,60+ix,242+iy)
!"$gborder" significa desenhar s o contorno. 5 - A Subrotina que Produz o Movimento
i = rectangle($gborder,61+ix,225+iy,75+ix,242+iy) A subrotina que produz o movimento desenvolvida a partir da seguinte
lgica: um desenho exposto ao observador por um dado intervalo de tempo,
i = setcolor(0) !cor dos pneus digamos 80 ms. Depois, o desenho apagado e imediatamente refeito mais
frente, com ou sem alteraes, ficando exposto por mais um certo
i = ellipse($gfillinterior,25+ix,243+iy,31+ix,249+iy) intervalo de tempo, o que d a sensao de movimento. A varivel que
!pneus traseiros possibilitar deslocar o desenho ix, e pode-se usar um LOOP para fazer a
variao contnua de ix. Assim, a estrutura da subrotina ser a seguinte:
i = ellipse($gfillinterior,64+ix,243+iy,70+ix,249+iy)
!pneus dianteiros

read(*,*) !espera pelo "Enter" subroutine movimento(iy)


...
... use msflib

type (xycoord) pos

O programa principal, construdo conforme as instrues anteriores, ao ser do ix = 0, 500, 2


executado apresentar a seguinte tela:
desenho do caminho na posio ix, com suas cores

call sleepqq(80) !tempo de exposio do desenho

i = setcolor(15) !cor da tela: apaga o caminho

desenho do caminho na posio ix, sem suas cores

end do

return

end subroutine

Note que, inicialmente, o caminho desenhado para ix = 0, por 80 ms, e


depois apagado. Ento, na seqncia do loop, redesenhado para ix = 2
(2 pixels frente), por mais 80 ms, e apagado novamente. O movimento s
cessa para ix = 500, o que significa que a posio final do caminho 500
pixels direita do ponto de partida. A seguir ser apresentado todo o
cdigo fonte para produzir a animao.

6 - Avance um Pouco Mais: Abertura de Janelas


Caso o usurio queira preservar a Child Window e criar uma outra janela
para apresentar novos elementos, basta usar o comando Open conforme i = SetWSizeQQ(1, winfo)
mostrado a seguir:
i = setbkcolorrgb(#ffffff)
open(unit = 1, file = 'user', title = 'Nova Janela')
call clearscreen($gclearscreen)
a identificao file = user indica no se tratar de um arquivo fsico, em
si, mas sim de uma nova janela (no caso, com o ttulo de Nova Janela). A i = setcolor(9)
child window tem a unidade default de nmero 0 e a que estamos abrindo com
o comando anterior tem o nmero 1: unit = 1. Para dimensionar o tamanho da call moveto(10,250+iy,pos)
janela necessrio definir a varivel de tipo derivada qwinfo o que,
i = lineto(590,250+iy)
nesta lio, j foi feito no programa principal com a declarao
call movimento(iy)
Type (qwinfo) winfo
close(1)
Para obter informaes sobre o tamanho mximo e a posio da child window ...
deve-se dar o comando ...
i = getwsizeqq(0,QWIN$SIZEMAX,winfo) Ao executar o aplicativo, na parte final da execuo ele ter a seguinte
aparncia:
O argumento 0 refere-se child window e o segundo argumento indica
tratar-se das dimenses mximas. Tais dimenses, e tambm a posio do
canto superior esquerdo, so retornadas na varivel winfo, do seguinte
modo:

winfo.y d a posio y do canto superior esquerdo;

winfo.x d a posio x do canto superior esquerdo;

winfo.w d a largura da janela

winfo.h d a altura da janela

Para estabelecer um novo tamanho e posio para a child window deve-se dar
o comando

i = SetWSizeQQ(0, winfo)

aps ter sido definido os novos valores para winfo.y, winfo.x, winfo.w e
winfo.h.

Para utilizar essas informaes sobre abertura de janelas (aps executar o


programa da animao como foi proposto originalmente), faa o seguinte:
logo depois do comando

call movimento(iy)

no final do programa principal (antes do STOP) entre com o seguinte cdigo:

...
...
i = getwsizeqq(0,QWIN$SIZEMAX,winfo)

winfo.y = 0

winfo.x = 0 7 - Cdigos fontes


winfo.h = winfo.h/1.5
program anima
i = SetWSizeQQ(0, winfo)
use msflib !biblioteca com elementos grficos
winfo.y = winfo.h / 2
implicit none
open(unit = 1, file = 'user', title = 'Nova Janela') !elimina a facilidade de no declarar variveis
type (xycoord) pos i = rectangle($gfillinterior,20+ix,215+iy,60+ix,242+iy)
!varivel que identifica o tipo de coordenada usada !"$gfillinterior" significa pintar todo o retngulo

type (qwinfo) winfo i = setcolor(10) !cor da cabine do caminho ba


!varvel para informar o tamanho da janela
i = rectangle($gfillinterior,61+ix,225+iy,75+ix,242+iy)
integer i, ix, iy
!declarao de variveis i = setcolor(5) !cor do contorno da cabine e carroceria

winfo.TYPE = QWIN$MAX i = rectangle($gborder,20+ix,215+iy,60+ix,242+iy)


!tamanho mximo para a tela !"$gborder": significa desenhar s o contorno.

i = SETWSIZEQQ(QWIN$FRAMEWINDOW, winfo) i = rectangle($gborder,61+ix,225+iy,75+ix,242+iy)


!Maximiza a janela principal
i = setcolor(0) !cor dos pneus
i = setbkcolor(15)
!colore a tela de branco, mas ela deve ser limpa i = ellipse($gfillinterior,25+ix,243+iy,31+ix,249+iy)
!pneu traseiro
call clearscreen($gclearscreen)
!limpa a cor antiga e aparece o branco i = ellipse($gfillinterior,64+ix,243+iy,70+ix,249+iy)
!pneu dianteiro
iy = 0
!iy permite mudar a posio vertical do desenho read(*,*) !espera pelo "Enter"

ix = 0 i = setcolor(15) !letras brancas: "apaga" a frase


!define a posio inicial do caminho na horizontal
call moveto(150,5,pos)
i = clickmenuqq(QWIN$STATUS) !leva cursor para as coordenadas indicadas
!Elimina barra de status
call outgtext('Tecle "Enter" para iniciar')
i = clickmenuqq(QWIN$TILE) !escreve o texto indicado
!janela filhote no estilo tile
call movimento(iy)
i = INITIALIZEFONTS( ) !chama a subrotina que criar o movimento
!disponibiliza fontes para escrever na tela
stop
i = SETFONT ('t''Arial''h30') !fonte a ser utilizada
!se i for 1, ento a fonte solicitada no est end program
!disponvel no micro e outra deve ser escolhida
if(i .eq. -1) i = SETFONT ('t''times new roman''h30')
if(i .eq. -1) i = SETFONT ('t''courier new''h30')
if(i .eq. -1) i = SETFONT ('t''tahoma''h30')
if(i .eq. -1) i = SETFONT ('t''cac futura casual''h30') subroutine movimento(iy)

i = setcolor(5) !cor magenta use msflib

call moveto(150,5,pos) type (xycoord) pos


!leva cursor para as coordenadas indicadas !varivel que identifica o tipo de coordenada usada

call outgtext('Tecle "Enter" para iniciar') do ix = 0, 500, 2


!escreve o texto indicado em x = 150 e y = 5 !o passo d o avano da imagem, em pixels.
!ix a varivel para mudar a posio do caminho
i = setcolor(9) !a pista azul
i = setcolor(14)
call moveto(10,250+iy,pos) !cor da carroceria do caminho ba
!leva cursor para as coordenadas indicadas
i = rectangle($gfillinterior,20+ix,215+iy,60+ix,242+iy)
i = lineto(590,250+iy) !"$gfillinterior" significa pintar todo o retngulo
!traa um linha at a posio indicada
i = setcolor(10) !cor da cabine do caminho ba
! caminho
!ix a varivel para mudar a posio do caminho i = rectangle($gfillinterior,61+ix,225+iy,75+ix,242+iy)
i = setcolor(14) !cor da carroceria do caminho ba
i = setcolor(5)
!cor do contorno da cabine e carroceria ordem, idc_radio1, idc_radio2 e idc_radio3. Ns vamos estabelecer o
dilogo no final do cdigo da animao, imediatamente antes do STOP.
i = rectangle($gborder,20+ix,215+iy,60+ix,242+iy)
Para tal voc deve, na seo de declarao do programa principal, entrar
i = rectangle($gborder,61+ix,225+iy,75+ix,242+iy) com o seguinte cdigo:
!"$gborder" significa desenhar s o contorno.

i = setcolor(0) !cor dos pneus use dialogm

i = ellipse($gfillinterior,25+ix,243+iy,31+ix,249+iy)
!pneu traseiro logo depois do Use MSFLIB. Imediatamente depois do

i = ellipse($gfillinterior,64+ix,243+iy,70+ix,249+iy)
!pneu dianteiro implicit none

call sleepqq(80)
!mostra a imagem desenhada por 80 ms. voc deve escrever ainda:

i = setcolor(15) !apaga a imagem desenhada


type (dialog) dlg
i = rectangle($gfillinterior,20+ix,215+iy,60+ix,242+iy)
include 'resource.fd'
i = rectangle($gfillinterior,61+ix,225+iy,75+ix,242+iy)
logical pushed_state1, pushed_state2, pushed_state3, pushed_state4
i = ellipse($gfillinterior,25+ix,243+iy,31+ix,249+iy)
logical retlog
i = ellipse($gfillinterior,64+ix,243+iy,70+ix,249+iy)
integer iret, message
end do

return Conforme pode ser visto na caixa, as duas check box so s para
exemplificar sua utilizao. O boto Finalizar o idcancel e o V
end subroutine para... o idok. O primeiro radio button, chamado de idc_radio1, deve
desviar o programa para o incio da animao (imediatamente antes da
primeira chamada call movimento(iy)), onde voc deve dar o comando

8 - Caixa de Dilogos: Check Box e Radio Button 10 continue

Para compreender o uso de Check Box e Radio Button, construa a caixa de O segundo radio button, chamado de idc_radio2, deve desviar o programa
dilogo idd_dialog1 neste projeto, com os elementos mostrados: para a segunda parte da animao, que comea com a abertura da Nova Janela
. Assim, deve-se dar o comando

20 continue

antes da abertura dessa Nova Janela, que voc j deve ter implementado.

Repare que o terceiro radio button, idc_radio3, no tem funo


especfica e foi colocado na caixa somente para exemplificar a sua forma
de desabilitao. Cada um dos dois Radio Button e das duas Check Box
necessitam de uma varivel lgica de comunicao e, por isso, foram
definidas as variveis pushed_state1, pushed_state2, pushed_state3,
pushed_state4. Para evocar a caixa e interpretar as aes do usurio,
antes do

STOP

deve-se entrar com o seguinte cdigo:

...
...
Na caixa temos: idc_check1, idc_check2, idok (cujo texto apresentado V retlog = dlginit(idd_dialog1, dlg) !inicia o dilogo
para...), idcancel (cujo texto definido em Caption Finalizar) e, na
!desabilita radio3 Retlog = dlginit(idd_dialog1,dlg)
retlog = dlgset(dlg, idc_radio3, .false., dlg_enable)
Retlog = dlgset(dlg, idok, "&Contagem")
!check box1 inicia com falso Retlog = dlgset(dlg, idc_check1, .false.)
retlog = dlgset(dlg, idc_check1, .false.) Retlog = DlgSetSub(dlg, idok, Icallback)

!check box inicia com verdadeiro Iret = dlgmodal(dlg)


retlog = dlgset(dlg, idc_check2, .true.)
Call dlguninit(dlg)
iret = dlgmodal(dlg) !estabelece o dilogo

if(iret == 2) then !o boto Finalizar foi clicado Nesse exemplo, temos algo j visto sobre o estabelecimento da forma de
call dlguninit(dlg) apario de um dilogo em uma caixa que, no caso, uma check box:
stop
end if Retlog = dlgset(dlg, idc_check1, .false.)

!obtm o valor falso ou verdadeiro para idc_check1 Este comando estabelece que a check box idc_check1 vai ser apresentada na
retlog = dlgget(dlg,idc_check1,pushed_state3) caixa de dilogo, inicialmente com o estado igual a .false.. Temos,
if(pushed_state3) then tambm nesse exemplo, algo de novo, como a forma de se modificar, via
message = MESSAGEBOXQQ('A Check Box1 retornou ".True."! 'C,& cdigo, o texto que aparecer no boto idok:
'Sobre a Check Box'C, MB$ICONEXCLAMATION .or.MB$OK)
else Retlog = dlgset(dlg, idok, "&Contagem")
message = MESSAGEBOXQQ('A Check Box1 retornou ".False."! 'C,&
'Sobre a Check Box'C, MB$ICONEXCLAMATION .or.MB$OK) Com esse comando, o boto idok passar a exibir o texto Contagem. H que
end if se relembrar que a forma inicial de se fazer esta mudana seria atravs da
caixa de propriedades do boto idok, mudando-se o texto em Caption.
!obtm o valor falso ou verdadeiro para idc_check2
retlog = dlgget(dlg,idc_check2,pushed_state4)
if(pushed_state4) then
message = MESSAGEBOXQQ('A Check Box2 retornou ".True."! 'C,& DlgSetSub
'Sobre a Check Box'C, MB$ICONEXCLAMATION .or.MB$OK)
else Uma novidade muito maior, em relao aos recursos de programao que j
message = MESSAGEBOXQQ('A Check Box2 retornou ".False."! 'C,& estudamos, o terceiro comando entre dlginit e dlgmodal:
'Sobre a Check Box'C, MB$ICONEXCLAMATION .or.MB$OK)
end if Retlog = DlgSetSub(dlg, idok, Icallback)

!obtm o valor falso ou verdadeiro para idc_radio1 Em geral, ao clicar num boto, a funo dlgmodal retorna um valor (atravs
retlog = dlgget(dlg,idc_radio1,pushed_state1) de Iret) indicando qual foi o boto clicado. Alguns valores so lidos, se
if(pushed_state1) then !se idc_radio1 for T, v para o incio for o caso, e o dilogo sempre encerrado. Entretanto, com o uso de
goto 10 DlgSetSub as coisas funcionam de maneira diferente. O comando anterior,
end if por exemplo, estabelece que se o boto idok for clicado, a funo
dlgmodal no ser evocada, e sim uma subrotina callback chamada Icallback
!obtm o valor falso ou verdadeiro para idc_radio2 , sendo que a caixa de dilogo continua ativa. Essa subrotina callback,
retlog = dlgget(dlg,idc_radio2,pushed_state2) criada pelo usurio, pode modificar alguns dos elementos de dilogo, ou
if(pushed_state2) then !se idc_radio2 for T, v para o meio mesmo inicializar outra caixa de dilogo. Para exemplificar isso,
goto 20 apresentaremos o cdigo a seguir, que pode ser compilado, ligado e
end if executado em um projeto criado especificamente para esse fim. Com a
execuo, voc perceber que tal projeto auto-explicativo. Alm do
call dlguninit(dlg) cdigo, voc deve criar duas caixas (idd_dialog1 e idd_dialog2) que
... devero ter as seguintes aparncias:
...

9 DLGSETSUB: Evocao de uma Callback que Modifica uma


Caixa de Dilogo
Os dilogos de uma caixa podem evocar uma callback especial que capaz de
modificar parmetros da caixa, sem que a mesma seja encerrada e
reiniciada. Para compreender a forma de se fazer isso, devemos recordar
que tudo que formos estabelecer na caixa deve estar entre os comandos que i
nicia o dilogo e o que estabelece o dilogo. Veja o exemplo:
idd_dialog1 idd_dialog2 !escolhida, sem que dlgmodal seja evocado.
retlog = dlgsetsub(dlg, idc_radio3, updateradio)

Em idd_dialog1 a primeira static text mostrada idc_static2 enquanto !clicando em idc_button1 a callback resultados
que a de baixo, utilizada em Contagem, idc_static1. Os trs radio !chamada e uma nova caixa de dilogo evocada.
buttons so, pela ordem, idc_radio1, idc_radio2 e idc_radio3, enquanto que retlog = dlgsetsub(dlg, idc_button1, resultados)
button1 tem a ID IDC_BUTTON1. Em idd_dialog2 o boto OK , na verdade,
iret = dlgmodal(dlg) !o nico boto que evoca dlgmodal
idcancel, o que possibilita manter o X do canto superior direito e
! Finalizar (idcancel) que no
button1 idc_button1. Para a caixa Resultados (idd_dialog2), veja a caixa !est associado a nenhuma dlgsetsub.
Dialog Properties:
!obtm o ltimo texto (valor) escrito em idc_static1
retlog = dlgget(dlg,idc_static1,text)
read(text,*,iostat = ierr) i
if(ierr /= 0) text = '0'
!escreve o ltimo valor contado em updatestatictext na tela
write(*,"(' O boto Contagem foi clicado ',(a),' vezes.')") &
trim(text)

call dlguninit(dlg)

end program dodialog

!A cada clique no boto "contagem" (idok) a callback


!updatestatictext chamada.Essa callback adiciona 1
Para obter o efeito Dj Vu desejado, para demonstrar a recursividade de !unidade em um contador e o novo valor mostrado
uma callback, a posio x e y da caixa Resultados deve ser igual a 10, ! na caixa de dilogo, em uma static text.
conforme mostrado anteriormente. Passemos ao cdigo fonte: subroutine updatestatictext(dlg,id,icallback)
use msflib
use dialogm
program dodialog include 'resource.fd'
use msflib type (dialog) dlg
use dialogm character (len=256) text
include 'resource.fd' logical retlog
type (dialog) dlg
character (len=256) text !para evitar advertncia:
logical retlog icallback1 = icallback
external UpdateStaticText, UpdateRadio, Resultados id1 = id !id identifica o dilogo clicado

retlog = dlginit(idd_dialog1,dlg) !modificao do que aparece em idc_static1,


!na caixa de dilogo, quando o boto Contagem
!comandos que modificam os textos dos botes !(idok) clicado
retlog = dlgset(dlg,idok,"&Contagem") i = i + 1
retlog = dlgset(dlg,idcancel,"&Finalizar") write(text,*)i
retolog = dlgset(dlg,idc_button1,"&Resultados") retlog = dlgset(dlg,idc_static1,trim(adjustl(text)))

!desabilita idc_radio1 return


retlog = dlgset(dlg,idc_radio1,.false.,dlg_enable) end subroutine

!Chamando a subrotina updatestatictext, ao clicar


!OK,que foi modificado para Contagem, uma soma !Quando um radiobutton selecionado, informado
!(incrementando 1) feita a partir de zero e o !em idc_static2 qual foi esse radiobutton.
!resultado colocado em idc_static1, sem que subroutine updateradio(dlg,id,icallback)
!dlgmodal seja evocado. use msflib
retlog = dlgsetsub(dlg, idok, updatestatictext) use dialogm
include 'resource.fd'
!clicando em idc_radio2 a callback updateradio type (dialog) dlg
!chamada e informa, na caixa de dilogo, a opo character (len=256) text
!escolhida, sem que dlgmodal seja evocado. logical retlog
retlog = dlgsetsub(dlg, idc_radio2, updateradio)
!para evitar advertncia:
!clicando em idc_radio3 a callback updateradio icallback1 = icallback
!chamada e informa, na caixa de dilogo, a opo
!modificao do que aparece na caixa de dilogo parser (evaluator) e em Fortran existem pouqussimos destes mdulos
if(id == idc_radio2) then desenvolvidos. Muito embora o grupo de pesquisa dos autores deste tutorial
write(text,*)"1" j tenha desenvolvido um evaluator de excelente desempenho, ele s ser
retlog = dlgset(dlg,idc_static2,trim(adjustl(text))) disponibilizado em lies futuras. Assim, passemos ao cdigo de um
end if programa grfico elementar. Para observar as suas potencialidades, basta
selecionar o cdigo, copiar e colar em um arquivo, digamos,
if(id == idc_radio3) then intro_Graf_2D.f90, dentro de um workspace criado com essa finalidade.
write(text,*)"2"
retlog = dlgset(dlg,idc_static2,trim(adjustl(text))) program intro_graf_2D
end if use msflib
implicit none
return integer nsegmentos,i,icor_linha,iavx,iavy
end subroutine real x(501),y(501),deltax,f
character (30) xux,yuy
character (50) tit
recursive subroutine resultados(dlg,id,icallback) logical retlog
use msflib type (qwinfo) winfo
use dialogm
include 'resource.fd' !estabelecimentos
type (dialog) dlg, dlg1, dlg2 !preparao do menu grfico: descarte de menus defaults indesejveis
logical retlog retlog = DELETEMENUQQ (6, 0) !help
retlog = DELETEMENUQQ (5, 0) !window
!para evitar advertncia: retlog = DELETEMENUQQ (3, 0) !view
icallback1 = icallback retlog = DELETEMENUQQ (2, 1) !select text
id1 = id i = setbkcolorrgb(#f5f5f5) !cor do fundo de tela: "cinza claro"
dlg2 = dlg !(para distinguir a linha de contorno
!de seleo do grfico, que branca)
retlog = dlginit(idd_dialog2,dlg1) call clearscreen($gclearscreen)
winfo.TYPE = QWIN$MAX
!modifica o nome button1 i = SETWSIZEQQ(QWIN$FRAMEWINDOW, winfo) !maximiza a frame window
retlog = dlgset(dlg1, idc_button1, '&Dj Vu') i = clickmenuqq(qwin$tile) !estilo tile

!evoca a si mesmo: recursividade. Para apresentar !grfico da funo definida em "function f(x)": inicializao.
!resultados, acabe com a evocao a si mesmo, isto nsegmentos = 499 !nmero de segmentos (mximo igual a 500, mnimo = 2)
!, acabe com a recursividade. x(1) = -25.0 !valor inicial de x, poderia ser lido
retlog = dlgsetsub(dlg1, idc_button1, resultados) x(nsegmentos+1) = 25.0 !valor final de x, poderia ser lido
deltax = (x(nsegmentos+1)-x(1))/float(nsegmentos)
iret = dlgmodal(dlg1)
!valores de y: funo definida em "function f(x)" <<<<==== FUNO
call dlgexit(dlg1) !ateno: os pontos a serem ligados sero gerados a partir da funo
!"f(x)" definida em "funtion f(x)" mas os pontos poderiam ser lidos
return !em um arquivo de dados.
end subroutine y(1) = f(x(1))
do i = 2,nsegmentos + 1
if(i /= nsegmentos + 1) x(i) = x(i-1) + deltax
10 Grfico 2D: Noes bsicas y(i) = f(x(i))
end do
No atual estgio de nosso estudo, j devemos ter condies de icor_linha = 12 !cor da linha do grfico
desenvolver programas para traar grficos 2D e 3D, j que os comandos iavx = 80 ! avano nas coordenadas x (deslocamento de todo o desenho)
bsicos envolvem apenas a subrotina moveto e a funo lineto, ambas iavy = 50 ! avano nas coordenadas y (deslocamento de todo o desenho)
grficas. S que, s vezes, no percebemos isso. Portanto, vamos !origem do sistema de eixos: (100+iavx,280+iavy) <= posio em pixels
apresentar um esboo que d noes para que um programa criterioso possa xux = 'X(Ux)' !grandeza "X" e sua unidade
ser elaborado posteriormente. Aqui, no nos preocupamos com aspectos yuy = 'Y(Uy)' !grandeza "Y" e sua unidade
importantes como a incluso ou descarte da origem do sistema de eixos, tit = ' Noes Sobre Grficos' !ttulo do grfico
quais os quadrantes a serem ocupados pelo grfico e os degraus apropriados
para a construo de escalas. call graf_2D(nsegmentos,x,y,icor_linha,iavx,iavy,xux,yuy,tit)
Um outro aspecto que no consideraremos refere-se forma de do while (.true.)
informao da funo cujo grfico iremos traar. No exemplo a seguir, a end do
informao ser feita no programa fonte, em function f(x). Entretanto, o end program
mais adequado captar um string com a informao da funo, e transformar
tal string numa expresso aritmtica, posteriormente calculada. Em geral
esta operao feita por mdulos especficos para este fim, chamados de subroutine graf_2D(nsegmentos,x,y,icor_linha,iavx,iavy,xux,yuy,tit)
!nsegmentos: nmero de segmentos (de 2 a 500) a serem ligados !y
!x: valores da varivel independente (de 3 a 501) call moveto(99+iavx,280+iavy,pos)
!y: valores da varivel dependente (de 3 a 501) i = lineto(95+iavx,280+iavy)
!icor_linha: cor da linha do grfico write(text,'(e10.4)')ymin !escreve o valor de ymin no caractere text
!iavx: avano de todo o grafico em x (em pixels) call moveto(17+iavx,272+iavy,pos)
!iavy: avano de todo o grfico em y (em pixels) call outgtext(trim(text))
!xux: string com informaes sobre a grandeza marcada em x => X(Ux) call moveto(99+iavx,80+iavy,pos)
!yuy: string com informaes sobre a grandeza marcada em y => Y(Uy) i = lineto(95+iavx,80+iavy)
!tit: string com o ttulo do grfico write(text,'(e10.4)')ymax !escreve o valor de ymax no caractere text
use msflib call moveto(17+iavx,72+iavy,pos)
implicit none call outgtext(trim(text))
type (xycoord) pos call moveto(99+iavx,180+iavy,pos) !define o meio do comprimento til
integer nsegmentos,i,icor_linha,i2 i = lineto(95+iavx,180+iavy)
integer ixcoord(nsegmentos+1),iycoord(nsegmentos+1),iavx,iavy
real x(nsegmentos+1),y(nsegmentos+1),ymin,ymax !nomes dos eixos
character (30) xux,yuy,text call moveto(180+iavx,315+iavy,pos) !posiciona para escrever um nome
character (50) tit call outgtext(trim(xux)) !nome e unidade da grandeza no eixo x
CALL SETGTEXTROTATION (900) !giro de 90 no texto a ser escrito em y
!fontes call moveto(60+iavx,220+iavy,pos) !posiciona para escrever um nome
i = initializefonts() call outgtext(trim(yuy)) !nome e unidade da grandeza no eixo y
i = SETFONT ('t''Arial''h16e') CALL SETGTEXTROTATION (0) !retorna para o ngulo zero normal
if(i.eq.-1) i = SETFONT ('t''times new roman''h17e') call moveto(110+iavx,30+iavy,pos) !posiciona para escrever um nome
if(i.eq.-1) i = setfont ('t''courier new''h16e') call outgtext(tit) !ttulo do grfico
if(i.eq.-1) i = SETFONT ('t''Tahoma''h16e')
if(i.eq.-1) i = SETFONT ('t''CAC FUTURA CASUAL''h16e') !linha do grfico <<== GRFICO PROPRIAMENTE DITO
!***********************************************************************
!valores mximo e mnimo de y i = setcolor(icor_linha) !cor da linha do grfico
ymin = y(1)
ymax = y(1) !equao da escala x
do i = 1,nsegmentos+1 ixcoord(1) = 100 + ifix(200*(x(1)-x(1))/(x(nsegmentos+1)-x(1))) + iavx
if(y(i) < ymin) ymin = y(i) !equao da escala y
if(y(i) > ymax) ymax = y(i) iycoord(1) = 280 - ifix(200*(y(1)-ymin)/(ymax-ymin)) +iavy
end do !PS: lembre-se que o "y = 0" para a tela em cima. Por isso,
!testa se a funo constante ! a equao da escala y tem o "280 -".
if( ymax <= ymin) then
ymin = ymax - 1.0 !isso apenas para desenhar um mximo e um call moveto(ixcoord(1),iycoord(1),pos) !posiciona o cursor
!um mnimo. O valor do mnimo no relevante.
end if do i = 1,nsegmentos + 1 !loop para traar a linha
!equao da escala x
!comprimento de cada eixo: 260 (y) e 280 (x) pixels. til 200 pixels. ixcoord(i) = 100 + ifix(200*(x(i)-x(1))/(x(nsegmentos+1)-x(1))) + iavx
!origem do sistema de eixos: (100+iavx,280+iavy) <= posio em pixels !equao da escala y
!desenho dos eixos. iycoord(i) = 280 - ifix(200*(y(i)-ymin)/(ymax-ymin)) + iavy
i = setcolor(0) !eixos de cor preta i2 = lineto(ixcoord(i),iycoord(i))
call moveto(100+iavx,20+iavy,pos) call sleepqq(20) !d a sensao de "animao". Se no quiser, tire!
i = lineto(100+iavx,280+iavy) !linha vertical end do
i = lineto(380+iavx,280+iavy) !linha horizontal !***********************************************************************
call moveto(99+iavx,20+iavy,pos)
i = lineto(99+iavx,281+iavy) !reforo na linha vertical (trao duplo) return
i = lineto(380+iavx,281+iavy) !reforo na linha horizontal (trao duplo) end subroutine

!pequenos traos representando mximos e mnimos e os seus valores


!x function f(x)
call moveto(100+iavx,281+iavy,pos) real x !aqui x no um vetor
i = lineto(100+iavx,285+iavy) f = sin(x)/x !definio da funo (cuidado na definio do nmero
write(text,'(e10.4)')x(1) !escreve o valor de x(1) no caractere text !de pontos para no gerar uma operao ilegal)
call moveto(65+iavx,292+iavy,pos) return
call outgtext(trim(text)) end function
call moveto(300+iavx,281+iavy,pos)
i = lineto(300+iavx,285+iavy)
write(text,'(e10.4)')x(nsegmentos+1) !escreve o valor de x(nsegmentos+1)
call moveto(265+iavx,292+iavy,pos) 11 Grfico 3D: Noes bsicas
call outgtext(trim(text))
call moveto(200+iavx,281+iavy,pos) !define o meio do comprimento til
i = lineto(200+iavx,285+iavy) Da mesma forma que apresentamos as noes bsicas para grficos 2D,
apresentaremos para o caso 3D. Na verdade, um grfico 3D um conjunto de
grficos 2D formando uma malha, que d a idia de uma superfcie. Como j i = clickmenuqq(qwin$tile) !estilo tile
vimos os passos iniciais para traar grfico 2D, vamos reutiliz-los para
traar uma superfcie. Apresentaremos um programa fonte que esboa a !grfico da funo definida em "function f(x1,x2)": inicializao.
superfcie de uma funo de duas variveis independentes, f(x1,x2), nsegmentos = 200 !nmero de segmentos em cada linha
traando linhas transversais para alguns valores fixados para x2. A !da malha (pode ser 50, 100, 150, ... 500)
complementao da malha feita fixando-se, tambm, alguns valores de x1,
e traando-se linhas longitudinais, perpendiculares quelas que foram x1(1) = -3.0 !valor inicial de x1, poderia ser lido
traadas.
x1(nsegmentos+1) = 3.0 !valor final de x1, poderia ser lido
Ateno: No programa que apresentaremos, algumas linhas de comando so
muito extensas e, ao serem copiadas aqui e coladas no arquivo do projeto, x2(1) = -3.0
podem ser quebradas. Se isso acontecer e houver erro de compilao, s
emendar essas linhas quebradas numa nica linha. Passemos ao programa x2(nsegmentos+1) = 3.0
fonte.
deltax1 = (x1(nsegmentos+1)-x1(1))/float(nsegmentos)
program intro_graf_3D
deltax2 = (x2(nsegmentos+1)-x2(1))/float(nsegmentos)
use msflib
!valores de y: funo definida em "function f(x1,x2)" <<<<==== FUNO
implicit none !ateno: os pontos a serem ligados sero gerados a partir da funo
!"f(x1,x2)" definida em "funtion f(x1,x2)" mas os pontos poderiam ser
integer nsegmentos,i,j,icor_linha,iavx,iavy !lidos em um arquivo de dados.
do i = 1,nsegmentos+1
real x1(501),x2(501),y(501,501),deltax1,deltax2,f
do j = 1,nsegmentos+1
character (30) x1ux1,x2ux2,yuy
y(i,j) = f(x1(i),x2(j))
character (50) tit
if(j /= nsegmentos+1) x2(j+1) = x2(j) + deltax2
logical retlog
end do
type (qwinfo) winfo
if(i /= nsegmentos+1) x1(i+1) = x1(i) + deltax1
type(windowconfig) wc
end do
!estabelecimentos
!preparao do menu grfico: descarte de menus defaults indesejveis icor_linha = -1 !cor da linha da malha: 0 preto, -1 colorido
retlog = DELETEMENUQQ (6, 0) !help
iavx = 250 !avano nas coordenadas x1 (deslocamento de todo o desenho)
retlog = DELETEMENUQQ (5, 0) !window
iavy = 30 !avano nas coordenadas y (deslocamento de todo o desenho)
retlog = DELETEMENUQQ (3, 0) !view
!origem do sistema de eixos: (100+iavx,280+iavy) <= posio em pixels
retlog = DELETEMENUQQ (2, 1) !select text
x1ux1 = 'X1(Ux1)' !grandeza "X1" e sua unidade
i = setbkcolorrgb(#f5f5f5) !cor do fundo de tela: "cinza claro"
!(para distinguir a linha de contorno x2ux2 = 'X2(Ux2)' !grandeza "X2" e sua unidade
!de seleo do grfico, que branca)
call clearscreen($gclearscreen) yuy = 'Y(Uy)' !grandeza "Y" e sua unidade

retlog = GETWINDOWCONFIG (wc) tit = ' Noes Sobre Grficos 3D' !ttulo do grfico

if(wc.numxpixels < 800) THEN call graf_3D(nsegmentos,x1,y,icor_linha,iavx,iavy,x1ux1,x2ux2,yuy,tit)

i = MESSAGEBOXQQ('A resoluo do monitor deve ser 800x600 & do while (.true.)


ou mais!'C,'RESOLUO'C,MB$ICONQUESTION.OR.MB$DEFBUTTON1)
end do
call exit
end program
end if

winfo.TYPE = QWIN$MAX subroutine graf_3D(nsegmentos,x1,y,icor_linha,iavx,iavy, &


i = SETWSIZEQQ(QWIN$FRAMEWINDOW, winfo) !maximiza a frame window x1ux1,x2ux2,yuy,tit)
!nsegmentos: nmero de segmentos (igual a 500) end if
!x1: valores da varivel independente x1 (501 valores)
!y: valores da varivel dependente x2 (501 valores) !comprimento de cada eixo: 260 (y) e 280 (x) pixels. til 200 pixels.
!icor_linha: cor da linha do grfico !origem do sistema de eixos: (100+iavx,280+iavy) <= posio em pixels
!iavx: avano de todo o grafico em x (em pixels) !desenho dos eixos.
!iavy: avano de todo o grfico em y (em pixels)
!x1ux1: string com informaes sobre a grandeza i = setcolor(0) !eixos de cor preta
!marcada em x1 => X1(Ux1)
!x2ux2: string com informaes sobre a grandeza call moveto(100+iavx,40+iavy,pos)
!marcada em x2 => X2(Ux2)
!yuy: string com informaes sobre a grandeza marcada em y => Y(Uy) i = lineto(100+iavx,280+iavy) !eixo vertical
!tit: string com o ttulo do grfico
i = lineto(380+iavx,280+iavy) !eixo de x1
use msflib
call moveto(100+iavx,280+iavy,pos) !eixo x2
implicit none
i = lineto(100-ifix(160.*cos(45./180.))+iavx,280+ &
type (xycoord) pos
ifix(160.*cos(45./180.))+iavy) !eixo de x2
integer nsegmentos,i,j,icor_linha,i2,i_cor
call moveto(99+iavx,40+iavy,pos)
integer ixcoord(501,501),iycoord(501,501),iavx,iavy,passo
i = lineto(99+iavx,281+iavy) !reforo do eixo vertical (trao duplo)
real x1(501),y(501,501),ymin,ymax
i = lineto(380+iavx,281+iavy) !reforo de x1 (trao duplo)
character (30) x1ux1,x2ux2,yuy
call moveto(101+iavx,280+iavy,pos) !reforo de x2 (trao duplo)
character (50) tit
i = lineto(101-ifix(160.*cos(45./180.))+iavx,280+ &
!fontes
i = initializefonts() ifix(160.*cos(45./180.))+iavy) !eixo de x2

i = SETFONT ('t''Arial''h16e') !nomes dos eixos


call moveto(360+iavx,285+iavy,pos) !posio do nome do eixo x1
if(i.eq.-1) i = SETFONT ('t''times new roman''h17e')
call outgtext(trim(x1ux1)) !nome do eixo x1
if(i.eq.-1) i = setfont ('t''courier new''h16e')
call moveto(75-ifix(160.*cos(45./180.))+iavx,285+ &
if(i.eq.-1) i = SETFONT ('t''Tahoma''h16e')
ifix(160.*cos(45./180.))+iavy,pos)
if(i.eq.-1) i = SETFONT ('t''CAC FUTURA CASUAL''h16e')
call outgtext(trim(x2ux2)) !nome do eixo x2
!valores mximo e mnimo de y
ymin = y(1,1) call moveto(60+iavx,10+iavy,pos)

ymax = y(1,1) call outgtext(trim(yuy))

do i = 1,nsegmentos+1 call moveto(110+iavx,45+iavy,pos)

do j = 1,nsegmentos+1 call outgtext(tit) !ttulo do grfico

if(y(i,j) < ymin) ymin = y(i,j) i = setcolor(icor_linha) !cor da malha do grfico

if(y(i,j) > ymax) ymax = y(i,j)


!Ateno o que vamos fazer agora traar o grfico 2D para
end do
!y = f(x1,x2) com x2 constante: x2(1). Depois, faremos o mesmo
end do
!para outros x2 fixos, at x2(501). A complementao a malha
!testa se a funo constante
if( ymax <= ymin) then !feita fixando x1 e traando f(x1,x2). Veja que, a rigor, faremos

ymin = ymax - 1.0 !isso apenas para desenhar um mximo e um !clculos que possibilitam traar uma malha com at 501 x 501 linhas:
!um mnimo. O valor do mnimo no relevante.
!*********************************************************************** i2 = lineto(ixcoord(i,j),iycoord(i,j))
do j = 1,nsegmentos+1
end do
do i = 1,nsegmentos + 1
end do
!equao da escala x !***********************************************************************
ixcoord(i,j) = 100 - ifix(120.*cos(45./180.)*(j-1)/(nsegmentos &

)) + ifix(200*(x1(i)-x1(1))/(x1(nsegmentos+1)-x1(1))) + iavx !***********************************************************************


do j = 1,nsegmentos+1,passo !trao das linhas longitudinais
!equao da escala y
iycoord(i,j) = 280 + ifix(120.*cos(45./180.)*(j-1)/(nsegmentos & call moveto(ixcoord(j,1),iycoord(j,1),pos) !posiciona o cursor

)) - ifix(200*(y(i,j)-ymin)/(ymax-ymin)) + iavy do i = 1,nsegmentos + 1 !loop para traar a linha

end do if(icor_linha /= 0) then !cores por cota (4 cotas. Mude, se quiser)

end do if(y(j,i) <= (ymax-ymin)/4+ymin) then


!***********************************************************************
i_cor = setcolor(4)

passo = nsegmentos/50 !define o avano de cada linha no eixo. else

if(y(j,i) > (ymax-ymin)/4+ymin .and. y(j,i) <= 2*(ymax&


!***********************************************************************
do j = 1,nsegmentos+1,passo !trao das linhas transversais -ymin)/4+ymin) then

call moveto(ixcoord(1,j),iycoord(1,j),pos) !posiciona o cursor i_cor = setcolor(9)

do i = 1,nsegmentos + 1 !loop para traar a linha else

if(icor_linha /= 0) then !cores por cota (4 cotas. Mude, se quiser) if(y(j,i) > 2*(ymax-ymin)/4+ymin .and. y(j,i) <= 3*(ymax&

if(y(i,j) <= (ymax-ymin)/4+ymin) then -ymin)/4+ymin) then

i_cor = setcolor(4) i_cor = setcolor(12)

else else

if(y(i,j) > (ymax-ymin)/4+ymin .and. y(i,j) <= 2*(ymax& i_cor = setcolor(13)

-ymin)/4+ymin) then end if

i_cor = setcolor(9) end if

else end if

if(y(i,j) > 2*(ymax-ymin)/4+ymin .and. y(i,j) <= 3*(ymax& end if

-ymin)/4+ymin) then i2 = lineto(ixcoord(j,i),iycoord(j,i))

i_cor = setcolor(12) end do

else end do
!***********************************************************************
i_cor = setcolor(13)
return
end if
end subroutine
end if

end if function f(x1,x2)

end if real x1,x2 !aqui x1 e x2 no so vetores


f = -exp(-x1**2-x2**2) real x1(501),y(501,501),ymin,ymax

return character (30) x1ux1,x2ux2,yuy

end function character (50) tit

!fontes

i = initializefonts()
12 Avance um pouco mais - Grfico 3D: MALHA SLIDA
i = SETFONT ('t''Arial''h16e')
Ao invs de traar uma superfcie com malha vazada (todas a linhas
transversais e depois todas as longitudinais), voc pode traar uma if(i.eq.-1) i = SETFONT ('t''times new roman''h17e')
superfcie de malha slida, intercalando trechos de linhas transversais
com trechos de linhas longitudinais. Para isso estude, no help do estdio, if(i.eq.-1) i = setfont ('t''courier new''h16e')
detalhes sobre a varivel de tipo derivado denominada poly. Depois, estude
o cdigo fonte da nova subrotina graf_3D dada a seguir. Finalmente, if(i.eq.-1) i = SETFONT ('t''Tahoma''h16e')
substitua a subrotina de mesmo nome dada anteriormente, pela apresentada
aqui, compile e execute o novo programa. O resultado para a superfcie if(i.eq.-1) i = SETFONT ('t''CAC FUTURA CASUAL''h16e')
uma figura bem mais ntida que a anterior. Voc pode, tambm, deixar as
duas opes (malha vazada e slida) para a escolha do usurio de seu !valores mximo e mnimo de y
software.
ymin = y(1,1)

subroutine graf_3D(nsegmentos,x1,y,icor_linha,iavx,iavy, & ymax = y(1,1)

x1ux1,x2ux2,yuy,tit) do i = 1,nsegmentos+1

!nsegmentos: nmero de segmentos (igual a 500) do j = 1,nsegmentos+1

!x1: valores da varivel independente x1 (501 valores) if(y(i,j) < ymin) ymin = y(i,j)

!y: valores da varivel dependente x2 (501 valores) if(y(i,j) > ymax) ymax = y(i,j)

!icor_linha: cor da linha do grfico end do

!iavx: avano de todo o grafico em x (em pixels) end do

!iavy: avano de todo o grfico em y (em pixels) !testa se a funo constante

!x1ux1: string com informaes sobre a grandeza if( ymax <= ymin) then

!marcada em x1 => X1(Ux1) ymin = ymax - 1.0 !isso apenas para desenhar um mximo e um
!um mnimo. O valor do mnimo no relevante.
!x2ux2: string com informaes sobre a grandeza
end if
!marcada em x2 => X2(Ux2)
!comprimento de cada eixo: 260 (y) e 280 (x) pixels. til 200 pixels.
!yuy: string com informaes sobre a grandeza marcada em y => Y(Uy)
!origem do sistema de eixos: (100+iavx,280+iavy) <= posio em pixels
!tit: string com o ttulo do grfico
!desenho dos eixos.
use msflib
i = setcolor(0) !eixos de cor preta
implicit none
call moveto(100+iavx,40+iavy,pos)
type (xycoord) pos
i = lineto(100+iavx,280+iavy) !eixo vertical
type (xycoord) poly(4)
i = lineto(380+iavx,280+iavy) !eixo de x1
integer nsegmentos,i,j,icor_linha,i2,i_cor
call moveto(100+iavx,280+iavy,pos) !eixo x2
integer ixcoord(501,501),iycoord(501,501),iavx,iavy,passo
i = lineto(100-ifix(160.*cos(45./180.))+iavx,280+ &
ifix(160.*cos(45./180.))+iavy) !eixo de x2 end do

call moveto(99+iavx,40+iavy,pos) end do

i = lineto(99+iavx,281+iavy) !reforo do eixo vertical (trao duplo) !***********************************************************************

i = lineto(380+iavx,281+iavy) !reforo de x1 (trao duplo) passo = nsegmentos/50 !define o avano de cada linha no eixo.

call moveto(101+iavx,280+iavy,pos) !reforo de x2 (trao duplo) !***********************************************************************

i = lineto(101-ifix(160.*cos(45./180.))+iavx,280+ & do j = 1,nsegmentos+1,passo !trao das linhas transversais

ifix(160.*cos(45./180.))+iavy) !eixo de x2 do i = 1,nsegmentos + 1,passo !loop para traar a linha

!nomes dos eixos if(icor_linha /= 0) then !cores por cota (4 cotas. Mude, se quiser)

call moveto(360+iavx,285+iavy,pos) !posio do nome do eixo x1 if(y(i,j) <= (ymax-ymin)/4+ymin) then

call outgtext(trim(x1ux1)) !nome do eixo x1 i_cor = setcolor(2)

call moveto(75-ifix(160.*cos(45./180.))+iavx,285+ & else

ifix(160.*cos(45./180.))+iavy,pos) if(y(i,j) > (ymax-ymin)/4+ymin .and. y(i,j) <= 2*(ymax&

call outgtext(trim(x2ux2)) !nome do eixo x2 -ymin)/4+ymin) then

call moveto(60+iavx,10+iavy,pos) i_cor = setcolor(9)

call outgtext(trim(yuy)) else

call moveto(110+iavx,45+iavy,pos) if(y(i,j) > 2*(ymax-ymin)/4+ymin .and. y(i,j) <= 3*(ymax&

call outgtext(tit) !ttulo do grfico -ymin)/4+ymin) then

i = setcolor(icor_linha) !cor da malha do grfico i_cor = setcolor(12)

!Ateno o que vamos fazer agora traar o grfico 2D para else

!y = f(x1,x2) com x2 constante: x2(1). Depois, faremos o mesmo i_cor = setcolor(13)

!para outros x2 fixos, at x2(501). A complementao a malha end if

!feita fixando x1 e traando f(x1,x2). Veja que, a rigor, faremos end if

!clculos que possibilitam traar uma malha com at 501 x 501 linhas: end if

!*********************************************************************** else

do j = 1,nsegmentos+1 i_cor = setcolor(7)

do i = 1,nsegmentos + 1 end if

!equao da escala x
if( j <= nsegmentos .and. i <= nsegmentos) then
ixcoord(i,j) = 100 - ifix(120.*cos(45./180.)*(j-1)/(nsegmentos & poly(1)%xcoord = ixcoord(i,j+passo)
poly(1)%ycoord = iycoord(i,j+passo)
)) + ifix(200*(x1(i)-x1(1))/(x1(nsegmentos+1)-x1(1))) + iavx poly(2)%xcoord = ixcoord(i,j)
poly(2)%ycoord = iycoord(i,j)
!equao da escala y poly(3)%xcoord = ixcoord(i+passo,j)
poly(3)%ycoord = iycoord(i+passo,j)
iycoord(i,j) = 280 + ifix(120.*cos(45./180.)*(j-1)/(nsegmentos & poly(4)%xcoord = ixcoord(i+passo,j+passo)
poly(4)%ycoord = iycoord(i+passo,j+passo)
)) - ifix(200*(y(i,j)-ymin)/(ymax-ymin)) + iavy i2 = POLYGON($GFILLINTERIOR, poly, INT2(4))
end if
i2 = setcolor(0)
if(j <= nsegmentos) then
call moveto(ixcoord(i,j),iycoord(i,j), pos)
i2 = lineto(ixcoord(i,j+passo),iycoord(i,j+passo))
end if
if(i <= nsegmentos) then
call moveto(ixcoord(i,j),iycoord(i,j), pos) INTRODUO AO VISUAL FORTRAN CVF
i2 = lineto(ixcoord(i+passo,j),iycoord(i+passo,j))
end if
Wilton, Cleide e Cleiton Diniz P. S. e Silva
end do

end do
!*********************************************************************** Programador:

return

end subroutine Aula n 7 - DLL: Introduo, Criao de uma DLL, Criao de um


executvel com importao de DLL

Exerccios
1 - Introduo
1) Estude, no HELP, a funo POLYGON (varivel poly) e, ento, no
Simplificadamente, uma DLL (Dynamic Link Library) um programa
programa principal, crie uma paisagem para a animao desenvolvida
independente, em um arquivo separado, que executado quando for evocado
nesta lio.
por qualquer outro programa. Na verdade, em FORTRAN, uma DLL uma
subrotina "de vida prpria", que recebe dados do aplicativo que a evoca,
2) Integre a animao dessa lio ao projeto que j desenvolvemos ao
longo das 5 lies anteriores, utilizando a estrutura previamente faz clculos com esses dados, e depois envia (exporta) os resultados para
desenvolvida (use a callback subr3 ou subr4). Lembre-se que todas as o executvel que a evocou.
definies do programa principal daqui j existem na estrutura
bsica do nosso projeto. Em QuickWin Application existem algumas limitaes de uso, e uma DLL s
funcional para o clculo numrico. Em QuickWin Application uma DLL no
3) Crie um boneco (cabea, tronco e membros) e faa-o subir uma ladeira pode ter nenhum comando grfico, e nem tampouco interaes diretas com o
caminhando. operador. Por exemplo: uma DLL no l dados via teclado (mas em um
arquivo, sim) e nem escreve na tela (mas em um arquivo, sim). Para criar
um programa funcional (um executvel interligado com uma DLL), deve-se
4) Melhore o programa grfico 2D apresentado, de forma que cada trecho criar dois projetos. Um para a DLL e outro para o executvel que a
da linha seja desenhado no quadrante apropriado. utilizar.

2 - Criao de uma DLL


Para criar uma DLL deve-se criar um projeto especfico para esse fim,
seguindo-se os seguintes passos:

1) No menu "File" clique em "New":


Depois, clique OK.

3) Para criar o cdigo fonte da DLL, faa como de costume. V ao menu "
File" e clique em "New".

4) Na caixa de dilogo "New", com a aba em "File", escolha "Fortran Free


Format Source File" (formato livre, extenso .f90) e, na edit box "File
name", d um nome ao arquivo com o cdigo fonte da DLL. Vamos cham-lo de "
Arq_DLL":

2) Na caixa de dilogo "New", com a aba em "Projects", marque "Fortran


Dynamic Link Library", e na edit box "Project name" d um nome ao projeto
(voc pode, mas no mude a locao default). Vamos cham-lo de "Teste_DLL":

Depois, clique OK.

5) Crie, ento, uma subrotina simples (chame-a de MEU_TESTE), que receba


os valores dos reais "a" e "b", e que repasse a soma "s" ao executvel que
a evocou. A declarao indicando do que se trata, isto , a declarao que
d a diretiva de compilao (com o atributo de exportao da DLL) deve ser
escrita depois da declarao inicial da subrotina. Vejamos as duas
declaraes iniciais:

SUBROUTINE MEU_TESTE(a,b,s)

!MS$ ATTRIBUTES DLLEXPORT :: MEU_TESTE

Ateno: a) os argumentos da subrotina so "a" e "b" (dados a serem


importados do programa que a evocar) e "s" (argumento de retorno a ser
exportado para a subrotina).

b) o atributo "DLLEXPORT" significa tratar-se da DLL em si, que


vai exportar resultados.
c) os comandos finais so os de uma subrotina comum:

RETURN e END SUBROUTINE

d) na diretiva com o atributo de exportao da DLL (aquela


linha verde, comeada com exclamao e que parece com uma linha de
comentrio), o nome (apelido, ou alias) depois de "::" aquele com o qual
a DLL ser evocada por outro aplicativo, na diretiva com o atributo de
importao de resultados. Ento, no caso anterior tal nome MEU_TESTE

e) a diretiva foi iniciada por !$MS para incluir tambm o


estdio PowerStation.

f) assegure-se de que o arquivo criado j esteja salvo e


adicionado ao projeto.

6) Para compilar e criar a DLL clique no menu "Build" e, depois, em "


Build Teste_DLL.dll":

7) Com tudo pronto, feche o projeto.

Ateno: aps a criao da DLL, dois arquivos dentro da pasta "Debug"


so de especial importncia para a utilizao de tal DLL:

a) a prpria DLL em si, que nesse caso foi chamada Teste_DLL.dll"(na hora
da execuo ela dever estar no mesmo diretrio do executvel que a
evocar)

b) "Teste_DLL.lib" (que dever ser ligado aos arquivos do projeto que


gerar o executvel que importar os resultados da DLL).

Note que isto feito da mesma forma que se criaria um programa executvel Os arquivos de interesse podem ser encontrados, via explorer, na locao
comum, s que a extenso do arquivo a ser criado no ".exe" e sim, mostrada na figura a seguir:
".dll". O aspecto geral das janelas do estdio pode ser visto na figura a
seguir:
5) Crie um programa simples, que leia os valores de "a" e "b" via
teclado, e que evoque a subrotina contida em "Teste_DLL.dll" para somar
esses valores, informando depois, na tela, o resultado. Note que uma
declarao que d a diretiva de compilao com o atributo de importao da
DLL deve seguir-se declarao inicial de um programa principal. Vejamos
as duas declaraes iniciais:

PROGRAM PRINCIPAL

!MS$ ATTRIBUTES DLLIMPORT :: MEU_TESTE

Ateno: a) bom lembrar que "MEU_TESTE" foi o apelido (alias), isto , o


nome interno dado DLL.

b) o atributo "DLLIMPORT" :: MEU_TESTE significa tratar-se da


importao de resultados de uma DLL denominada, internamente, de "MEU_TESTE
".

c) a forma de evocar a DLL a mesma da evocao de qualquer


subrotina: call MEU_TESTE(a,b,s).

d) depois da evocao da DLL (como uma subrotina comum), o


programa deve prosseguir normalmente.
Clicando na pasta DEBUG, v-se alguns arquivos intermedirios e os dois
arquivos de interesse (Teste_DLL.dll e Teste_DLL.lib): e) o programa principal termina como de costume: STOP (se couber)
e depois END PROGRAM.

f) Uma vez criado o fonte do programa principal, assegure-se de


que o arquivo j esteja adicionado ao projeto.

6) Com o fonte do programa principal j pronto copie, l do diretrio da


DLL (chamado "Teste_DLL"), os arquivos "Teste_DLL.dll" e "Teste_DLL.lib",
que esto na pasta "Debug" daquele diretrio. Ento, cole-os na pasta "
Utiliza_teste_DLL".

7) Ligue o arquivo "Teste_DLL.lib" ao projeto atual, que criar o


executvel. Para fazer isso, use a forma habitual de adicionar (inserir)
um arquivo ao projeto (selecione-o e depois insira-o, isto , adicione-o
ao projeto):
3 - Criao de um Executvel
Para criar o executvel que importar os resultados da DLL, os passos a
serem seguidos so os normais: cria-se um novo projeto, conforme visto em
lies anteriores. Veja:

1) No menu "File" clique em "New"

2) Na caixa de dilogo "New", com a aba em "Projects", marque "Fortran


Standard Graphics or QuickWin Application", e na edit box "Project name"
d um nome ao projeto. Vamos cham-lo de "Utiliza_teste_DLL". Depois,
clique OK.

3) Para criar o executvel, propriamente dito, v ao menu "File" e clique


em "New".
Assim que a caixa Insert Files into Project aparecer, selecione o
4) Na caixa dilogo "New", com a aba em "File", escolha "Fortran Free arquivo Teste_DLL.lib
Format Source File" (formato livre, extenso .f90) e, na edit box "File
name", d um nome ao arquivo com o cdigo fonte do executvel. Vamos
chamar esse arquivo fonte de "Principal". Depois, clique OK.
"Utiliza_teste_DLL.exe" em uma pasta qualquer e tente execut-lo. No vai
funcionar. Coloque, ento, o arquivo "teste_DLL.dll" na mesma pasta:
agora, o executvel deve funcionar.

4 - Cdigos fontes

Cdigo fonte da DLL

SUBROUTINE MEU_TESTE (a , b , s)

!MS$ ATTRIBUTES DLLEXPORT :: MEU_TESTE

s=a+b

RETURN

END SUBROUTINE
Ento, ao clicar OK na caixa acima, a janela com os arquivos do projeto
conter dois arquivos: "principal.f90" e "Teste_DLL.lib". Veja o aspecto
da janela com os componentes do projeto: Cdigo fonte do EXECUTVEL

PROGRAM PRINCIPAL

!MS$ ATTRIBUTES DLLIMPORT :: MEU_TESTE

write (* , *)'escreva "a" e "b"'

read (* , *)a , b

call MEU_TESTE (a , b , s)

write(*,*)'soma: s =',s

STOP

END

5 - Avance um Pouco Mais


No projeto que desenvolvemos ao longo deste curso, o clculo das razes da
equao de segundo grau est "misturado" com a parte grfica de
apresentao do software, o que no muito recomendvel. Retire esse
clculo do projeto original e utilize uma DLL para faz-lo.

O arquivo "Teste_DLL.lib" contm informaes que viabilizar a utilizao


da DLL pelo executvel. Agora, compile e crie o executvel atravs da
opo "Build Utiliza_teste_DLL.exe", no menu "Build".

8) O executvel j existe mas no funciona individualmente. Ele necessita


da DLL (na verdade uma subrotina) para o seu funcionamento correto e,
sempre que o executvel for rodado em um diretrio, a DLL deve estar
presente nesse mesmo diretrio. Para perceber isso, coloque o arquivo
listaP listaR
Exerccios Propostos Exerccios Resolvidos

Estes exerccios so recomendveis a partir da segunda aula, Uma observao: existem algumas convenes mostrando como escrever
e destinados a quem ainda no sabe programar em Fortran 77. Caso cada comando, o que deve ser maisculo, o que deve ser minsculo, e outros.
voc no tenha o Power Station em casa, use o ambiente do software Aqui, no seguimos essas convenes.
AJUSTE (DOS) (http://www.extensao.hpg.com.br).

1) Faa um programa que indentifique as letras S ou s como a resposta


sim a uma pergunta, e as letras N e n como a resposta no. Se for teclada
1)Fazer um programa que leia um conjunto de dados em um arquivo e faa o qualquer outra letra, emitir a observao de que a resposta deve ser
somatrio desses dados. as letras referentes a sim ou no, e perguntar novamente.

SOLUO
2) Determinado ao classificado de acordo com o resultado de trs program detecta
testes, que devem verificar se o mesmo satisfaz s seguintes
especificaes: use msflib
Teste 1 - contedo de carbono abaixo de 7%; CHARACTER (1) RESPOSTA
teste 2 - dureza Rokwell maior que 50; TYPE (qwinfo) winfo
teste 3 - resistncia trao maior que 80000 psi.
Ao ao atribuido o grau 10 se passa pelos trs testes; 9 se ! Maximiza a tela principal(FRAME)
passa apenas nos testes 1 e 2; 8 se passa no teste 1 e 7 se no passou winfo.TYPE = QWIN$MAX
nos trs testes. Supondo que sejam lidos de uma unidade de entrada o ires = SETWSIZEQQ(QWIN$FRAMEWINDOW, winfo)
nmero de amostras, o contedo de carbono (em %), a dureza Rokwell e
a resistncia trao (em psi), fazer um programa que d a !colore a "janela filhote"(CHILD WINDOW)
classificao de 112 amostras de ao que foram testadas, escrevendo I=SETBKCOLORRGB(#997654)
o nmero da amostra e o grau obtido. call clearscreen($gclearscreen)
!maximiza a "janela filhote"
Iresult=SETWSIZEQQ(0, winfo)

3) Fazer um programa que calcule e escreva o nmero de gros de milho


que se pode colocar num tabuleiro de xadrez, colocando 1 gro no primeiro write(*,*)'DETECO DE RESPOSTA VIA TECLADO'
quadro e, nos quadros seguintes, o dobro do anterior. WRITE(*,*)' '
WRITE(*,*)' '
WRITE(*,*)' '

4) Fazer um programa que leia duas matrizes em um arquivo e faa o produto


entre elas, apresentando o resultado na tela e em um arquivo. 10 continue

WRITE(*,*)'QUAL A SUA RESPOSTA? SIM: S NO: N'


READ(*,*)RESPOSTA
5)Fazer um programa para calcular a raiz quadrada de um nmero positivo
usando o roteiro abaixo, baseado no mtodo de aproximaes sucessivas de
Newton: IF(RESPOSTA == 's' .or. RESPOSTA == 'S' .OR. RESPOSTA == 'n' .OR. RESPOSTA =='N')goto 20
call clearscreen($gclearscreen) !limpa toda a tela
* a primeira aproximao para a raiz quadrada de Y X1 = Y/2; WRITE(*,*)'Responda S, s, N ou n.'
* as sucessivas aproximaes sero: Xn+1 = [(Xn)**2 + Y]/(2*Xn). WRITE(*,*)' '
WRITE(*,*)' '
O programa dever fazer 20 aproximaes. WRITE(*,*)' '
call BEEPqq(300,500)!emite sinal sonoro: freq = 300Hz e durao 500ms.
GOTO 10
6) Fazer um prgrama para determinar e escrever o valor de pi, o qual pode 20 continue
ser calculado pela integral:
IF(RESPOSTA == 'N' .OR. RESPOSTA == 'n')THEN
pi = itegral de [1/(1 + X**2)]dx, com X variando de 0 a 1.
call clearscreen($gclearscreen)

WRITE(*,*)' '
7) Foram feitas uma srie de N leituras de uma grandeza de X e obtidos os WRITE(*,*)' '
resultados x1, x2, ..., xN. Fazer um programa que calcule o valor mdio WRITE(*,*)' '
e o desvio padro das leituras. Obs.: se a preciso do instrumento de write(*,*)"A sua resposta foi NO"
leituras for grande, os valores das medidas sero prximos, e trabalhar WRITE(*,*)' '
com preciso simples pode resultar em erros bastante considerveis. Usar WRITE(*,*)' '
dupla preciso. WRITE(*,*)' '

ELSE
call clearscreen($gclearscreen)
8) Fazer um programa que determine uma das raizes de uma funo dada. O
intervalo (Xmin,Xmax) que contm a raiz deve ser informado. Usar o mtodo WRITE(*,*)' '
da bisseo. WRITE(*,*)' '
WRITE(*,*)' '
WRITE(*,*)'A SUA RESPOSTA FOI SIM'
WRITE(*,*)' '
WRITE(*,*)' '
WRITE(*,*)' '
Page 1 Page 1
listaR listaR

WRITE(*,'(" FATORIAL = ",E13.7)')FAT


END IF
stop
stop
end program fatorial
end program detecta

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ //////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////

4) Utilize a estrutura desenvolvida no primeiro exerccio resolvido


2) Faa um programa para somar valores Xi, dados num arquivo chamado para criar um programa que pergunta se o usurio quer somar valores
dados.dat, onde o primeiro dado o nmero N de valores a serem lidos dados em um arquivo, ou se quer calcular o fatorial de um nmero dado.
e depois somados. Depois, o programa deve executar a opo informada pelo usurio.

SOLUO SOLUO

program SOMA program diversos


USE MSFLIB use msflib
dimension x(500) DOUBLE PRECISION FAT
dimension x(500)
I = SETBKCOLOR(4)
CALL CLEARSCREEN($GCLEARSCREEN) CHARACTER (1) RESPOSTA
TYPE (qwinfo) winfo

open(unit = 1, file = 'dados.dat')! abre o arquivo dados.dat ! Maximiza a tela principal(FRAME)


winfo.TYPE = QWIN$MAX
read(1,*)N ires = SETWSIZEQQ(QWIN$FRAMEWINDOW, winfo)
read(1,*)(x(i), i = 1, N)
!colore a "janela filhote"(CHILD WINDOW)
close(unit = 1) ! fecha o arquivo aberto. I=SETBKCOLORRGB(#997654)
call clearscreen($gclearscreen)
somat = 0.0 !maximiza a "janela filhote"
Iresult=SETWSIZEQQ(0, winfo)
do i = 1, n

somat = somat + x(i) write(*,*)'VOC DESEJA CALCULAR'


WRITE(*,*)' '
end do WRITE(*,*)' '
WRITE(*,*)' '
write(*,*) somat

stop 10 continue
end program soma WRITE(*,*)'SOMATRIO: S FATORIAL: F'
READ(*,*)RESPOSTA
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
////////////////////////////////////////////////////////////////////////// IF(RESPOSTA == 's' .or. RESPOSTA == 'S' .OR. RESPOSTA == 'f' .OR. RESPOSTA =='F')goto 20
call clearscreen($gclearscreen) !limpa toda a tela
WRITE(*,*)'Responda S, s, F ou f.'
3) Faa um programa que l um inteiro e que calcule o fatorial deste WRITE(*,*)' '
nmero. WRITE(*,*)' '
WRITE(*,*)' '
SOLUO call BEEPqq(300,500)!emite sinal sonoro: freq = 300Hz e durao 500ms.
GOTO 10
program fatorial
USE MSFLIB 20 continue
DOUBLE PRECISION FAT
IF(RESPOSTA == 'F' .OR. RESPOSTA == 'f')THEN
I = SETBKCOLOR(2)
CALL CLEARSCREEN($GCLEARSCREEN) I = SETBKCOLOR(2)
CALL CLEARSCREEN($GCLEARSCREEN)
I = DISPLAYCURSOR($GCURSORON)!ABILITA CURSOR
write(*,*)'ESCREVA O INTEIRO:' I = DISPLAYCURSOR($GCURSORON)!ABILITA CURSOR
READ(*,*) N write(*,*)'ESCREVA O INTEIRO:'
READ(*,*) N
FAT = 1.0
FAT = 1.0
DO I = 1, N
FAT = FAT*FLOAT(I) DO I = 1, N
END DO FAT = FAT*FLOAT(I)
END DO

Page 2 Page 3
listaR modelo
WRITE(*,'(" FATORIAL = ",E13.7)')FAT Ateno: a estrutura dada a seguir pode ser usada para que voc
desenvolva seus programas nela, como subroutine callback, no ambiente
ELSE PowerStation ou Visual Studio, em QickWin Application. Colocamos 5
subroutine callback, com os nomes de subroutine subr1, ...,
I = SETBKCOLOR(4) subroutine subr5. Na estrutura tem comentrios de como inserir seus programas.
CALL CLEARSCREEN($GCLEARSCREEN) Naturalmente que, quem tiver experincia, deve personalisar suas
prprias estruturas. Para usar esta, s copiar toda a estrutura e
open(unit = 1, file = 'dados.dat')! abre o arquivo dados.dat inserir no Workspace que j deve ter sido criado.
Uma observao: existem algumas convenes mostrando como escrever
read(1,*)N cada comando, o que deve ser maisculo, o que deve ser minsculo, e outros.
read(1,*)(x(i), i = 1, N) Aqui, no seguimos essas convenes.
close(unit = 1) ! fecha o arquivo aberto. Wilton, Cleide (UFPB) e Cleiton (ITA) (wiltonps@uol.com.br)
somat = 0.0
!programa principal, chamado Prog_QW. Mude o nome, se for o caso
do i = 1, n program Prog_QW
somat = somat + x(i) use msflib !biblioteca com muitas funes grficas e outras.
end do TYPE (windowconfig) wc !define uma varivel para as informaes sobra a configurao do
micro.
WRITE(*,*)' ' TYPE (qwinfo) winfo !define uma varivel para informaes sobre o dimensionamento do frame e
WRITE(*,*)' ' child window.
WRITE(*,*)' ' TYPE (XYCOORD) XY !define uma varivel para estabelecer uma posio no vdeo atravs de
write(*,"(' Somatrio =',1x, e13.7)") somat coordenadas em pixels.
WRITE(*,*)' ' LOGICAL status
WRITE(*,*)' '
WRITE(*,*)' ' ! Maximiza a tela principal
winfo.TYPE = QWIN$MAX
END IF ires = SETWSIZEQQ(QWIN$FRAMEWINDOW, winfo)
stop ! obtm dados do sistema: nmero de pixels, etc.
wc.numxpixels = -1
end program diversos wc.numypixels = -1
wc.numtextcols = -1
wc.numtextrows = -1
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ wc.numcolors = -1
////////////////////////////////////////////////////////////////////////// ! a "janela filhote" se chamar "PROGRAMAS" mas o nome pode ser
!mudado para o desejado.
wc.title= "PROGRAMAS"C ! ttulo da "janela filhote" (child window)
wc.fontsize = -1

status = SETWINDOWCONFIG(wc) ! estabelece a configurao do micro como aquela obtida


anteriormente.

!colore a "janela filhote"


I=SETBKCOLORRGB(#808080)
call clearscreen($gclearscreen)

!maximiza a "janela filhote"


Iresult=SETWSIZEQQ(0, winfo)

inumfonts = INITIALIZEFONTS( ) !disponibiliza os tipos de fontes do micro.

!escolha do tipo de letras a serem usadas.


ifontnum = SETFONT ('t''Arial''h30w20i')! h30 a altura das letras na tela e w20 a
largura. O i refere-se a itlico.

! se ifontnum for -1, a fonte requerida no existe. Ento, deve-se escolher outra fonte.
if(ifontnum.eq.-1) ifontnum = SETFONT ('t''times new roman''h30')
if(ifontnum.eq.-1) ifontnum = SETFONT ('t''courier new''h30')
if(ifontnum.eq.-1) ifontnum = SETFONT ('t''tahoma''h30')
if(ifontnum.eq.-1) ifontnum = SETFONT ('t''cac futura casual''h30')

!cor da palavra a ser escrita na tela (se voc quiser escrever)


i= setcolor(10)! de 0 a 15
!voc pode alterar as coordenadas onde a palavra ser escrita
call moveto (50,170,xy) ! coordenadas (em pixels) de onde ser escrita a palavra ou frase a
seguir.
call outgtext(' ') !escreva entre os apstrofes uma palavra ou frase para aparecer na tela

!Loop infinito: mantm o programa funcionando depois de executado


do while (.true.)
end do
Page 4 Page 1
modelo modelo
! a seguir, subrotinas callbacks onde voc pode colocar programas
end program ! fim do programa principal subroutine subr1(ia)

USE MSFLIB
!/////////////////////////////////////////////////////////////////////////// logical ia
!///////////////////////////////////////////////////////////////////////////
ia = .true. !argumento da subrotina callback subr1

!Funo onde se define os itens do menu. CALL CLEARSCREEN($GCLEARSCREEN) !apaga o que estiver escrito na tela
LOGICAL(4) FUNCTION INITIALSETTINGS()
USE MSFLIB !para abrir uma nova child window d os comamandos abaixo (basta tirar o smbolo de
LOGICAL(4)result comentrio "!")
external subr1, subr2, subr3, subr4, subr5, leiame !open(unit = 1, file = 'user', title = 'programa1') !ateno: se voc abrir, lembre-se de
fechar antes do return.
! Cria um menu 1 chamado Arquivo !i = setbkcolor(12) ! colore a child window de vermelho
result = APPENDMENUQQ(1, $MENUENABLED, '&Arquivo'C, NUL ) !call clearscreen($gclearscreen) !limpa a tela
!i= displaycursor($gcursoron) !ativa cursor
! os nomes programa1, programa2, ..., programa5
!(C strings) definidos a seguir devem ser alterados
!de acordo com as suas aplicaes. !suspende os itens do menu 1 durante a execuo desta subrotina
result = MODIFYMENUFLAGSQQ (1, 1, $MENUGRAYED)
! chama a callback subr1 (externa, feita pelo programador result = MODIFYMENUFLAGSQQ (1, 2, $MENUGRAYED)
!e, por isso, foi declarada no incio da funo result = MODIFYMENUFLAGSQQ (1, 3, $MENUGRAYED)
!initialsettings) result = MODIFYMENUFLAGSQQ (1, 4, $MENUGRAYED)
result = APPENDMENUQQ(1, $MENUENABLED, 'Programa1'C, subr1) result = MODIFYMENUFLAGSQQ (1, 5, $MENUGRAYED)
!coloca um trao separando o primeiro do segundo item do menu result = MODIFYMENUFLAGSQQ (1, 6, $MENUGRAYED)
result = APPENDMENUQQ(1, $MENUSEPARATOR, ''C,NUL ) result = MODIFYMENUFLAGSQQ (1, 7, $MENUGRAYED)
result = MODIFYMENUFLAGSQQ (1, 8, $MENUGRAYED)
result = APPENDMENUQQ(1, $MENUENABLED, 'Programa2'C, subr2) result = MODIFYMENUFLAGSQQ (1, 9, $MENUGRAYED)
result = APPENDMENUQQ(1, $MENUSEPARATOR, ''C, NUL ) !Obs: para suspender o menu 1 inteiro (e no item por item) bastaria dar o comando:
result = APPENDMENUQQ(1, $MENUENABLED, 'Programa3'C, subr3) !result = MODIFYMENUFLAGSQQ (1, 0, $MENUGRAYED)
result = APPENDMENUQQ(1, $MENUSEPARATOR, ''C, NUL )
result = APPENDMENUQQ(1, $MENUENABLED, 'Programa4'C, subr4) !INSIRA UM PROGRAMA AQUI, E APAGUE A LINHA A SEGUIR
result = APPENDMENUQQ(1, $MENUSEPARATOR, ''C, NUL ) message = messageboxqq('Este item est indisponvel no
result = APPENDMENUQQ(1, $MENUENABLED, 'Programa5'C, subr5) momento!'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1)
result = APPENDMENUQQ(1, $MENUSEPARATOR, ''C, NUL )

!chama a subrotina WINEXIT (interna, definida em MSFLIB) !reativa os itens do menu aps a execuo desta subrotina
!que termina a execuo do programa em loop infinito result = MODIFYMENUFLAGSQQ (1, 1, $MENUENABLED)
result = APPENDMENUQQ(1, $MENUENABLED, 'Sair'C, WINEXIT) result = MODIFYMENUFLAGSQQ (1, 2, $MENUENABLED)
result = MODIFYMENUFLAGSQQ (1, 3, $MENUENABLED)
result = MODIFYMENUFLAGSQQ (1, 4, $MENUENABLED)
result = MODIFYMENUFLAGSQQ (1, 5, $MENUENABLED)
result = MODIFYMENUFLAGSQQ (1, 6, $MENUENABLED)
! Cria um menu 2 chamado Informaes. result = MODIFYMENUFLAGSQQ (1, 7, $MENUENABLED)
result = APPENDMENUQQ(2, $MENUENABLED, '&Informaes'C, NUL ) result = MODIFYMENUFLAGSQQ (1, 8, $MENUENABLED)
result = MODIFYMENUFLAGSQQ (1, 9, $MENUENABLED)
! chama a callback subrotina de msflib com ajuda sobre o !Obs: para ativar um menu inteiro desativado com o comando result =
!QuickWin Application MODIFYMENUFLAGSQQ (1, 0, $MENUGRAYED) basta dar o comando:
result = APPENDMENUQQ(2, $MENUENABLED, 'Ajuda QuickWin'C, WININDEX) !result = MODIFYMENUFLAGSQQ (1, 0, $MENUENABLED)
result = APPENDMENUQQ(2, $MENUSEPARATOR, ''C, NUL )

! chama a callback WINUSING (interna, definida em msflib) com !message = messageboxqq('Este programa
!ajuda sobre o windows terminou'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1)
result = APPENDMENUQQ(2, $MENUENABLED, 'Usando a Ajuda'C, WINUSING) !i= displaycursor($gcursoroff) !desativa cursor
result = APPENDMENUQQ(2, $MENUSEPARATOR, ''C, NUL ) !close(unit = 1)
!chama a subrotina WINABOUT (interna, definida em msflib) com return
!informaes sobre o Developer Studio.
result = APPENDMENUQQ(2, $MENUENABLED, 'Sobre o Developer Studio'C, WINABOUT) end subroutine
result = APPENDMENUQQ(2, $MENUSEPARATOR, ''C, NUL )

!chama a callback leiame (externa, feita pelo programador !///////////////////////////////////////////////////////////////////////////


!e deve ser declarada) !///////////////////////////////////////////////////////////////////////////
result = APPENDMENUQQ(2, $MENUENABLED, 'Leiame'C, leiame)

INITIALSETTINGS= .true. subroutine subr2(ia)


END FUNCTION INITIALSETTINGS !fim da subrotina lgica que cria o menu. USE MSFLIB
logical ia
!/////////////////////////////////////////////////////////////////////////// ia = .true.
!///////////////////////////////////////////////////////////////////////////
!suspende todo o menu 1 durante a execuo desta subrotina
result = MODIFYMENUFLAGSQQ (1, 0, $MENUGRAYED)
! subrotinas callbacks:
Page 2 Page 3
modelo modelo
CALL CLEARSCREEN($GCLEARSCREEN)
USE MSFLIB
!INSIRA UM PROGRAMA AQUI, E APAGUE A LINHA A SEGUIR logical ia
message = messageboxqq('Este item est indisponvel no
momento!'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1) ia = .true.

!reativa todo o menu aps a execuo desta subrotina !suspende todo o menu 1 durante a execuo desta subrotina
result = MODIFYMENUFLAGSQQ (1, 0, $MENUENABLED) result = MODIFYMENUFLAGSQQ (1, 0, $MENUGRAYED)

CALL CLEARSCREEN($GCLEARSCREEN)
return
!INSIRA UM PROGRAMA AQUI, E APAGUE A LINHA A SEGUIR
end subroutine message = messageboxqq('Este item est indisponvel no
momento!'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1)

!/////////////////////////////////////////////////////////////////////////// !reativa todo o menu aps a execuo desta subrotina


!/////////////////////////////////////////////////////////////////////////// result = MODIFYMENUFLAGSQQ (1, 0, $MENUENABLED)

return
subroutine subr3(ia)
end subroutine
USE MSFLIB
logical ia
!///////////////////////////////////////////////////////////////////////////
ia = .true. !///////////////////////////////////////////////////////////////////////////

!suspende todo o menu 1 durante a execuo desta subrotina


result = MODIFYMENUFLAGSQQ (1, 0, $MENUGRAYED) subroutine leiame(ia)

CALL CLEARSCREEN($GCLEARSCREEN) USE MSFLIB


logical ia
!INSIRA UM PROGRAMA AQUI, E APAGUE A LINHA A SEGUIR
message = messageboxqq('Este item est indisponvel no ia = .true.
momento!'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1)
! Quando j existir um arquivo leiame, apague as prximas duas
!reativa todo o menu aps a execuo desta subrotina ! linhas na sua aplicao
result = MODIFYMENUFLAGSQQ (1, 0, $MENUENABLED) message = messageboxqq('Este item est indisponvel no
momento!'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1)
return return

end subroutine i = runqq('write.exe','leiame.doc')

return
!///////////////////////////////////////////////////////////////////////////
!/////////////////////////////////////////////////////////////////////////// end subroutine

subroutine subr4(ia) !///////////////////////////////////////////////////////////////////////////


!///////////////////////////////////////////////////////////////////////////
USE MSFLIB
logical ia

ia = .true.

!suspende todo o menu 1 durante a execuo desta subrotina


result = MODIFYMENUFLAGSQQ (1, 0, $MENUGRAYED)

CALL CLEARSCREEN($GCLEARSCREEN)

!INSIRA UM PROGRAMA AQUI, E APAGUE A LINHA A SEGUIR


message = messageboxqq('Este item est indisponvel no
momento!'c,'Ateno',MB$OK.OR.MB$ICONEXCLAMATION.or.MB$DEFBUTTON1)

!reativa todo o menu aps a execuo desta subrotina


result = MODIFYMENUFLAGSQQ (1, 0, $MENUENABLED)

return

end subroutine

!///////////////////////////////////////////////////////////////////////////
!///////////////////////////////////////////////////////////////////////////

subroutine subr5(ia)
Page 4 Page 5
Guia bsico de
programao em NDICE
linguagem
Fortran 77 e 90 CAPTULO 1: CONCEITOS DA LINGUAGEM 1
1. INTRODUO ............................................................................................................................ 1
2. FORMATAO .......................................................................................................................... 1
3. CONCEITOS BSICOS ................................................................................................................ 2
4. DECLARAO DE VARIVEIS .................................................................................................... 3
Tipos de Variveis 4
Inteiras (INTEGER) 4
Reais (REAL) 5
Complexas (COMPLEX) 5
Alfanumricas (CHARACTER) 5
Lgicas (LOGICAL) 6
5. OPERADORES ........................................................................................................................... 6
Atribuio 6
Operadores Literais 6
Operadores Aritmticos 7
Operadores Relacionais 7
Operadores Lgicos 7
Prioridade 8
6. FUNES INTRNSECAS ............................................................................................................. 8
Funes Trigonomtricas 8
Funes Diversas 9

Programao 7. FUNES E SUBROTINAS ........................................................................................................... 9


Funes
Subrotinas
9
10

em Linguagem 8. LEITURA E IMPRESSO ............................................................................................................ 11


9. FORMATOS (LEITURA OU IMPRESSO)...................................................................................... 12
Outros Recursos Para Formatos 15

FORTRAN 10. ARQUIVOS ............................................................................................................................ 16


Outros Recursos
CAPTULO 2: ESTRUTURAS DE PROGRAMAO 18
17

1. ESTRUTURA SEQENCIAL ....................................................................................................... 18


2. COMANDO GO TO OU GOTO ............................................................................................ 19
3. ESTRUTURA CONDICIONAL ..................................................................................................... 19
Estrutura Condicional Simples 19
Estrutura Condicional Composta 19
Estrutura Condicional Composta Simplificada 20
4. ESTRUTURAS DE REPETIO ................................................................................................... 21
Estruturas de Repetio Simples 21
DO WHILE (F90) 22
DO Implcito (WIN) 23
CAPTULO 3: RECURSOS DE PROGRAMAO 24
1. DESLOCAMENTO..................................................................................................................... 24
GOTO Implcito 24
IF Com Deslocamento 24
2. DECLARAES E ATRIBUIES AVANADAS ........................................................................... 25
DIMENSION 25
PARAMETER 26
TYPE (F90) 26
DATA 27
Helder Pereira Cristo 3. DESIGNAO DE MEMRIA ..................................................................................................... 28
Belo Horizonte COMMON 28
Junho/2003 BLOCK DATA 29
4. MODULARIZAO .................................................................................................................. 29
INCLUDE 29
Programao em Linguagem FORTRAN .1.

ANEXO A: FUNES INTRNSECAS 31


1. FUNES TRIGONOMTRICAS ................................................................................................. 31
Captulo 1: Conceitos da Linguagem
2. FUNES GENRICAS ............................................................................................................. 32
3. EXPONENCIAIS ....................................................................................................................... 33
4. LOGARITMOS.......................................................................................................................... 33 1. Introduo
5. MXIMOS............................................................................................................................... 33
6. MNIMOS ................................................................................................................................ 33
7. RESTOS .................................................................................................................................. 33 Em FORTRAN existem basicamente duas formas de se escrever um programa: com
8. RAIZ QUADRADA DE X ........................................................................................................... 34 formulrio fixo (fixed form) ou com formulrio livre (free form). Sendo este segundo disponvel
9. TRUNCAMENTO DE X .............................................................................................................. 34
10. ARREDONDAMENTO DE X ..................................................................................................... 34 apenas para os compiladores mais novos que suportam a programao em FORTRAN 90.
11. DIFERENA POSITIVA ENTRE X E Y....................................................................................... 34
12. TIPO DE DADO ...................................................................................................................... 34
Outro ponto importante que existem comandos vlidos somente para estes novos
13. TRANSFORMAO DO TIPO DE X ........................................................................................... 35 compiladores (por exemplo Microsoft Developer Studio) que aceitam programas em FORTRAN
14. COMPLEXOS ......................................................................................................................... 35
15. CARACTERES ........................................................................................................................ 35 90. Algumas verses dos compliladores baseados em FORTRAN 77 aceitam funes ou
16. VALORES ABSOLUTOS DE X .................................................................................................. 36
comandos criados posteriormente a essa verso, mas no aceitam todas as inovaes dos
ANEXO B: OPES DE ARQUIVOS, LEITURA E ESCRITA 37 compiladores de FORTRAN 90. Para as explicaes ficarem mais claras a seguinte
1. ABERTURA DE ARQUIVOS (OPEN) .......................................................................................... 37
2. FECHAMENTO DE ARQUIVOS (CLOSE).................................................................................... 38 nomenclatura ser utilizada:
3. ESCRITA (WRITE).................................................................................................................. 38
4. LEITURA (READ)................................................................................................................... 39 tpicos precedidos da identificao N77 s so validos para compiladores novos, mas que
5. RECUO TOTAL (REWIND)...................................................................................................... 39
6. RECUO DE UM CAMPO (BACKSPACE) ................................................................................... 40 no aceitam a programao em FORTRAN 90;

ANEXO C: TABELA DE VALORES ASCII 41 tpicos precedidos de F90 so vlidos apenas para os compiladores que aceitam
comandos FORTRAN 90.

Deve ficar claro que compiladores para FORTRAN 90 aceitam tambm os outros dois
tipos, e os baseados em FORTRAN N77 aceitam todos os comandos dos compiladores mais
antigos (FORTRAN 77), e que a recproca no verdadeira.

Os programas podem ser escritos em qualquer editor de texto, desde que sejam salvos
com as extenses .for ou .f90. Esta segunda forma somente para F90. Os compiladores em
N77 e F90 possuem um editor prprio; que deve ser usado, pois possui muitos recursos
adicionais, como por exemplo o destaque das palavras chaves e identificaes mais claras dos
erros de compilao, o que facilita muita a deteco de falhas na criao dos programas.

2. Formatao

A formatao dos cdigos em FORTRAN, principalmente em formato fixo deve seguir


um estilo diferente dos usados na maioria das linguagens de programao. Estes conceitos
iniciais podem no ficar claro para os iniciantes na linguagem, estes leitores podem observar o
exemplo no final do item 8 (Leitura e impresso) para ter maior clareza da disposio dos
comandos em FORTRAN.
Programao em Linguagem FORTRAN .2. Programao em Linguagem FORTRAN .3.

Os seguintes critrios devem ser seguidos para se escrever um programa em Variveis e Nomes de Blocos: devem ter no mximo seis letras, no permitido o uso de
FORTRAN no modo de formulrio fixo: caracteres especiais e no podem comear com um nmero.

colunas 1 a 5: so usadas para escrever os rtulos label ou nmeros de comando. Estes N77 podem ter 31 caracteres, inclusive o caractere underscore _
nmeros devem ser inteiros e estar totalmente contido nestas colunas. No podem se
repetir e no precisam estar em ordem crescente. Sero usados para que outros comandos Constantes
possam identificar aquela linha;
Numricas: podem conter quaisquer valores reais, inteiros ou complexos. A parte decimal
coluna 6: qualquer caractere diferente de 0 zero nesta coluna indica que o que vem a separada da inteira por um ponto .. Os zeros antes e depois do ponto decimal podem ser
seguir continuao da linha anterior ou da ultima linha que no seja um comentrio omitidos, se no forem significantes. O expoente decimal indicado pela letra e ou E,
(prximo item, conceitos bsicos). Um mesmo comando pode estar dividido em at 19 deve vir entre o nmero e seu expoente sem o uso de espaos entre eles. Nmeros
linhas de cdigo. Entre as linhas do comando pode haver linhas em branco ou comentrios; negativos assim como a parte exponencial quando for negativa deve vir precedida do sinal
menos -. O sinal + opcional em ambas as partes. Os nmeros imaginrios devem vir
colunas 7 a 72: comandos ou comentrios;
entre parnteses e a parte real deve ser separada por uma vrgula da parte imaginria.
colunas 73 a 80: campos de identificao, so usados pelo compilador, portanto no se
Alfanumricas: (so as strings, seqncias de letras e/ou nmeros) podem conter
deve escrever nestas colunas.
qualquer seqncia de caracteres no especiais. Devem vir entre aspas ou apstrofos .
F90 O programa pode ser escrito em qualquer posio, desde que o modo formulrio livre
As aspas tm preferncia sobre os apstrofos, portanto um valor literal pode conter
esteja ativado. Alguns pontos devem ser observados para este formato:
apstrofos, desde que seu valor venha entre aspas. No permitido o uso de caracteres
as linhas de continuao so indicadas pelo smbolo & no fim da sentena, e a prxima especiais e letras acentuadas. Uma forma de se indicar ao compilador que usar um valor
linha abaixo que no seja um comentrio ser tomada como continuao. Deixe sempre um alfanumrico o uso de wHvalorliteral, onde w o nmero de caracteres do valor
espao entre os comandos e o smbolo de continuao. permitida a insero de alfanumrico. Apresar de vlido este formato praticamente no usado nos programas
comentrios aps o &; atuais.

os rtulos devem ser os primeiros caracteres da linha, e podem estar em qualquer coluna. Maisculas e Minsculas: FORTRAN no case sensitive, isto no faz qualquer
distino entre letras maisculas e minsculas. permitido inclusive o uso do nome da
varivel escrita de formas diferentes num mesmo programa. EX.: VAR = var = Var.
3. Conceitos Bsicos
Nomes de programa: os programas podem conter no incio o seu nome (program
Nesta seo sero apresentados outros conceitos importantes para a construo de
nome_do _programa), e devem terminar com a palavra end indicando que o que vem a
programas em FORTRAN.
seguir no precisa ser executado.
Comentrios: no so interpretados pelo computador, um bom programa deve conter
muitos para que fique o mais claro possvel principalmente para quem vai analis-lo. Em
4. Declarao de Variveis
FORTRAN a letra c ou o caractere * na primeira coluna indica que toda a linha um
comentrio. Alguns compiladores aceitam o uso de qualquer caractere diferente de As variveis podem ser inteiras, reais ou literais. A declarao de uma varivel deve vir
nmeros para iniciar a linha de comentrio. Na linha de comentrio permitido o uso de antes que ela seja usada, se isto no ocorrer o compilador assumir que as variveis que
qualquer caractere, especial ou no. comeam com as letras I at N como inteiras (INTEGER*4) e todas as outras como reais

N77 o ponto de exclamao ! indica que o que vem aps ele comentrio, ele pode vir em (REAL*4).

qualquer posio, inclusive aps os comandos.


Programao em Linguagem FORTRAN .4. Programao em Linguagem FORTRAN .5.

Esta forma de declarao implcita pode ser modificada usando o comando implicit Reais (REAL)
tipo (a1-a2,b1-b2,...) sendo a1, a2, b1, b2 quaisquer letras do alfabeto. A vrgula
Preciso simples, 6 casas decimais (padro):
separa os intervalos de letras e o sinal determina o intervalo. As letras que no estiverem em
REAL*4 ou REAL 3.402823E+38
nenhum dos intervalos ter o seu tipo dado pela declarao implcita. O comando seguinte
indica que as variveis que comeam com as letras a, b, c e de r at z so do tipo TIPO1.
Incremento mnimo de 1.175494E-38
implicit TIPO1 (a, b, c, r-z)
Preciso dupla, 15 casas decimais (padro):
os espaos so usados para dar clareza e so ignorados pelo compilador. Quando no se
REAL*8 ou DOBLE PRECISION 1.797693134862316D+308
deseja que nenhuma varivel seja declarada implicitamente usa-se o comando implicit
none. Se este comando for usado e uma varivel citada no programa no estiver em Incremento mnimo de 2.225073858507201D-308
nenhuma outra declarao o complilador acusar um erro.
A parte exponencial deve ser separada por um d ou D no lugar do e ou E para real do tipo
Para se declarar variveis que sejam matrizes e vetores deve-se indicar suas
*8.
dimenses logo aps o nome da varivel; entre parnteses, e separadas umas das outras por
N77 podem ser usados o e ou E para separar a parte exponencial. No s isso mas
vrgula. Ex.: a(4,3) indica uma matriz a de 4 linhas por 3 colunas.
tambm todas as outras funes (item 6 Funes intrnsecas) podem ser iguais a de um real,
As variveis podem receber valores iniciais usando /valor/, logo aps sua
no sendo necessrio o uso de funes especiais para este tipo de valor.
declarao. No caso de vetores e matrizes devem ser dados os valores para todos os
implict real(a-z) ! todas as variveis so reais
elementos de cada linha em seqncia. integer d ! a varivel d inteira mesmo com a
! declarao acima
Tipos de Variveis
Complexas (COMPLEX)
Inteiras (INTEGER) Preciso simples, 6 casas decimais:

Podem assumir os seguintes valores: COMPLEX*8 ou COMPLEX

INTEGER*1 128 a 127 Preciso dupla, 15 casas decimais:

INTEGER*2 32,768 a 32,767 COMPLEX*16

INTEGER*4 2,147,483,648 a 2,147,483,647 Os valores que um complexo pode assumir so os mesmos que os reais.

INTEGER*4 pode ser representado somente por: INTEGER complex c/(4.,.3)/ ! c vale 4,0 reais e 0,3 imaginrios

integer d ! a varivel d inteira do tipo *4 Alfanumricas (CHARACTER)


integer*1 a, b, c ! a, b e c so inteiras do tipo *1
CHARACTER NOME*w
integer a/6/, b(2,2)/0,1,2,3/ ! a = 6
0 1 Onde w representa o nmero mximo de caracteres que a varivel pode conter dentro do
! b =
2 3 programa.

Os nmeros aps o * indicam quantos bytes a varivel ocupa na memria do computador. Esta Ou CHARACTER *wvar1,var2
observao vlida para todos os tipos de variveis.
(var1 e var2 possuem o mesmo tamanho w)
Programao em Linguagem FORTRAN .6. Programao em Linguagem FORTRAN .7.

Ou CHARACTER (LEN = w) var1, (LEN=w2) var2 Operadores Aritmticos

(var1 tem tamanho w e var2 tamanho w2) Executam operaes aritmticas comuns.

cHaRaCtEr loucura/alta/ ! Fortran no faz diferena FORTRAN Matemtica Tradicional Significado


! entre maisculas e minsculas + + soma
character data*8,*9 data2,data3 ! data pode conter 8 caracteres - - Subtrao
! e data2 e data3 9 caracteres * Multiplicao
/ p Diviso
Lgicas (LOGICAL) ** a Potenciao

LOGICAL NOME
Quando uma varivel inteira recebe o resultado de uma diviso com resto, este resto
Podem assumir os valores .TRUE. (VERDADEIRO) ou .FALSE. (FALSO) desprezado ou seja o valor truncado.

Ou somente T e F ou ainda 1 e 0 ou diferente de zero e 0. C = A**2 + B**2 ! c = a2 + b 2


D = E**(1/2) ! d = e1/2

5. Operadores Operadores Relacionais

Comparam variveis, constantes ou expresses e retornam .TRUE., T ou 1 se a


Atribuio
comparao for verdadeira, .FALSE., F ou 0 se a comparao for falsa.
A varivel ou identificador que estiver a esquerda do sinal de atribuio = recebem o
FORTRAN F90 Matemtica Tradicional Significado
valor da expresso, constante ou varivel que estiver direita. .LT. < < MENOR QUE
.LE. <= MENOR OU IGUAL QUE
Identificador = Expresso .EQ. == = IGUAL A
.NE. /= DIFERENTE DE
nome = Engenharia Quimica ! no se pode usar acentuao .GT. > > MAIOR QUE
ano = 1999 ! no preciso de ; no final .GE. >= MAIOR OU IGUAL QUE
data1 = 12\10\98
data2 = 20\11\98 ! as strings no precisam usar 20 .ne. 30 ! verdadeiro
data3 = 15\3\99 ! todo o campo a que tem direito 1000 .lt. 500 ! falso
temp(1)= 25.6
temp(2)= 22.4 ! atribuindo valores a vetores Operadores Lgicos
temp(3)= 22.8
So usados quando so necessrias mais de uma condio relacional ou quando

F90 estas declaraes poderiam estar na mesma linha desde que fossem separadas por preciso inverter seu resultado.

ponto e vrgula ;. FORTRAN Significado


Juno verdadeiro se os dois operadores
.AND.
data3 = 15\3\99;temp(1)= 25.6;num_dias= 3 forem verdadeiros
Disjuno verdadeiro se um dos dois
.OR.
Operadores Literais operadores forem verdadeiro
.NOT. Negao verdadeiro se o operador for falso
Desigualdade Lgica verdadeiro se
Uma funo til para variveis literais a concatenao, ou a juno de duas ou mais .NEQV. ou .XOR.
somente um dos operadores for verdadeiro
palavras. Em FORTRAN a concatenao feita pelo operador //. Igualdade Lgica verdadeiro se os dois
.EQV.
operadores forem falsos ou verdadeiros
a = tele
b = visao 10.GT.5 .AND. 20.GT.25 ! .FALSE. ou 0
c = a//b ! c = televisao 10.GT.5 .OR. 20.GT.25 ! .TRUE. ou 1
.NOT. 20.GT.25 ! .TRUE. ou 1
10 > 5 .XOR. 20 >= 25 ! .TRUE. ou 1
Programao em Linguagem FORTRAN .8. Programao em Linguagem FORTRAN .9.

10.GT.5 .NEQV. 25.GT.20 ! .FALSE. ou 0 Outras funes trigonomtricas podem ser encontradas no Anexo A.
10 < 5 .EQV. 20 <= 25 ! .TRUE. ou 1
10.LT.5 .EQV. 25.GT.20 ! .FALSE. ou 0 Funes Diversas

Prioridade Nome Definio Tipo de Argumento Tipo da Funo


ALOG10 (x) logaritmo de x na base 10 real real
FORTRAN usa a seguinte relao de prioridades: ALOG (x) logaritmo neperiano de x (x > 0) real real
EXP (x) o nmero e (base dos logaritmos real real
Operador Prioridade neperianos) elevado a x
** 1 ABS (x) valor absoluto de x real real
* 2 IABS (x) valor absoluto de x inteiro inteiro
/ 2 IFIX (x) converso de real para inteiro, truncando real inteiro
+ 3 FLOAT (x) converso de inteiro para real inteiro real
- 3 DBLE (x) converte para dupla preciso real real (dupla preciso)
.EQ. 4 CMPLX (x) converte para o tipo complexo real complexo
.NE. 4 SIGN (x,y) fornece valor positivo de x se y 0 e real real
.GT. 4 negativo de x se y < 0
.GE. 4 MOD (x,y) resto da diviso de x por y inteiro inteiro
.LT. 4 AMOD (x,y) resto da diviso de x por y real real
.LE. 4 SQRT (x) raiz quadrada de x (x 0) real real
.NOT. 5
.AND. 6
.OR. 7 Outras funes intrnsecas podem ser encontradas no Anexo A.

O uso de parnteses pode ser feito para trocar a ordem de prioridade.


7. Funes e Subrotinas
(20.GT.10 .AND. 20.GT.25).OR.(10.LT.20 .AND. 10.LT.(3*10))
! .TRUE. Funes e subrotinas podem ser usadas para economizar espao e tempo de
programao j que podem ser usadas vrias vezes num mesmo programa. Outro ponto
6. Funes Intrnsecas importante que elas podem dar ao programa maior clareza, pois vrias seqncias de

Existem vrias funes predefinidas em FORTRAN, que podem ser usadas em clculos ou execues podem vir separadas do restante dos comandos.

qualquer parte do programa. O que d grande versatilidade s funes e subrotinas, so os argumentos passados a
elas, que quando variam produzem resultados diferentes. As funes e subrotinas podem vir
Funes Trigonomtricas
em qualquer parte do programa, mas o mais comum que apaream no fim (aps o end de
Nome Definio Tipo de Argumento Tipo da Funo
termino do programa), por motivo de clareza. As variveis e rtulos usados em funes e
SIN (x) seno (radianos). Se x for complexo, a parte real Real ou complexo. REAL*4
assumida como valor em radianos. subrotinas so locais e por isso devem ser declarados novamente, podendo ser usados os
ASIN (x) Arcoseno (radianos). Retorna valores na faixa [- Real, |x| .le. 1 REAL*4
/2, /2 ] mesmos nomes de variveis e rtulos de outras funes e subrotinas ou mesmo do programa
COS (x) Coseno (radianos) Se x for complexo, a parte real Real ou complexo REAL*4 principal. Os parmetros necessrios devem ser passados junto com a chamada da funo ou
assumida como valor em radianos.
ACOS (x) Arcocoseno (radianos) ) Retorna valores na faixa Real, |x| .le. 1 REAL*4 subrotina, devem vir entre parnteses e separados por virgula. Os nomes das variveis no
[ 0, ] precisam ser os mesmos na chamada e definio de uma funo ou subrotina, devendo
TAN (x) Tangente (radianos) Real REAL*4
ATAN (x) Arcotangente (radianos). Retorna valores na faixa Real REAL*4 apenas estar na mesma ordem.
[-/2, /2 ]
SINH (x) Seno Hiperblico (radianos) Real REAL*4 Funes
COSH (x) Coseno Hiperblico (radianos) Real REAL*4
TANH (x) Tangente Hiperblica (radianos) Real REAL*4 Retornam sempre um valor, e a ela podem ser passados qualquer nmero de
parmetros. As funes funcionam de forma semelhante s funes intrnsecas, com a
Programao em Linguagem FORTRAN .10. Programao em Linguagem FORTRAN .11.

diferena de que agora o programador que define o que a funo deve gerar como resultado. Chamada:
O tipo da funo deve ser declarado no programa principal, como se fosse uma varivel call nome_da_subrotina (lista_de_parmetros)
comum. Uma funo pode utilizar outras funes.
Definio:
Chamada:
subroutine nome_da_subrotina (lista_de_parmetros)
nome_da_funo(lista_de_parmetros) definio e declarao das variveis e constantes locais
seqncia de comandos
Definio: return
end
function nome_da_funo(lista_de_parmetros) A palavra chave return opcional.
definio e declarao das variveis e constantes locais
seqncia de comandos Exemplo:
return
end call converte_unidades ! chama a subrotina para converter as
A palavra chave return opcional, pode aparecer em qualquer ponto e mais de uma ! unidades
subroutine converte_unidades
vez. Ela indica que o comando deve retornar ao programa principal ou funo ou subrotina implicit none
que a chamou. real temp,press,n_mols,gas_ideal
T = temp + 273.15
A funo retornar o valor do ultimo comando do tipo: P = press*101325

nome_da_funo = expresso volume = gas_ideal(T,P,3) ! chama a funo com os valores


! corrigidos de T e P
Exemplo: end

volume = gas_ideal(T,P,3) ! volume recebe o valor gerado pela


! funo gas_ideal 8. Leitura e Impresso

function gas_ideal(temp,press,n_mols) Na maior parte dos programas preciso haver uma interao entre o programa e o
implicit none
usurio. Essa interao pode ser feita em FORTRAN pelos comandos de leitura e escrita de
real temp,press,n_mols,gas_ideal
gas_ideal = n_mols*8.314*temp/press dados. Esses comandos na sua forma mais simplificada possuem a seguinte estrutura:
return
end leitura :

read (unidade, formato) lista_de_parmetros


Subrotinas
impresso:
No retornam nenhum valor, e tambm a elas podem ser passados qualquer nmero de
parmetros inclusive nenhum. As subrotinas podem conter quaisquer tipos de comandos como write (unidade, formato) lista_de_parmetros
imprimir resultados, abrir arquivos (estes sero vistos frente, prximo item Leitura e
ou
Impresso) ou executar clculos. Como ocorrem com as funes, as subrotinas podem
print formato, lista_de_parmetros
chamar outras subrotinas ou funes.
Onde lista_de_parmetros representa os dados que sero impressos, e devem vir
separados por vrgula. Podendo conter variveis ou expresses alfanumricas, estas ltimas
devem vir entre apstrofos . unidade representa a unidade onde os dados sero impressos
ou de onde sero lidos; tela, teclado, impressora ou arquivo. formato pode conter uma lista
de formatos de impresso (prximo item, Formatos), um rtulo que indique um comando
Programao em Linguagem FORTRAN .12. Programao em Linguagem FORTRAN .13.

format (que contenha a lista de formatos) ou o smbolo * que indica impresso ou leitura de O FORTRAN no considera a primeira coluna da unidade de leitura e impresso
forma livre. quando a sada ou entrada formatada, por isso deve-se incluir uma casa de impresso em
branco a mais para dados. Para formato livre no necessrio pois o FORTRAN os posiciona
As unidades 6 e * se no forem definidas dentro do programa, sero consideradas
automaticamente.
como a tela do computador (write ou print). Da mesma forma as unidades 5 ou * so
definidas como o teclado (read). O comando print imprime sempre os resultados na Quando mais de um dado usar a mesma especificao, ela pode ser feita da seguinte
unidade definida por * ou na tela caso no haja nenhuma definio para de uma unidade forma: nespecificao1, n2especificao2 ou n(especificao1,
especificada pelo *. especificao2, ...), onde n e n2 representam o nmero de vezes que a especificao
ou seqncia de especificaes deve se repetir.
Na leitura os dados devem vir separados por espaos ou vir na linha seguinte. Caso se
tenham mais dados em uma linha do que os que sero lidos por um comando read eles Caso o nmero de especificaes seja menor que o de variveis a serem lidas ou
sero desprezados, inclusive pelo prximo comando read. Na escrita os dados viro um aps impressas, a ultima especificao ou a ultima seqncia, caso seja usado o recurso
os outros separados por espaos (no caso de strings viro sem espaos de separao), ou n(especificao1, especificao2, ...), ser repetida at que se complete o

na linha seguinte quando no houver mais espao. O prximo comando write ou print nmero necessrio. Isto no valido para constantes inclusas nos comandos de leitura e

comear a escrever na linha seguinte. impresso.

F90 para que se leia ou escreva dados na mesma linha mesmo aps mudar o comando Quando o nmero de especificaes maior que os de dados a serem impressos as

pode-se usar a opo advance=opcao no comando anterior. Onde opcao pode ser yes ultimas sero desprezadas.

ou no e indica se o comando deve ou no avanar automaticamente para a prxima linha. A forma de se declarar os formatos a seguinte:
So usados somente nos comandos read e write onde a opo formato no seja livre. r format (especificao1, especificao2, ...)
write (*,2,advance=no) Engenharia
onde r um numero inteiro, e representa o rtulo do format. Um mesmo format pode ser
write (*,2) Quimica
2 format(a) usado por vrios comandos de escrita e leitura.

10 format (2x,a,I) ! imprime 2 espaos em branco, uma


imprime: Engenharia Quimica ! string e um valor inteiro
a significa que ser impressa uma string de qualquer tamanho (item 9, Formatos). N77 o formato pode vir entre apstrofos e parnteses (esp.1, esp2,..), dentro do
Outras opes de impresso e leitura podem ser encontradas no Anexo B. prprio comando de impresso ou leitura.

print (esp.), var1


9. Formatos (leitura ou impresso) write (*, (esp.1,esp.2)) var1,var2
read (*, (esp.1,esp.2)) var1,var2
Os formatos servem para que os dados sejam impressos ou lidos de uma forma
As strings devem vir entre apstrofos duplos (string) nesse formato.
especfica, determinada pelo programador. Os formatos so compostos por uma seqncia de
especificaes que determinaro como os dados sero processados. Cada uma dessas
especificaes deve vir separada por vrgulas. Pode-se ainda imprimir constantes numricas e
alfanumricas, sendo que esta ltima deve vir entre apstrofos . O uso do * no lugar do
formato indica que todos os dados sero impresso ou lidos de forma livre, com o nmero de
casas especificado pelo prprio compilador. um recurso til para se evitar erros.
Programao em Linguagem FORTRAN .14. Programao em Linguagem FORTRAN .15.

belo horizonte
read (*, (a10)) nome => belo horiz
Formato Uso write (*, (a15)) nome => belo horiz
Iw[.m] Valores Inteiros
Fw.d Valores Reais F90 os valores dos campos podem ser variveis desde que venham entre <var1>. No
Ew.d[Ee] Valores Reais com expoente
Gw.d[Ee] Mesmo que Iw[.m], Ew.d[Ee], Lw e A[w] valido para print.
Dw.d Valores Reais de Dupla Preciso
Lw Valores Lgicos a = 5
A[w] Seqncia de Caracteres b = FORTRAN
N77 Zw_hexedit Valores Hexadecimais write (*,(a<a>)) b => FORTR
F90 Bw[.m] Valores Binrios
F90 Ow[.m] Valores Octadecimais Para valores numricos que precisam de mais casas de impresso que as indicadas no
F90 ENw.d[Ee] Valores Reais em Notao de Engenharia
F90 ESw.d[Ee] Valores Reais em Notao Cientifica format, sero impressos somente * naquele campo.
w representa o tamanho do campo a ser impresso ou lido, m representa o nmero de zeros
pi = 3.1416
que vir antes do nmero, d o nmero de casas decimais e e o nmero de casas para o print (1x,E7.3e2), pi => *******
expoente. print (1x,E8.3e2), pi => .314E+01

O ponto decimal, o e do expoente e o sinal - devem ser contados ao se dar o tamanho Outros Recursos Para Formatos
do campo (w). Ao ler um dado que no possui ponto decimal e no seu formato esperado um,
Alguns recursos adicionais so permitidos para read ou write.
o compilador ler este dado como se l houvesse um ponto.
Formato Uso
12345 string Transmite uma string para a sada
read (*,(f5.3)) a => a = 12.345 F90 Q A varivel recebe o nmero de espaos que o valor ocupa
nH Transmite os prximos n caracteres para a sada
Quando o ponto existe mas no est na posio especificada, a sua posio original Tc Move o ponto de leitura ou escrita para a posio c
TLc Move o ponto de leitura ou escrita c posies esquerda
mantida.
TRc Move o ponto de leitura ou escrita c posies direita
nX Deixa n posies em branco
12.345
read (*,(f5.4)) a => a = 12.345 SP Escreve o sinal + onde ele opcional
SS Omite o sinal + onde ele opcional
S Retorna ou padro ss
A notao com zeros m s vlida quando m maior que o nmero de casas que o
/ Muda de linha
nmero ocuparia no formato livre. N77 \ Comea a escrever no ponto onde a ultima escrita parou
N77 $ Comea a escrever no ponto onde a ultima escrita parou
a = 555 : Termina a impresso se no houver mais itens na lista
print (i5.4),a => 0555 kP O nmero multiplicado por 10 elevado -k (se o nmero j possuir expoente no h
efeito)
Nas notaes com expoente (ENw.d[Ee], ESw.d[Ee], ...) no se pode omitir o E ou e. BN Ignora os espaos em branco
BZ Transforma os espaos em branco em zeros
Sempre que houver este termo, a parte exponencial vai existir independente do seu valor.

a = 12.345
b = 12345.789e6 Antes ou depois de , , /, \, nH, $ ou : a vrgula opcional.
write (*,1) a,b
real a, b
1 format ( a=,e10.4e3, e b=,e10.4e3)
character dia*20
=> a=.1235E+002 e b=.1235E+011
a = 23.99
b = 55.8e-3
Caso as strings sejam maiores que o espao reservado a elas, sero tomados apenas dia = 'Segunda-feira'
os w primeiros caracteres. Se forem menores, elas sero alinhadas a direita e os outros write (*,'(5x,sp,e10.3e2,2x,en12.3e3)') a, b
write (*,'(/2x,''hoje e '',a8)') dia
espaos deixados em branco.
Programao em Linguagem FORTRAN .16. Programao em Linguagem FORTRAN .17.

produz o seguinte resultado: ou sero criados no mesmo diretrio em que estiver o programa a menos que se d como

+.240E+02 +55.800E-003 nome o caminho para um outro diretrio. Os caminhos seguem o mesmo padro do DOS.

hoje e Segunda- Um arquivo pode tambm ser fechado, isto far com que o FORTRAN coloque uma
marca de fim de arquivo naquele ponto, esta marca pode ser identificada por outro comando ou
funo (Anexos A e B).
10. Arquivos
close (unidade,status=estado)
Quando se deseja trabalhar com grandes quantidades de dados, o melhor armazen-
ou
los numa unidade de memria secundria, ou seja em arquivos. Um programa pode gerar
endfile unidade
tantos dados que todos eles no caberiam na tela de uma s vez, e ainda seriam perdidos ao
finalizar o programa. Os dados salvos em arquivos podem ser usados pelo prprio programa ou onde status=estado opcional. Estado pode ser keep que mantm o arquivo na
exportados para serem processados de outra forma. Arquivos de leitura economizam um tempo memria (este padro esta opo omitida), ou delete que apaga o arquivo da memria.
precioso para o usurio do programa pois ele no vai precisar enviar dados via teclado, e com
Arquivos fechados podem ser reabertos em qualquer parte do programa.
arquivos milhares de dados podem ser lidos em fraes de segundos.
Outros Recursos
O primeiro passo para se usar arquivos em FORTRAN indicar ao programa qual o
nome do arquivo e o nmero da unidade referente a ele. rewind unidade (volta o controle ao primeiro espao do arquivo)

open (unidade,file=nome.ext) backspace unidade (volta o controle um campo no arquivo)

onde unidade deve ser um inteiro maior ou igual a zero, e uma referncia a este arquivo. O Programa Arquivo arqui.dat
character *15a,b,c ' Qumica' ' Fsica'
nmero da unidade deve vir no comando read ou write indicando que os dados sero open(20,file='arqui.out') ' Engenharia'
retirados ou armazenados nesta unidade. A disposio dos dados em arquivos a mesma open(30,file='arqui.dat') Arquivo arqui.out
read (30,*) a este um
utilizada nas unidades de entrada e sada padro (Item 8, Leitura e Impresso), com uma nica write(20,*) ' este um ' arquivo de
diferena, as strings devem vir entre apstrofos . A abertura do arquivo pode ser feita em write(20,*) ' arquivo de ' sada
write(20,*) ' sada ' Qumica
qualquer parte do programa (inclusive dentro de funes e subrotinas), desde que venha antes read (30,*) b Engenharia Qumica
de um comando que o utilize. rewind 30
read (30,*) c
F90 o rtulo unidade pode ser uma string. write(20,*) a
write(20,*) b,c
Outras opes para abertura e fechamento de arquivos podem ser encontradas no end

Anexo B.

Apesar de se poder usar qualquer extenso de arquivo ou at omiti-la, as extenses


.dat para leitura e .out para sada so mais comumente encontradas.

Quando no for utilizado o comando open, alguns compiladores emitiro uma


mensagem na tela pedindo um nome, podendo o usurio escolher um nome diferente a cada
vez que o programa for executado. Em outros compiladores sero dados nomes padro como
fort.1, fort.2, etc para cada arquivo utilizado que no foi aberto. Todos os arquivos devem estar
Programao em Linguagem FORTRAN .18. Programao em Linguagem FORTRAN .19.

2. Comando GO TO ou GOTO
Captulo 2: Estruturas de Programao
O quando se deseja que o comando do programa avance ou recue em sua estrutura de
forma no seqencial, usa-se o comando goto ou go to.
1. Estrutura Seqencial
goto r
Os programas em FORTRAN devem conter os comandos escritos na ordem em que
sero executados, com exceo das funes, subrotinas e laos de repetio. Portanto um onde r um rtulo de uma linha que possui ou no um comando. Como uma linha rotulada no

programa em FORTRAN deve seguir o seguinte padro: pode estar em branco pode-se usar a palavra chave continue, que no ir interferir em nada
no programa.
declarao 1
declarao 2 Programa Resultado
... goto 20 linha 20
declarao n 10 write (*,*) ' linha 10' linha 30
comando 1 20 write (*,*) ' linha 20'
comando 2 30 write (*,*) ' linha 30'
... end
comando n goto 1 linha 20
end 10 write (*,*) ' linha 10' linha 30
1 continue
20 write (*,*) ' linha 20'
onde as declaraes so opcionais (item 4 Captulo 1). 2 continue
30 write (*,*) ' linha 30'
O comando end indica o fim do programa. Se o programador preferir pode finalizar o end
programa prematuramente usando os comandos stop ou call exit.
3. Estrutura Condicional
Programa Resultado
integer*1 a,b 10
a=10 20 Estrutura Condicional Simples
b=20 30.000000
c=30 if (expresso de teste) comando
write (*,*) a
write (*,*) b ou
write (*,*) c
end
if (expresso de teste) then
integer*1 a,b 10
a=10 20 seqncia de comandos
b=20 end if
c=30
write (*,*) a Quando a expresso de teste for verdadeira os comandos sero executados, quando
write (*,*) b
stop for falsa o programa segue para o prximo comando logo abaixo da estrutura condicional. A
write (*,*) c primeira opo s valida quando for executado um nico comando. Este comando pode ser
end
integer*1 a,b 10 de qualquer tipo, atribuio, escrita, leitura, goto ou interrupo do programa.
a=10
b=20 Estrutura Condicional Composta
c=30
write (*,*) a if (expresso de teste) then
call exit
seqncia de comandos 1
write (*,*) b
write (*,*) c else
end seqncia de comandos 2
end if
Programao em Linguagem FORTRAN .20. Programao em Linguagem FORTRAN .21.

Quando a expresso de teste for falsa a seqncia de comandos 2 ser executada. As listas de seleo podem ser da seguinte forma:
Mesmo quando s h um comando na seqncia de comandos 1, no se pode omitir a palavra Estrutura Condio para ser verdadeira
chave then. case (valor) Exp. teste igual valor
case (:valor) Exp. teste menor que valor
case (valor:) Exp. teste maior que valor
permitido o uso de estruturas condicionais umas dento das outras.
case (valor1:valor2) Exp. teste entre valor1 e valor2
case (valor1,valor2,...,valorn) Exp. teste igual valor1 ou igual valor2 ou ... valorn.
Programa Resultado
implicit integer (a-z) a<b
a=10 c= 30 30 20
b=20 No permitida a superposio de valores.
c=30
if (a.lt.b) then Os valores literais devem vir entre apstrofos e seus valores sero avaliados de acordo
write (*,*) ' a<b'
a=b+10 com o padro ASCII. Uma tabela com os valores ASCII pode ser encontrada no Anexo C.
else
write (*,*) ' a>b' Programa Resultado
b=a-5 i=20 a=20
end if select case (i)
if (c.ge.20) write(*,*)' c=',c, a, b case (10)
end write (*,*) 'a=10'
case (20)
write (*,*) 'a=20'
case (11,19)
Estrutura Condicional Composta Simplificada write (*,*) 'a>11 a<19'
end select
Uma outra forma de se usar uma estrutura condicional composta (somente N77 e F90) end
character i*1 i esta entre d e m
usando o comando case. i='h'
valor_i: select case (i)
N77 F90 case ('a','b','c')
SELECT CASE (exp. case) nome_case: SELECT CASE (exp. case) write (*,*) 'i=a ou b ou c'
CASE (lista de seleo 1) CASE (lista de seleo 1) case ('d':'m')
comandos 1 comandos 1 write (*,*) 'i esta entre d e m'
CASE (lista de seleo 2) CASE (lista de seleo 2) case ('D':'M')
comandos 2 comandos 2 write (*,*) 'i esta entre D e M'
... ... end select valor_i
CASE (lista de seleo n) CASE (lista de seleo n) end
comandos n comandos n
CASE DEFAULT CASE DEFAULT importante observar que as letras maisculas e minsculas possuem valores ASCII
comandos d comandos d
END SELECT END SELECT nome_case diferentes.

onde exp. case' uma expresso ou constante inteira, lgica ou literal (somente um 4. Estruturas de Repetio
caractere character*1). Caso o valor de exp. case estiver na lista de seleo 1, os
Quando o mesmo comando precisa ser executado vrias vezes at que se atinja uma
comandos 1 sero executados. Se o valor no estiver na lista de seleo 1 o
certa condio ou um nmero certo de repeties, o melhor usar as estruturas de repetio.
computador ir avaliar a lista de seleo 2, se for verdadeira sero executados os
Estas estruturas so bem simples e podem economizar vrias linhas de comando.
comandos 2 e assim at terminar os comandos case (lista de seleo n). O
comando case default opcional, e faz com que os comandos d sejam executados caso Estruturas de Repetio Simples

nenhuma das outras avaliaes sejam verdadeiras. nome_case opcional e deve seguir as r1 if (condio_de_teste) goto r2
comandos
mesmas regras usadas para dar nomes as variveis. A sua utilidade apenas de dar maior goto r1
clareza ao programa. r2 continue
Programao em Linguagem FORTRAN .22. Programao em Linguagem FORTRAN .23.

Esta uma estrutura de repetio muito simples, mas no recomendada para Programa Resultado
integer i/1/, j/1/ 2 1
programao. Estruturas mais aceitas, pois possuem equivalentes em outras linguagens, so do while (i) 3 1
da seguinte forma: j=j+1 4 1
if(j.eq.5) i=0 5 0
print *,j,i
do r1 var=n1,n2,n3 end do
seqncia de comandos end
r1 continue real*8 a(4) +2.97646E+000
i = 1; a(1) = 2.97645984 ---------------
ou a(2) = 576.74e5 +57.67400E+006
a(3) =.45; a(4) = sin(.5) ---------------
N77 - do var=n1,n2,n3 do while(i.le.4) +449.99999E-003
seqncia de comandos print'(2x,sp,en16.5e3)', a(i) ---------------
end do write (*,*)' ---------------' +479.42554E-003
i = i + 1 ---------------
end do
'var uma varivel inteira ou real que recebe inicialmente o valor n1, a seqncia de end
comandos se repete, e o valor de var aumenta de n3 a cada vez que o comando volta para do i=9,12 09
print '(2x,I2.2)',i 10
a linha do do. A repetio s para quando o valor de var ultrapassa n2. enddo 11
end 12
Caso o programa exija uma contagem regressiva o valor de n3 deve ser negativo e n1
maior que n2.
DO Implcito (WIN)
A palavra chave end do pode ser escrita como enddo. n1, n2 e n3 podem ser
Nos comandos read e write possvel usar uma estrutura de repetio semelhante
constantes ou variveis inteiras ou reais, positivas ou negativas. Quando n3 for igual a um ele
ao DO, mas de forma implcita e mais simplificada.
pode ser omitido.
read(unidade,formato)(lista_de_parmetros, var=n1,n2,n3)
DO WHILE (F90)
Onde var=n1,n2,n3 tem o mesmo significado que na estrutura DO. Podem ser
Uma forma de se usar uma expresso de teste no comando do, o uso do do
usadas vrias estruturas deste tipo em um mesmo read ou write desde que venham separadas
while. por parnteses. Quando impressos desta forma, os dados ficam na mesma linha. Para leitura
do while(exp. teste) eles podem vir na seqncia correta na mesma linha ou em linhas diferentes. Os parmetros
seqncia de comandos
em formato sero usados at que se atinja o seu final, quando isto acontecer o comando muda
end do
de linha e os formatos so usados novamente desde o comeo.
Enquanto exp. teste for verdadeira a seqncia de comandos ser executada.

Programa Resultado
real*8 a,b 1.000000000000000 Programa Resultado
a=0 9.921976672293290E-001 integer a(5,3), b(3) 11 - 21 - 31
b=0 9.689124217106447E-001 do i=1,5 41 - 51 - 101
1 if(a.lt.0) goto 2 9.305076219123143E-001 do j=1,3 12 - 22 - 32
a=cos(b) 8.775825618903728E-001 a(i,j)=10*i+j 42 - 52 - 108
b= b+.125 8.109631195052179E-001 b(j)=100+j**3 13 - 23 - 33
write (*,*) a 7.316888688738209E-001 enddo 43 - 53 - 127
goto 1 6.409968581633251E-001 enddo
2 continue 5.403023058681398E-001 write (*,1) ((a(i,j), i=1,5) &
end 4.311765167986662E-001 & ,b(j), j=1,3)
3.153223623952687E-001 1 format ( 2x,i4,' - ',i5,' - ',i4)
1.945477079889872E-001 end
7.073720166770291E-002
-5.417713502693632E-002
Programao em Linguagem FORTRAN .24. Programao em Linguagem FORTRAN .25.

Programa Resultado
Captulo 3: Recursos de Programao i=1
10 if(i-2) 1,2,3
i<2
i=2
1 write (*,*) ' i<2' i>2
i=2
1. Deslocamento goto 10
2 write (*,*) ' i=2'
i=3
GOTO Implcito goto 10
3 write (*,*) ' i>2'
Outra forma de usar o goto a seguinte: end

goto (r1, r2, ..., rn) varivel


2. Declaraes e Atribuies Avanadas
Onde varivel uma varivel ou expresso inteira que deve ter valor mximo igual
DIMENSION
ao nmero de rtulos que esto dentro dos parnteses. Quando esta varivel tiver valor 1 o
comando do programa vai para a linha rotulada com r1, quando tiver valor 2 vai para a linha Uma outra forma de se declarar vetores e matrizes, com a vantagem de se poderem
com o rtulo r2, e assim por diante. Se o valor de varivel for maior que o nmero de rtulos o especificar os ndices mnimos e mximos em cada direo usando o comando dimension.
comando do programa vai para a linha imediatamente abaixo do goto. tipo var1,var2,...,varn
dimension var1(Li1:Ls1), var2(Li2:Ls2),..., varn(Lin:Lsn)
Programa Resultado
i=2 o valor de i=2
goto (10,20,15) i ou
10 write (*,*) ' o valor de i=1'
goto 1 tipo var1(Li1:Ls1), var2(Li2:Ls2), ...,varn(Lin:Lsn)
20 write (*,*) ' o valor de i=2'
go to 1 tipo pode ser qualquer tipo de varivel inteira, real, lgica, complexa ou literal. Li1, Li2,..., Lin
15 write (*,*) ' o valor de i=3'
1 continue so os ndices inferiores, e Ls1, Ls2,..., Ln so os ndices superiores da matriz ou vetor. Os
end
valores de Li e Ls podem ser positivos, nulos ou negativos desde que sejam inteiros. Quando o
valor de Li omitido, o valor um usado como padro. As variveis podem ter duas ou mais
IF Com Deslocamento dimenses, sendo declaradas da mesma forma, com cada dimenso separada das outras por

Uma outra maneira de se deslocar num programa, usando agora um comando if a vrgulas.

seguinte: var(Li1:Ls1, Li2:Ls2, ...,Lin:Lsn)

if (exp. numrica) r1,r2,r3 Programa Resultado


integer a a(-03,+01)=-03
exp. numrica no pode ser complexa. r1, r2, r3 so rtulos. Se o valor de exp. dimension a(-3:1,3) a(-03,+02)=+09
do i=-3,1 a(-03,+03)=-27
numrica for menor que zero o comando vai para a linha com o rtulo r1, quando for igual a do j=1,3 a(-02,+01)=-02
a(i,j)=i**j a(-02,+02)=+04
zero o comando vai para linha com o rtulo r2 e quando for maior que zero vai para r3. print 1,'a(',i,',',j,')=',a(i,j) a(-02,+03)=-08
1 format(1x,sp,a,i3.2,a,i3.2 & a(-01,+01)=-01
A exp. numrica pode ser uma expresso que gere como valores 0 (zero) que ser ,a,i3.2) a(-01,+02)=+01
enddo a(-01,+03)=-01
considerado como .false. ou qualquer nmero diferente de 0 (zero) que ser considerado enddo a(+00,+01)=+00
como .true.. end a(+00,+02)=+00
a(+00,+03)=+00
a(+01,+01)=+01
a(+01,+02)=+01
a(+01,+03)=+01
Programao em Linguagem FORTRAN .26. Programao em Linguagem FORTRAN .27.

PARAMETER nome_type o nome do bloco, e deve seguir as mesmas regras para nomes de variveis.
declaraes so declaraes de variveis (tipo varivel). Este bloco pode ser usado
Uma constante pode ser representada por um smbolo no lugar do seu valor, ou seja o
vrias vezes, associando cada novo grupo um nome. O bloco com esse novo nome ter as
valor de , por exemplo, pode ser sempre que preciso referenciado como pi, no lugar de se
mesmas variveis feitas na declarao.
escrever sempre 3.14159. Bastando para isso o uso do comando parameter. A diferena
Associao:
entre um valor com parameter e uma varivel comum que com parameter o valor no
pode ser modificado em nenhuma parte do programa ou ser lido atravs de um comando type (nome_type) :: nome

read. O tipo da constante deve ser especificado antes ou sero usadas s atribuies Atribuio:
implcitas (item 4 Captulo 1).
nome = nome_type (valor das variveis)
tipo constante1, constante2,...
parameter ( constante1 = valor, constante2 = valor,...) ou

Os parnteses so opcionais. tipo pode ser integer, real ou qualquer outro tipo nome%nome_varivel = valor

de varivel. Em parameter no se podem declarar vetores e matrizes. Programa Resultado


type anivers Fevereiro
F90 Uma forma simplificada de se atribuir o valor e o tipo da constante feito da seguinte character nome*10 Helder 17
character mes*10 Carlo 12
forma. integer*1 dia Keila Agosto 22
end type anivers
tipo , parameter :: constante1=valor, constante2=valor,... type (anivers) :: helder
type (anivers) :: keila
Programa resultado type (anivers) :: carlo
real pi,r(3),a real pi,r(3) 6.291800 helder=anivers('Helder','Fevereiro',17)
parameter (pi=3.1459) parameter (pi=3.1459) 25.167200 carlo=anivers('Carlo','Fevereiro',12)
do i=1,3 do i=1,3 56.626200 keila %nome='Keila'
r=i**2 r=i**2 keila %mes='marco'
a=area(r(i),pi) call area(r(i),pi) keila%dia=24
print *,a enddo write(*,*) helder%mes
enddo end write(*,*) helder%nome,helder%dia
end write(*,*) carlo%nome,carlo%dia
subroutine area(r,pi) write(*,'(1x,a,a,i2)') keila
function area(r,pi) real r,a end
real r,area a=2*pi*r
area=2*pi*r print *,a
return return DATA
end end
O modo mais estruturado de se atribuir valores iniciais a variveis pelo comando
TYPE (F90) data. As diferenas entre o data e parameter que as variveis declaradas em data
podem alterar seu valor durante o programa, e essas variveis podem ser vetores ou matrizes.
Quando vrias variveis esto relacionadas entre si, o melhor agrup-las em grupos
type, de forma que possam ser acessadas pelo nome do grupo. Este um recurso data var1/valor1/,var2/valor2/,...,varn/valorn/

semelhante programao orientada a objetos. ou

Declarao: data var1,var2,...,varn/valor1,valor2,...,valorn/

type nome_type Os valores de vetores e matrizes devem ser declarados todos de uma vez, com a
declaraes
end type nome_type separao entre eles feita por vrgula.
Programao em Linguagem FORTRAN .28. Programao em Linguagem FORTRAN .29.

Programa Resultado Programa Resultado


integer h(3,4),a,b,c 010203040506 common /func/a,b 12.000
logical l1,l2 070809101112 common / /c,d 2.000
character cor*5 05 03 10 common e,f 4.000
data h/1,2,3,4,5,6,7,8,9,10,11,12/ T F data a,b/1,2/
data a/5/,b/3/,c/10/ preto c=3;d=4;e=5
data l1,l2,cor/.true.,.false.,'preto'/ f=funcao(4)
print '(2x,6i2.2,/,2x,6i2.2)',h call subrotina(5)
print '(2x,3(i2.2,2x))',a,b,c end
print '(2x,l7,2x,l7)',l1,l2
print *,cor ! funes e subrotinas
end function funcao(t)
common /func/a,b
a=a*2
3. Designao de Memria funcao=t+a+b
return
end
COMMON
subroutine subrotina(r)
Quando muitos dados devem ser passados a funes ou subrotinas, um recurso til o common /func/a,b
common c,d,e,f
common, que pode resumir este servio. Um mesmo common pode ser usado vrias vezes e r=r+c+d+e
carregar muitas variveis ao mesmo tempo. Este comando deve aparecer de forma igual no print '(3(2x,f6.3,/))',r,a,f
return
incio do programa principal (logo aps a definio dos tipos de variveis) e tambm no incio end
de cada funo ou subrotina que o utilize.

common /nome/lista de variveis/nome2/lista de variveis2,... BLOCK DATA

O nome do bloco opcional, e se for repetido, as variveis sero agrupadas em um As variveis declaradas em um common com nome podem receber valores iniciais de
mesmo bloco. A ausncia do nome e o nome / / tm o mesmo significado. As variveis de um uma forma mais estruturada. No block data podem ser usados os seguintes recursos:
common sem nome no podem ser declaradas pelo comando data. Uma mesma varivel common(com nome), parameter, data, dimension e variveis derivadas de um type.
no pode ocupar mais de um comando common. block data nome_bloco
declaraes e atribuies
A ordem em que as variveis aparecem no common devem ser iguais em qualquer parte end
do programa, apesar de seus nomes poderem variar de uma subrotina ou funo para outras.
O nome_bloco opcional e deve seguir as mesmas regras para nomes de variveis.
Na declarao de um common recomendvel que se siga uma ordem crescente do
tamanho das variveis. O tamanho de uma varivel dado pelo nmero de bites que ela
4. Modularizao
ocupa. A seqncia para essa declarao : logical, character, integer, real, vetores e matrizes.
As matrizes e vetores devem seguir esta mesma seqncia de tamanhos (vetores logical, INCLUDE
vetores character, ...). As strings so consideradas vetores de caracteres.
Declaraes, atribuies, common e outros comados que estejam em um arquivo de
Alguns compiladores apenas mostraro mensagens de advertncia quando est texto com o mesmo formato usado no programa podem ser adicionados ao programa principal
seqncia estiver incorreta, outros no avaliam esta ordem e consideram como corretas atravs do comando include. Esses arquivos podem ser adicionados a outros arquivos
quaisquer ordem em que as variveis aparecerem. include ao programa principal e a funes e subrotinas. O mesmo arquivo pode ser usado
vrias vezes. Os arquivos sero interpretados como parte do programa, e por isso devem
seguir as mesmas regras do programa normal escrito em FORTRAN.
Programao em Linguagem FORTRAN .30. Programao em Linguagem FORTRAN .31.

include nome.ext
Anexo A: Funes Intrnsecas
ou

include nome.ext 1. Funes Trigonomtricas

Nome e extenso podem ser qualquer um, mas a extenso .inc a mais comum para Nome Definio Parmetro Resultado
SIN (X) seno (radianos). se x for real ou complexo. real*4
este tipo de arquivo. permitido o uso de caminhos completos no lugar do nome. complexo, a parte real
assumida como valor em
radianos.
SIND (X) seno (graus se x for real ou complexo real*4
complexo, a parte real
assumida como valor em
graus.
CSIN (X) seno (radianos) complex*4 complex*4
CDSIN (X) seno (radianos) complex*8 complex*8
DSIN (X) seno (radianos) real*8 real*8
DSIND (X) seno (graus) real*8 real*8
ASIN (X) Arcoseno (radianos). retorna real, |x| .le. 1 real*4
valores na faixa [-/2, /2 ]
ASIND (X) Arcoseno (graus) retorna real |x| .le. 1 real*4
valores na faixa [-90, 90 ]
DASIN (X) Arcoseno (radianos). retorna real*8 real*8
valores na faixa [-/2, /2 ]
DASIND (X) Arcoseno (graus) retorna real*8 real*8
valores na faixa [-90, 90 ]
COS (X) coseno (radianos) se x for real ou complexo real*4
complexo, a parte real
assumida como valor em
radianos.
COSD (X) coseno (graus) se x for real ou complexo real*4
complexo, a parte real
assumida como valor em
graus.
CCOS (X) coseno (radianos) complex*4 complex*4
CDCOS (X) coseno (radianos) complex*8 complex*8
DCOS (X) coseno (radianos) real*8 real*8
DCOSD (X) coseno (graus) real*8 real*8
AOS (X) Arcocoseno (radianos) ) real, |x| .le. 1 real*4
retorna valores na faixa [ 0,
]
ACOSD (X) Arcocoseno (graus) retorna real, |x| .le. 1 real*4
valores na faixa [ 0, 180 ]
DACOS (X) Arcocoseno (radianos) ) real*8, |x| .le. 1 real*8
retorna valores na faixa [ 0,
]
DACOSD (X) Arcocoseno (graus) ) retorna real*8, |x| .le. 1 real*8
valores na faixa [ 0, 180 ]
TAN (X) tangente (radianos) real real*4
TAND (X) tangente (graus) real real*4
DTAN (X) tangente (radianos) real*8 real*8
DTAND (X) tangente (graus) real*8 real*8
COTAN (X) cotangente (radianos) real. x no pode ser 0. real*4
DCOTAN (X) cotangente (radianos) real*8. x no pode ser 0. real*8
Programao em Linguagem FORTRAN .32. Programao em Linguagem FORTRAN .33.

Nome Definio Parmetro Resultado


ATAN (X) Arcotangente (radianos). ) real real*4
retorna valores na faixa [- 3. Exponenciais
/2, /2 ]
ATAND (X) Arcotangente (graus). ) real real*4 O nmero e elevado a X (eX )
retorna valores na faixa [-90,
90 ] Nome Parmetro Resultado
DATAN (X) Arcotangente (radianos). real*8 real*8 CDEXP (X) complex*16 complex*16
retorna valores na faixa [- CEXP (X) complex*8 complex*8
/2, /2 ] DEXP (X) real*8 real*8
DATAND (X) Arcotangente (graus). real*8 real*8 EXP (X) real, inteiro ou complexo mesmo que o parmetro
retorna valores na faixa [-90,
90 ]
ATAN2 (Y,X) Arcotangente (y / x) em real. x e y no podem real*4 4. Logaritmos
radianos. retorna valores na ambos ser 0.
faixa [-, ]
Nome Definio Parmetro Resultado
ATAN2D (Y,X) Arcotangente (y / x) em real. x e no podem ambos real*4 LOG (X) logaritmo natural real ou complexo mesmo que o
graus. retorna valores na ser 0. parmetro
faixa [-180, 180 ] ALOG (X) logaritmo natural real*4 real*4
DATAN2 (Y,X) Arcotangente (y / x) em real*8 x e y no podem real*8
DLOG (X) logaritmo natural real*8 real*8
radianos retorna valores na ambos ser 0.
CLOG (X) logaritmo natural complex*8 complex*8
faixa [-, ])
CDLOG (X) logaritmo natural complex*16 complex*16
DATAN2D (Y,X) Arcotangente (y / x) em real*8 x e y no podem real*8
LOG10 (X) logaritmo na base 10 real mesmo que o
graus. retorna valores na ambos ser 0.
parmetro
faixa [-180, 180 ]
ALOG10 (X) logaritmo na base 10 real*4 real*4
SINH (X) seno hiperblico (radianos) real real*4
DLOG10 (X) logaritmo na base 10 real*8 real*8
DSINH (X) seno hiperblico (radianos) real*8 real*8
COSH (X) coseno hiperblico real real*4
(radianos) 5. Mximos
DCOSH (X) coseno hiperblico real*8 real*8
(radianos)
TANH (X) tangente hiperblica real real*4 Nome Definio Parmetro Resultado
(radianos) MAX(X1,X2,..) maior valor qualquer tipo maio tipo entre os
DTANH (X) tangente hiperblica real*8 real*8 valores
(radianos) MAX0(X1,X2,..) maior valor inteiro inteiro
AMAX1(X1,X2,..) maior valor real real
AMAX0(X1,X2,..) maior valor inteiro real
2. Funes Genricas MAX1(X1,X2,..) maior valor real inteiro
DMAX1(X1,X2,..) maior valor real*8 real*8
Nome Definio Parmetro Resultado
DPROD(A,B) a*b real*4, real*4 real*8 6. Mnimos
EOF(UNIT) verifica o final da unidade integer*2 logical
unit
SIGN(X,Y) retorna x com o sinal de y real ou inteiro real ou inteiro Semelhante as funes de mximo (MIN, MIN0, AMIN1, AMIN0, MIN1, DMIN1)
ISIGN(X,Y) retorna x com o sinal de y inteiro inteiro
DSIGN(X,Y) retorna x com o sinal de y real*8 real*8

7. Restos

Resto da diviso de X por Y

Nome Parmetro Resultado


MOD(X,Y) real ou inteiro real ou inteiro
AMOD(X,Y) real*4 real*4
DMOD(X,Y) real*8 real*8
Programao em Linguagem FORTRAN .34. Programao em Linguagem FORTRAN .35.

8. Raiz Quadrada de X 13. Transformao do Tipo de X

Nome Parmetro Resultado Nome Parmetro Resultado


SQRT(X) real ou complexo real ou complexo INT(X) real, inteiro ou complexo inteiro
DSQRT(X) real*8 real*8 INT1(X), INT2(X), INT4(X), real, inteiro ou complexo integer*1, integer*2, integer*4, c
CSQRT(X) complex*8 complex*8 INTC(X) integer
CDSQRT(X) complex*16 complex*16 IFIX(X) real*4 inteiro
HFIX(X) real, inteiro ou complexo integer*2
JFIX(X) real, inteiro ou complexo integer*4
9. Truncamento de X IDINT(X) real*8 inteiro
REAL(X) real, inteiro ou complexo real*4
Nome Parmetro Resultado DREAL(X) complex*16 real*8
AINT(X) real real FLOAT(X) inteiro real*4
SNGL(X) real*8 real*4
DINT(X) real*8 real*8
DBLE(X) real*8 ou complexo real*8
DFLOAT(X) real*8 ou complexo real*8
10. Arredondamento de X CMPLX(X) inteiro, real, complexo complexo
DCMPLX(X) inteiro, real, complexo complex*16
ICHAR(X) ASCII inteiro
Nome Parmetro Resultado CHAR(X) integer*4 ASCII
NINT(X) real inteiro
DNINT(X) real*8 real*8
ANINT(X) real real 14. Complexos
IDNINT real*8 inteiro
Nome Definio Parmetro Resultado
11. Diferena Positiva Entre X e Y IMAG(X) retorna a parte complexo real
imaginria
DIMAG(X) retorna a parte complex*16 real*8
( se Y > X o valor zero) imaginria
AIMAG(X) retorna a parte complex*8 real*4
Nome Parmetro Resultado imaginria
DIM(X,Y) real ou inteiro real ou inteiro
CONJG(X) retorna o complexo complex*8 complex*8
DDIM(X,Y) real*8 real*8
DIM(X,Y) inteiro inteiro conjugado
DCONJG(X) retorna o complexo complex*16 complex*16
conjugado
12. Tipo de Dado
15. Caracteres
Nome Definio Parmetro Resultado
ALLOCATED(X) .true. se a for vetor ou todos lgico
Nome Definio Parmetro Resultado
matriz
LEN(X) tamanho de x character inteiro
EPSILON(X) menor valor que pode real real
LGE(X,Y) compara x e y se x >= y .true. character logical
ser incrementado
LGT(X,Y) compara x e y se x > y .true. character logical
HUGE(X) maior valor possvel real ou inteiro real ou inteiro
LLE(X,Y) compara x e y se x <= y .true. character logical
MAXEXPONENT(X) maior expoente real real
LLT(X,Y) compara x e y se x < y .true. character logical
possvel
INDEX(X,Y) procura y em x e retorna a posio character inteiro
MINEXPONENT(X) menor expoente real real
LEN_TRIM(X) tamanho de x menos o nmero de character inteiro
possvel
espaos
NEAREST(X,Y) se y positivo retorna real real
SCAN(X,Y) procura um dos caracteres de y em x e character inteiro
o maior real se
negativo o menor real retorna o nmero de ocorrncias
PRECISION(X) nmero de casas real real VERIFY(X,Y) procura um dos caracteres de y em x e character inteiro
retorna a posio da primeira no
decimais
ocorrncia
TINY(X) menor valor positivo real real
que pode ser
armazenado
Programao em Linguagem FORTRAN .36. Programao em Linguagem FORTRAN .37.

16. Valores Absolutos de X


Anexo B: Opes de Arquivos, Leitura
Nome Parmetro Resultado
ABS(X)
IABS(X)
complexo ou real
inteiro
complexo ou real
inteiro
e Escrita
DABS(X) real*8 real*8 As opes contidas aqui foram baseadas no compilador FORTRAN Visual Workbrench
CABS(X) complex*16 complex*16
CDABS(X) complex*16 real*8 v 1.00. Outros compiladores possuem outros nomes para estas opes, e podem possuir
outras alem destas.

Os valores absolutos dos dados complexos so calculados pela seguinte As opes entre colchetes so opcionais. Elas podem vir em qualquer ordem, exceto

formula: (real ) 2
+ (imag )
2 quando explicitado.

1. Abertura de Arquivos (OPEN)

OPEN ([UNIT=]unit [ , ACCESS=access] [ , BLANK=blanks]


[ , BLOCKSIZE=blocksize] [ , ERR=errlabel] [ , FILE=file]
[ , FORM=form] [ , IOSTAT=iocheck] [ , MODE=mode]
[ , RECL=recl] [ , SHARE=share] [ , STATUS=status])

UNIT= - Quando omitido, o primeiro valor ser o nmero da unidade (unit).

unit Expresso inteira. Indica o nmero da unidade.

access Expresso alfanumrica. APPEND , DIRECT ou SEQUENTIAL (padro, quando


access omitido)

blanck Expresso alfanumrica. NULL ignora zeros e espaos, ZERO espaos so


substitudos por zeros. Os formatos BN e BZ podem anular este efeito.

blocksize Expresso inteira. Especifica o tamanho da unidade (em bytes).

errlabel Expresso inteira. Indica o rtulo de uma linha no mesmo arquivo para onde o
comando vai se houver erro. Quando omitido o efeito determinado pela presena ou no de
iocheck.

file Expresso alfanumrica. Indica o nome do arquivo. Quando omitido o programa pede ao
usurio um nome.

form Expresso alfanumrica. FORMATED (padro quando access=SEQUENTIAL),


UNFORMATED (padro quando access=DIRECT), BINARY.

iocheck Varivel inteira. Retorna zero quando no ocorre erros, retorna um nmero negativo
se encontrar a marca de fim de arquivo (EOF), retorna o nmero do erro quando um ocorre.

mode Expresso alfanumrica. READ o arquivo s para leitura, WRITE o arquivo s


para escrita, READWRITE o arquivo pode ser usado para leitura ou escrita.
Programao em Linguagem FORTRAN .38. Programao em Linguagem FORTRAN .39.

recl Expresso inteira. Representa o tamanho de cada dado em bytes. obrigatrio para errlabel Expresso inteira. Indica o rtulo de uma linha no mesmo arquivo para onde o
access=DIRECT. comando vai se houver erro. Quando omitido o efeito determinado pela presena ou no de
iocheck.
share Expresso alfanumrica. DENYRW ignora mode=READWRITE, DENYWR ignora
mode=WRITE, DENYRD ignora mode=READ, DENYNONE ignora qualquer mode, iocheck Varivel inteira. Retorna zero quando no ocorre erros, retorna o nmero do erro
quando um ocorre.
status Expresso alfanumrica. OLD indica que o arquiva j existe, NEW indica que o
arquivo deve ser criado, UNKOWN (padro) verifica a existencia do arquivo, se ele no existir rec Expresso inteira. Indica a posio do arquivo onde o dado ser impresso. Somente para
ser criado um, SCRATHC arquivos com access=DIRECT.

iolist Lista de variveis serem impressas.


2. Fechamento de Arquivos (CLOSE)

CLOSE ( [UNIT=] unit [,ERR=errlabel] [,IOSTAT=iocheck] 4. Leitura (READ)


[,STATUS=status] )
READ { { format, | nml } | ([UNIT=]unit [ , [ {[FMT=] format] |
UNIT= - Quando omitido, o primeiro valor ser o nmero da unidade (unit). [NML=]nmlspec}] [ , END=endlabel] [ , ERR=errlabel] [ , IOSTAT=iocheck]
[, REC=rec])} iolist
unit Expresso inteira. Indica o nmero da unidade.
UNIT= - Quando omitido, o primeiro valor ser o nmero da unidade (unit). Se FMT= ou NML=
errlabel Expresso inteira. Indica o rtulo de uma linha no mesmo arquivo para onde o
forem omitidos, format ou nml devem ser o segundo parmetro.
comando vai se houver erro. Quando omitido o efeito determinado pela presena ou no de
unit Expresso inteira. Indica o nmero da unidade.
iocheck.
format Expresso inteira. Indica o rtulo de um comando format. Expresso alfanumrica.
iocheck Varivel inteira. Retorna zero quando no ocorre erros, retorna um nmero negativo
Expresso que contenha os formatos de leitura.
se encontrar a marca de fim de arquivo (EOF), retorna o nmero do erro quando um ocorre.
nml Lista de variveis serem lidas, se estiver presente iolist deve ser omitida.
status Expresso alfanumrica. KEEP indica que o arquiva deve ser mantido, DELETE
indica que o arquivo deve ser apagado. endlabel Expresso inteira. Indica o rtulo de uma linha no mesmo arquivo para onde o
comando vai se a marca de fim de arquivo (EOF) for encontrada.

3. Escrita (WRITE) errlabel Expresso inteira. Indica o rtulo de uma linha no mesmo arquivo para onde o
comando vai se houver erro. Quando omitido o efeito determinado pela presena ou no de
WRITE ([UNIT=] unit [ , [{[ FMT=] format] | [ NML=] nml }]
iocheck.
[ , ERR=errlabel] [ , IOSTAT=iocheck] [ , REC=rec] ) iolist
iocheck Varivel inteira. Retorna zero quando no ocorre erros, retorna 1 se encontrar EOF,
UNIT= - Quando omitido, o primeiro valor ser o nmero da unidade (unit). Se FMT= ou NML=
retorna o nmero do erro quando um ocorre.
forem omitidos, format ou nml devem ser o segundo parmetro.
rec Expresso inteira. Indica a posio do arquivo de onde o dado ser lido.
unit Expresso inteira. Indica o nmero da unidade.
iolist Lista de variveis serem lidas.
format Expresso inteira. Indica o rtulo de um comando format. Expresso alfanumrica.
Expresso que contenha os formatos de impresso.

nml Lista de variveis serem impressas, se estiver presente iolist deve ser omitida. 5. Recuo Total (REWIND)

REWIND { unit | ([UNIT=]unit [ , ERR=errlabel] [ , IOSTAT=iocheck])}


Programao em Linguagem FORTRAN .40. Programao em Linguagem FORTRAN .41.

UNIT= - Quando omitido, o primeiro valor ser o nmero da unidade (unit).

unit Expresso inteira. Indica o nmero da unidade.


Anexo C: Tabela de Valores ASCII
Valor ASCII Caracter Correspondente
errlabel Expresso inteira. Indica o rtulo de uma linha no mesmo arquivo para onde o
comando vai se houver erro. Quando omitido o efeito determinado pela presena ou no de
iocheck.

iocheck Varivel inteira. Retorna zero quando no ocorre erros, retorna o nmero do erro
quando um ocorre.

6. Recuo de um Campo (BACKSPACE)

BACKSPACE {unit|( [UNIT=] unit [,ERR=errlabel] [,IOSTAT=iocheck ]] ) }

UNIT= - Quando omitido, o primeiro valor ser o nmero da unidade (unit).

unit Expresso inteira. Indica o nmero da unidade.

errlabel Expresso inteira. Indica o rtulo de uma linha no mesmo arquivo para onde o
comando vai se houver erro. Quando omitido o efeito determinado pela presena ou no de
iocheck.

iocheck Varivel inteira. Retorna zero quando no ocorre erros, retorna o nmero do erro
quando um ocorre.

You might also like