Elementi di base del linguaggio Fortran Paolo Bison
Fondamenti di Informatica Ingegneria Meccanica
Università di Padova A.A. 2008/09
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.1
Linguaggio F
sottoinsieme del Fortran 90
solo costrutti “moderni” senza duplicazioni
sintassi descritta da BNF
aale produzioni relative al linguaggio F presenti in questi appunti sono tratte da
“BNF Syntax of the FT M Programming Language”,Copyright (C) 1996 by Imagine1, Inc.
Evoluzione storica
1954 primo sviluppo presso IBM
1958 Fortran II con procedure, funzioni e common 1962 IBM introduce Fortran IV
1978 Fortran 77, standard ANSI ANSI X.39-1978, che introduce costrutti per la programmazione strutturata
1991 Fortran 90, standard ISO 1539:1991, che introduce ulteriori miglioramenti (ricorsione, strutture dinamiche)
1993 Proposta di standardizzazione HPF (High Performance Fortran) per il calcolo parallelo
1995 Fortran 95, standard ISO/IEC 1539-1:1997
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.3
Formato sorgente
formato libero del Fortran 90
insieme dei caratteri
alfanumerici (a ... z, A ... Z, 0 ... 9) ( ) . = , $ % : < > ? _ " !
una istruzione per linea (max 132 caratteri)
commento
! fino a fine linea
Fortran90
& concatenazione di linee
; separazione di istruzioni
Simboli
singoli/concatenazioni di caratteri non alfanumerici
* ** / ==
parole chiave (keywords)
simboli costituiti da lettere (if, do, ...) riservate in F
identificatori
R304 name
is letter [ alphanumeric-character ] ...
R302 alphanumeric-character is letter
or digit or underscore R303 underscore
is _
Constraint:The maximum length of a name is 31 characters.
Constraint:The last character of a name shall not be _ .
Constraint:Names may be in mixed upper and lower case, however all references to the names shall use the same case convention.
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.5
Programma
unità di programmazione
sintassi
R201 program
is program-unit
[ program-unit ] ...
R202 program-unit is main-program or module R1101 main-program
is program-stmt [ use-stmt ] ...
[ intrinsic-stmt ] ...
[ other-type-declaration-stmt ] ...
[ execution-part ]
programma minimo
program mini
end program mini
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.7
Sezione esecutiva - 1
istruzioni
sintassi
R208 execution-part
is [ executable-construct ] ...
R215 executable-construct is action-stmt
or case-construct
or do-construct
or if-construct
or where-construct
Sezione esecutiva - 2
sintassi
R216 action-stmt is allocate-stmt or assignment-stmt or backspace-stmt or call-stmt or close-stmt or cycle-stmt or deallocate-stmt or endfile-stmt or exit-stmt or inquire-stmt or nullify-stmt or open-stmt
or pointer-assignment-stmt or print-stmt
or read-stmt or return-stmt or rewind-stmt or stop-stmt or write-stmt
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.9
Stop
terminazione esplicita del programma
sintassi
R840 stop-stmt is STOP
program mini stop
end program mini
visualizzazione del valore di espressioni
sintassi
R911 print-stmt
is PRINT format [ , output-item-list ] R913 format
is char-expr or *
R915 output-item is expr
R420 char-literal-constant is " [ rep-char ] ... "
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.11
Espressioni - 1
sintassi
R723 expr
is [ expr defined-binary-op ] level-5-expr
.. .
R713 level-4-expr
is [ level-3-expr rel-op ] level-3-expr R714 rel-op
is ==
or /=
or <
or <=
or >
or >=
.. .
Espressioni - 2
sintassi (cont.)
R706 add-operand
is [ add-operand mult-op ] mult-operand R707 level-2-expr
is [ [ level-2-expr ] add-op ] add-operand R709 mult-op
is *
or /
R710 add-op
is +
or -
.. .
R703 level-1-expr
is [ defined-unary-op ] primary R701 primary
is constant or variable.
.. or ( expr )
costanti intere
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.13
Stampa numeri
!
! printnum.f90
! stampa dei numeri a terminale
!
program printnum print *,3,8,0
end program printnum
Stampa espressioni
!
! printexp.f90
! stampa il valore di una espressione
!
program printexp print *,5 + 3 / 2 end program printexp
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.15
Variabile
individuata attraverso un identificatore
associata univocamente ad un tipo linguaggio tipizzato
esplicita dichiarazione del tipo associato alla variabile
Fortran 90 - implicit none
Tipo
elemento del linguaggio che definisce:
un insieme di valori
un insieme di operatori applicabili a tali valori
notazione per le costanti
usato per caratterizzare variabili e espressioni
compatibilità/conversioni tra tipi
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.17
Dichiarazione di tipo
sintassi
R501 type-declaration-stmt
is type-spec [ , attr-spec ] ... :: entity-decl-list R502 type-spec
is INTEGER [ kind-selector ] or REAL [ kind-selector ] or CHARACTER char-selector or COMPLEX [ kind-selector ] or LOGICAL [ kind-selector ] or TYPE ( type-name )
R504 entity-decl
is object-name [ initialization ] R505 initialization
is = initialization-expr
Integer
sottoinsieme finito degli interi I
operatori
+ - * / **
costanti
sequenza di cifre (es. 300 -234 )
rappresentazione finita
min=-2147483648 max=2147483647
es.
integer :: a,b=45,d d+b*89
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.19
Istruzione di assegnazione
sintassi
R735 assignment-stmt
is variable = expr
compatibilità di tipo
tipo espressione deve corrispondere al tipo associato alla
variabile
assign
!
! assign.f90
! esempi di istruzioni di assegnazione
!
program assign
integer :: a,b,c=30 a=c; b=a*56-c*7;
c=a>b ! e’ corretta?
print *,a,b,c
end program assign
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.21
Lettura
sintassi lettura
R909 read-stmt
is READ ( io-control-spec-list ) [ input-item-list ] or READ format [ , input-item-list ]
input-item-list
lista di variabili separate da ,
test sui valori letti
piu
!
! piu.f90
!
! calcola la somma di due numeri
!
program piu
integer :: m,n,s read *,m,n
s = m+n print *,s
end program piu
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.23
Strutture di controllo
struttura sequenziale block
struttura di selezione if
struttura iterativa
do
block
sequenza di istruzioni
sintassi
R801 block
is [ executable-construct ] ...
esempio a=b+c print *,a
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.25
if
selezione/condizionale
sintassi
R802 if-construct is if-then-stmt
block
[ else-if-stmt block ] ...
[ else-stmt block ] end-if-stmt R803 if-then-stmt
is IF ( logical-expr ) THEN R804 else-if-stmt
is ELSEIF ( logical-expr ) THEN
esempi if
if (i > 5) then
print *,i end if
if (k==l) then x = k*3 else
x = l*3 end if
if a > 6 then ! ? a=a*a
end if
if (i > 5) then; print *,i; end if
if (a==0) then k = k+1
else if (b==0) then k = 0
else k = 1 end if end if
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.27
piuabs
! piuabs.f90
!
! somma al primo numero il valore assoluto
! del secondo program piuabs integer :: m,n,s read *,m,n
if (n>0) then s = m+n else
s = m-n
do
ciclo iterativo
sintassi
R817 do-construct is do-stmt
block end-do R818 do-stmt
is [ do-name : ] DO [ loop-control ] R821 loop-control
is int-variable = int-expr, int-expr [ , int-expr ] R824 end-do
is ENDDO [ do-name ]
int-variable non può essere modificata nel block
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.29
semantica do
senza loop-control ciclo infinito
con loop-control
dovar=exp1,exp2, [exp3] block
end do
if c’è laexpr3then inc←expr3 else
inc←1
cnt←MAX((exp2-exp1+inc)/inc,0)a var←exp1
whilecnt6=0 block
cnt←cnt-1 var←var+inc
a cnt `e 0 se exp1 > exp2 e exp3 >0 op-
Esempi DO
do
print *,3 end do
do i=1,10 print *,i end do
do k=20,10,-2 print *,k end do
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.31
moltiplicazione
! multi.f90
! calcolo di m x n come addizioni ripetute
!
program multi
integer :: m,n,ris read *,m,n
if (m<0) then; stop; endif if (n<0) then; stop; endif ris=0
do i=1,n
ris=ris+m
Fattoriale
n! =
( n(n − 1)(n − 2) · · · 2 · 1 n > 0
1 n = 0
Ciclo che moltiplica tutti i numeri tra n e 1
1 × n × (n − 1) × (n − 2) × · · · × 2
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.33
Programma fattoriale
! fatt.f90
! calcola fattoriale di n
!
program fatt
integer :: i,n,r read *,n
if (n<0) then; stop; endif r = 1
do i = 2,n
r= r*i
end do
Terminazione DO
• CYCLE
- passa all’iterazione successiva - sintassi:
R834 cycle-stmt
is CYCLE [ do-name ]
• EXIT
- termina il ciclo DO - sintassi:
R835 exit-stmt
is EXIT [ do-name ]
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.35
DO come while
while P do
S
do
if ( P′) then exit
end if
S
end do
P
′è la negazione di P
se P = cnt > 0 P′= cnt <= 0
somma_n
! somma_n.f90
! somma i primi n numeri positivi
!
program somma_n integer :: i,n,s read *,n
if (n<1) then; stop; end if s = 0 ; i=1
do
if (i>n) then; exit; end if s = s + i
i = i + 1 end do
print *,s
end program somma_n
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.37somma_npari
! somma_npari.f90
! somma i primi n numeri pari
!
program somma_npari integer :: i,n,s read *,n
if (n<1) then; stop; end if s = 0; i=1
do
if (i>2*n) then; exit; end if if ((i-(i/2)*2)==0) then
s = s + i end if i = i+1 end do
somma_npari variante
! somma_npari_var.f90
! somma i primi n numeri pari
! variante con istr. cycle program somma_npari
integer :: i,n,s read *,n
if (n<1) then; stop; end if s = 0
do i = 1,2*n
if ((i-(i/2)*2)!=0) then; cycle; end if s = s + i
end do print *,s
end program somma_npari
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.39
Massimo Comun Divisore - 1
Dati due numeri m,n > 0 trovare MCD
metodo 1
Sia m ≥ n, con ciclo da 2 a n si verifica quali sono i numeri che dividono esattamente sia m che n. Il MCD è il massimo di tali numeri.
Nota: un numero è divisibile per un altro se il resto della
divisione è zero.
programma MCD 1
! calcola massimo comun divisore
! algoritmo 1 - max dei divisori comuni tra 0 e n program mcd1
integer :: i,m,n,mcd,tmp read *,n,m
if (m<1) then; stop; endif if (n<1) then; stop; endif if (m < n) then
tmp = m; m = n; n = tmp end if
mcd = 1; i = 1 do
if (i>n) then; exit ;end if if ((m-(m/i)*i)==0) then
if ((n-(n/i)*i)==0) then if (i > mcd) then
mcd = i
end if; end if; end if i= i+1
end do print *,mcd end program mcd1
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.41
Massimo Comun Divisore - 2
metodo 2 - Metodo di Euclide
Dato m ≥ n, qualunque numero che divide sia m che n divide anche il resto della divisione m/n
m = qn + r m - qn = r ≥ 0
q
mk - qq
nk = r k(q
m) = r
Si calcola il resto r di m/n. Se tale resto è zero n è il MCD, altrimenti n e r diventano m e n e si riapplica il passo
precedente.
programma MCD 2
! mcd2.f90
! calcola massimo comun divisore
! algoritmo 2 - metodo di Euclide program mcd2
integer :: r,m,n,tmp read *,n,m
if (m<1) then; stop; endif if (n<1) then; stop; endif if (m < n) then
tmp = m; m = n; n = tmp end if
r = m-(m/n)*n do
if (r == 0) then exit
end if
m = n; n = r; r = m-(m/n)*n end do
print *,n
end program mcd2
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.43
Massimo Comun Divisore - 3
metodo 3 - Metodo di Euclide (senza divisione)
Se m=n il MCD è m, altrimenti se m > n m diventa m-n
altrimenti è n che diventa n - m, e si ricontrolla l’eventuale
uguaglianza di m con n
programma MCD 3
! mcd3.f90
! calcola massimo comun divisore
! algoritmo 3 - metodo di Euclide (senza divisione) program mcd3
integer :: m,n read *,n,m
if (m<1) then; stop; endif if (n<1) then; stop; endif do
if (m == n) then; exit; end if if (m > n) then
m = m - n else
n = n - m end if end do print *,m
end program mcd3
Basic Fortran, Paolo Bison, FI08, 2008-09-30 – p.45
numero primo
! primo.f90
! dato n stampa T se e’ primo, F altrimenti
!
program primo integer :: n,r,div read *,n
if (n<1) then; stop; endif div=n / 2
r = n-(n/div)*div do
if (r == 0) then ; exit; end if div=div-1
r = n-(n/div)*div end do
print *,div==1