Tipi strutturati
Paolo Bison
Fondamenti di Informatica Ingegneria Meccanica
Università di Padova A.A. 2008/09
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.1
tipi strutturati
composizione di altri tipi
caratterizzati
numero delle componenti
tipo delle componenti (tipo base)
metodo di strutturazione
selezione di un singolo componente
nel linguaggio Fortran
array
user-defined type
array
numero componenti:
fisso definito nella dichiarazione o al momento della creazione
tipo:
medesimo per tutte le componenti
strutturazione:
ad indice, corrispondenza biunivoca tra interi ed elementi dell’array (accesso casuale)
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.3
array - definizione
sintassi: attributo nella dichiarazione DIMENSION ( array-spec ) R513 array-spec
is explicit-shape-spec-list
or ...
514 explicit-shape-spec
is [ lower-bound : ] upper-bound
es.
integer, dimension(10) :: array1 integer, dimension(5,5) :: array2 real, dimension(-4:5) :: real_array logical, dimension(8,8) :: scacchiera
real, dimension(-10:10,-10:10,0:100) :: spazio_3D
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.4
array - terminologia
rango
numero (≤ 7)di explicit-shape-spec (indice)
nell’explicit-shape-spec-list
estensione
numero di elementi definiti da una singola
explicit-shape-spec
forma
combinazione del rango e di ogni singola estensione
dimensione
numero totale di elementi
tipo base: tipo presente nella dichiarazione
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.5
array - accesso agli elementi
sintassi
R613 part-ref
is part-name [ ( section-subscript-list ) ] R617 subscript
is scalar-int-expr R618 section-subscript
is subscript
or subscript-triplet
or ....
R619 subscript-triplet
is [ subscript ] : [ subscript ] [ : stride ] R620 stride
is scalar-int-expr
array - modalità di accesso
singola componente
array1(j+1) scacchiera(l,k)
sottoinsieme degli elementi
array1(2:7:2) array2(2,:) xy(::3,::2)
intero array spazio_3D
indici “out of bounds”
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.7
array - espressioni
array possono essere usati come operandi nelle espressioni
operatori su array delle medesima forma(elemento per elemento) o tra scalari e array
+ - / * **
funzioni intrinseche di elemento applicate elemento per elemento abs, sin, cos, ...
funzioni intrinseche di array
maxval, minval, product, sum, ...
lettura/scrittura
read *,array1 print *,spazio_3D
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.8
array - inizializzazione
array costante di rango 1
R432 array-constructor
is (/ ac-value-list /)
esempi
integer, dimension(5) :: b,a = (/ 1 , 3, 9, -8, 0 /) b = (/ -6, 65, -108, 0, 0 /)
funzione reshape per rango ≥ 2
RESHAPE ( value array , extension array )
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.9
array - semantica RESHAPE
real,dimension(3,2) :: arr
arr = RESHAPE((/ 1,2,3,4,5,6 /), (/3,2/))
equivalente a:
k=1
do j=1,2 do i=1,3
arr(i,j) = value-array(k) k = k+1
end do end do
minmax.f90
! minmax.f90
! cerca il max e il min di un array di interi program minmax
integer, parameter :: n=10 integer,dimension(n) :: a integer :: i,min,max
read *,a ! lettura di n interi min = a(1)
max=min do i=2,n
if (a(i)>max) then; max = a(i)
else if (a(i)<min) then; min=a(i); end if end do
print *,"min",min,"max",max
! funzioni intrinseche
print *,"min",minval(a),"max",maxval(a) end program minmax
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.11
matmul.f90
! matmul.f90
! prodotto di matrici 2x2 program matmul
real,dimension(0:1,0:1) :: a,b,c integer :: i,j,k
a =reshape((/ 0.5, 1.3, -0.8 ,2.5 /),(/2,2/)) b =reshape((/ 0.0, -0.9, -0.8 ,3.14 /),(/2,2/)) do i=0,1
do j=0,1 c(i,j)=0 do k=0,1
c(i,j)=c(i,j)+a(i,k)*b(k,j) end do
end do end do print *,c
end program matmul
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.12
crivello di Eratostene
! eratoprimo.f90
! calcolo numeri primi fino a N con il crivello di Eratostene program eratoprimo
integer, parameter :: N=100 integer :: i,k
logical,dimension(2:N) :: primo do i=2,N ; primo(i)=.TRUE. ;end do do k=2,N
if (primo(k)) then i=k+k
do
if (i>N) then; exit; end if primo(i)=.FALSE.
i = i + k end do end if end do
print *,"numeri primi fino a ",N do i=2,N
if (primo(i)) then; print *,i; end if end do
end program eratoprimo
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.13
div50.f90
! div50.p
! calcolo delle divisioni esatte di 1/N con N = 2..50 program div50
integer :: n,i
integer, dimension(50) :: cifre,resti
integer :: indice !indica quale cifra del quoziente
!si sta calcolando
integer :: inizio, fine ! inizio e fine del periodo logical :: finito
character (len=100) :: linea ! linea di stampa do n=2,50
indice = 1 ! indice della prima cifra
cifre(1) = 0 ! prima cifra quoziente e’ 0 (divisione 1/N) resti(1) = 10 ! con resto 10
inizio = 1
fine = 0 ! non c’e’ periodo
div50.f90
do
finito = resti(indice) == 0! valuta terminazione if (.not. finito) then
do i = 1,indice-1
if (resti(i) == resti(indice)) then finito= .true.
inizio = i + 1 fine = indice end if
end do end if
if (finito) then; exit; end if
! calcola cifra successiva indice = indice+1
cifre(indice)= resti(indice-1) / n
resti(indice)= modulo(resti(indice-1), n) * 10 end do
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.15
div50.f90
! stampa quoziente e periodo print *,"1/",n
linea="0."
do i=2,indice ! dalla seconda cifra
linea(i+1:i+1) = char(cifre(i)+ichar("0")) end do
print *,trim(linea) linea=" "
do i=2,fine
if (i<inizio) then linea(i+1:i+1)=" "
else
linea(i+1:i+1)="-"
end if end do
print *,trim(linea) end do ! n=1,50
end program div50 Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.16
user-defined type
numero componenti:
fisso definito nella dichiarazione o al momento della creazione
tipo:
definito per ogni singola componente
strutturazione:
per nome - ad ogni componente è associato un nome
analogo ai tipi:
struct del C
record del Pascal
struttura
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.17
user-defined type - definizione
sintassi
R422 derived-type-def is derived-type-stmt
component-def-stmt
[ component-def-stmt ] ...
end-type-stmt R423 derived-type-stmt
is TYPE , access-spec :: type-name R425 component-def-stmt
is type-spec [ , component-attr-spec-list ] :: component-decl-list
R426 component-attr-spec
is DIMENSION ( component-array-spec ) R428 component-decl
is component-name R430 end-type-stmt
user-defined type - esempi definizione
type :: person
character (len=20) :: cognome,nome integer :: eta
end type person type :: point3D real :: x,y,z end type point3D
type(person) :: io,tu
type(point3D) :: orig,top
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.19
user-defined type - accesso
sintassi
R612 data-ref
is part-ref [ % part-ref ] ...
modalità
singola componente nome qualificato con %
intera struttura (assegnazione, I/O) nome variabile
esempi
io%nome="Tarzan"
tu%nome="Jane" ; io%eta=tu%eta+7 io=tu
print *,tu ; print *,io%nome read *,io
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.20
user-defined type - inizializzazione
costruttore di strutture
R431 structure-constructor
is type-name ( expr-list )
identificatore di tipo seguito dalla lista dei valori da assegnare alle componenti
es.
type(person) :: egli=person("Pinco","Pallino",33) io=person("Bison","Paolo",min(k,38))
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.21
combinazione di tipi - 1
tipi composti possono combinati tra di loro
type :: a
integer :: n
real, dimension(17) :: arr end type a
type :: b
integer :: n
type(a), dimension(-2:2) : array_a end type b
type(b) :: b_var
combinazione di tipi - 2
accesso costruito combinando i differenti metodi di accesso
b var b var%n
b var%array a(6)%n
b var%array a(k+1)%arr(l)
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.23
conta_parole.f90
! conta_parole.f90
! conta le occorrenze di ogni singola parola
! presente in un testo memorizzato in una stringa
! parola e’ una sequanza di caratteri separati da _
!
program conta_parole
integer, parameter :: max_text_len=20000 integer, parameter :: max_word_len=20
!
! user-defined types
!
type :: entry_type
character (len=max_word_len) :: parola integer :: n_occ
end type
!
type :: db_type
integer :: n_entries
type (entry_type), dimension(100) :: entries end type
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.24
conta_parole.f90
! variabili
!
type(db_type) :: db
character(len=max_text_len) :: testo character(len=max_word_len) :: una_parola integer :: i,k
integer :: i,k db%n_entries=0 una_parola=""
read *,testo i=1
do
if (i>len_trim(testo)) then exit
end if
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.25
conta_parole.f90
! estrazione di una parola dal testo
!
una_parola=""
do
if ((testo(i:i)=="_") .or. (i>len_trim(testo))) then exit
end if
una_parola =trim(una_parola) // testo(i:i) i = i+1
end do
if (db%n_entries==0) then
! inserisci prima parola
db%entries(1)%parola = una_parola db%entries(1)%n_occ = 1
db%n_entries=1
conta_parole.f90
else
!ricerca la parola do k=1,db%n_entries
if (db%entries(k)%parola == una_parola) then exit
end if end do
if (k<=db%n_entries) then
! parola presente nel db
db%entries(k)%n_occ =db%entries(k)%n_occ +1 else
! inserisci parola alla fine db%entries(k)%parola = una_parola db%entries(k)%n_occ = 1
db%n_entries=k end if
end if i=i+1 end do
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.27
conta_parole.f90
!
! stampa parole con il numero di occorrenze
!
do i=1,db%n_entries
print *,db%entries(i)%parola,db%entries(i)%n_occ end do
end program conta_parole
Tipi strutturati, Paolo Bison, FI08, 2008-09-29 – p.28