Scaricare la presentazione
La presentazione è in caricamento. Aspetta per favore
PubblicatoPellegrino Cecchini Modificato 9 anni fa
1
Il linguaggio Fortran 90: 3. Procedure e Funzioni
Stefano Leonardi Dipartimento di Informatica e Sistemistica
2
Procedure Il problema da risolvere viene spesso decomposto in tante parti logiche di facile soluzione. E’ possibile realizzare le funzionalità di base attraverso unità di programma indipendenti dette procedure Le unità di programma possono essere compilate e testate separatamente. Le unità di programma possono essere utilizzate in più programmi che necessitano tale funzionalità.
3
Procedure (cont.) E’ possibile isolare la comunicazione delle procedure con il programma principale ad un insieme di parametri definiti nell’intestazione. Nelle Subroutine i dati di input e di output sono comunicati attraverso i parametri. Nelle Funzioni solo i dati di input sono comunicati attraverso i parametri mentre il risultato è indicato dal nome della funzione.
4
Subroutines Specifica di una subroutine
SUBROUTINE nome_subroutine (lista_argomenti) sezione dichiarativa sezione esecutiva RETURN END SUBROUTINE [nome_subroutine] Invocazione di una subroutine nel proramma principale CALL nome_subroutine (lista_argomenti)
5
Subroutines (cont.) I parametri di lista_argomenti nella dichiarazione sono detti parametri formali (o fittizi) I parametri di lista_argomenti nella chiamata sono detti paramentri attuali (o effettivi) I parametri attuali devono corrispondere ai parametri formali (o fittizi). Il controllo torna all’istruzione che segue la CALL dopo l’istruzione RETURN Le variabile usate all’interno della Subroutine sono dette variabili locali
6
Calcolo Ipotenusa SUBROUTINE calc_ipotenusa(lato_1, lato_2, ipotenusa)
! scopo: calcolare l’ipotenusa di un triangolo rettangolo date le ! lunghezza dei due cateti IMPLICIT NONE REAL, INTENT(IN) :: lato_ !lunghezza primo cateto REAL, INTENT(IN) :: lato_ !lunghezza secondo cateto REAL, INTENT(OUT) :: ipotenusa !lunghezza ipotenusa !Dichiara le variabili locali REAL :: temp !Calcolo ipotenusa temp = lato_1**2 + lato_2**2 ipotenusa = SQRT(temp) RETURN END SUBROUTINE calc_ipotenusa
7
Calcolo Ipotenusa (cont.)
! File prova_ipotenusa.for Program prova_ipotenusa !Scopo: Programma per provare la Subroutine calc_ipotenusa IMPLICIT NONE REAL :: c !Lunghezza primo cateto REAL :: c !Lunghezza secondo cateto REAL :: ipot !Lunghezza ipotenusa WRITE (*,*) 'Inserisci la lunghezza del primo cateto: ' READ (*,*) c1 WRITE (*,*) 'Inserisci la lunghezza del secondo cateto: ' READ (*,*) c2 CALL calc_ipotenusa (c1, c2, ipot) WRITE(*,*) 'La lunghezza dell''ipotenusa e'':', ipot STOP END PROGRAM prova_ipotenusa
8
Commenti: I nomi dei parametri attuali non sono necessariamente uguali ai nomi dei parametri formali I tipi dei parametri formali devono corrispondere uno ad uno ai tipi dei parametri attuali INTENT (IN): Il parametro formale è usato solo per passare i dati di input alla Subroutine INTENT (OUT): Il parametro formale è usato solo per passare i dati di output alla Subroutine INTENT (IN OUT): Il parametro formale è usato per passare i dati di input e output alla Subroutine USARE CON CAUTELA!!
9
Condivisione di Procedure
Le procedure sono contenute in un modulo che verrà indicato nelle unità di programma che le utilizzano Il modulo ed il programma sono compilati separatamente MODULE mie_sub CONTAINS SUBROUTINE sub1 (a,b,c) ……… END SUBROUTINE sub1 SUBROUTINE sub2 (a,b,c) END SUBROUTINE sub2 END MODULE mie_sub
10
Condivisione di Procedure (cont.)
PROGRAM prog_main USE mie_sub IMPLICITE NONE CALL sub1 (x,y,z) END PROGRAM prog_main
11
Stampa di Figure ! File: figure3.for
! Scopo: Definizione ed uso di SUBROUTINE: ! - con argomenti (1) ! - con costanti e variabili locali MODULE modulo_stampe_3 ! Questo modulo contiene la definizione di procedure per la stampa ! di figure e messaggi CONTAINS SUBROUTINE stampa_triangolo(dim) ! *** SEZIONE DICHIARATIVA *** ! IMPLICIT NONE ! DICHIARAZIONE ARGOMENTI FITTIZI INTEGER, INTENT(IN) :: dim ! lunghezza del lato !DICHIARAZIONE COSTANTI E VARIABILI LOCALI INTEGER, PARAMETER :: max_lung = 25 INTEGER :: i ! indice del ciclo CHARACTER(max_lung) :: linea ! linea da stampare
12
Stampa di Figure (cont.)
! *** SEZIONE ESECUTIVA *** ! DO i = 1, max_lung linea(i:i) = ' ' END DO DO i = 1, dim linea(i:i) = '*' WRITE (*,*) linea RETURN END SUBROUTINE stampa_triangolo
13
Stampa di Figure (cont.)
SUBROUTINE stampa_quadrato(dim) IMPLICIT NONE ! DICHIARAZIONE ARGOMENTI FITTIZI INTEGER, INTENT(IN) :: dim ! lunghezza del lato ! DICHIARAZIONE COSTANTI E VARIABILI LOCALI INTEGER, PARAMETER :: max_lung = 25 INTEGER :: i ! indice del ciclo CHARACTER(max_lung) :: linea ! linea da stampare DO i = 1, max_lung linea(i:i) = ' ' END DO DO i = 1, dim linea(i:i) = '*' WRITE (*,*) linea RETURN END SUBROUTINE stampa_quadrato END MODULE modulo_stampe_3
14
Stampa di Figure (cont.)
PROGRAM stampa_figure_3 !E' possibile scegliere la forma e la dimensione ! *** SEZIONE DICHIARATIVA *** ! USE modulo_stampe_3 IMPLICIT NONE CHARACTER(1) :: ch ! serve per il dialogo con l'utente INTEGER :: dimensione ! serve per l'acquisizione della dimensione ! *** SEZIONE ESECUTIVA *** ! DO WRITE (*,*) '*** IMMETTI UN CARATTERE A SCELTA FRA I SEGUENTI ***' WRITE (*,*) '***** T: stampa un triangolo' WRITE (*,*) '***** Q: stampa un quadrato' WRITE (*,*) '***** F: per terminare il programma' WRITE (*,*) READ (*,*) ch IF (ch == 'q' .OR. ch == 'Q' .OR. ch == 't' .OR. ch == 'T') THEN WRITE (*,*) 'Di che dimensione? ' READ (*,*) dimensione END IF
15
Stampa di Figure (cont.)
SELECT CASE (ch) CASE ('T','t') CALL stampa_triangolo(dimensione) CASE ('Q','q') CALL stampa_quadrato(dimensione) END SELECT IF (ch == 'f' .OR. ch == 'F') EXIT END DO STOP END PROGRAM stampa_figure_3
16
Funzioni Procedure che svolgono delle funzioni particolari non presenti tra le funzioni intrinseche (SIN(x), INT(x), etc…) I parametri indicano i valori di input su cui calcolare le funzioni. Occorre dichiarare nella funzione una variabile con stesso nome della funzione che definisce il tipo del risultato. Il risultato della funzione è assegnato al nome della variabile La funzione è utilizzabile in espressioni delle stesso tipo. E’ preferibile non modificare all’interno di una funzione i parametri di input che vengono tutti definiti come INTENT (IN) Modifiche ai parametri di input sono detti effetti collaterali (side effects)
17
Funzioni (cont.) FUNCTION nome (lista argomenti) sezione dichiarativa
tipo :: nome sezione esecutiva nome = espressione RETURN END FUNCTION nome
18
Calcolo di un polinomio
! File: test_quadf.for ! Scopo: Definizione ed uso di FUNCTION MODULE modulo_quadf ! Questo modulo contiene la function quadf() CONTAINS FUNCTION quadf (x,a,b,c) !calcola un polinomio del tipo f(x)= a*x**2+b*x+c IMPLICIT NONE !Dichiara gli argomenti REAL :: quadf REAL, INTENT(IN) :: x ! Valore della variabile REAL, INTENT(IN) :: a, b, c ! Coefficienti del polinomio quadf = a*x**2+b*x+c RETURN END FUNCTION quadf END MODULE modulo_quadf
19
Calcolo di un polinomio(cont.)
PROGRAM test_quadf !Scopo: provare la funzione quadf ! *** SEZIONE DICHIARATIVA *** ! USE modulo_quadf IMPLICIT NONE REAL :: a, b, c, x !Dati di input ! *** SEZIONE ESECUTIVA *** ! WRITE(*,*) 'Inserisci i coefficienti a, b, c: ' READ(*,*) a, b, c WRITE(*,*) 'Valore in cui valutare il polinomio: ' READ(*,*) x WRITE(*,*) 'quadf(', x, ') =', quadf(x,a,b,c) STOP END PROGRAM test_quadf
20
Condivisione di dati I moduli permettono anche la condivisione di dati tra diverse unità di programma. I dati sono accessibili a tutte le unità di programma che usano un determinato modulo ed alle procedure definite nello stesso modulo. All’interno di un modulo si possono includere sia dati che procedure che operano sui dati. E’ possibile imporre con l’istruzione SAVE che i valori dei dati non siano modificati tra l’esecuzione di due procedure.
21
Modulo Contatore ! File: counter.for MODULE counter_mod
! Questo modulo realizza un MODULO per un contatore intero IMPLICIT NONE INTEGER :: cont ! Variabile condivisa CONTAINS SUBROUTINE init() cont = 0 RETURN END SUBROUTINE init
22
Modulo Contatore (cont.)
SUBROUTINE incrementa() IMPLICIT NONE cont = cont + 1 RETURN END SUBROUTINE incrementa FUNCTION valore() INTEGER :: valore valore = cont END FUNCTION valore END MODULE counter_mod !================================================================ PROGRAM counter USE counter_mod CHARACTER(1) :: ch
23
Modulo Contatore (cont.)
DO WRITE (*,*) '*** IMMETTI UN CARATTERE A SCELTA FRA I SEGUENTI ***' WRITE (*,*) '***** A: azzera il contatore' WRITE (*,*) '***** I: incrementa il contatore' WRITE (*,*) '***** V: visualizza il contatore' WRITE (*,*) '***** F: per terminare il programma ' READ (*,*) ch SELECT CASE (ch) CASE ('A','a') CALL init() CASE ('I','i') CALL incrementa() CASE ('V','v') WRITE(*,*) valore() END SELECT IF (ch == 'f' .OR. ch == 'F') EXIT END DO STOP END PROGRAM counter
24
Avvertenze per Elf 90 Subroutine e funzioni devono essere necessariamente definite all'interno di un MODULE Una dichiarazione del tipo INTEGER FUNCTION nome_funzione (x) non viene compilata, e va sostituita con FUNCTION nome_funzione(x) INTEGER :: nome_funzione Il tipo di una funzione non deve essere ridichiarata nell'unità di programma che la usa. La clausola INTENT è obbligatoria per tutti gli argomenti passati ad un'unità di programma.
25
Compilazione di Procedure e Funzioni
Compilare semparatamente i file contenenti i Module e il file contenente il Programma principale, es: main.for Collegare i file oggetto con l’istruzione: > elf90 main.obj Eseguire il programma digitando: > main
Presentazioni simili
© 2024 SlidePlayer.it Inc.
All rights reserved.