1 / 25

Il linguaggio Fortran 90: 3. Procedure e Funzioni

Il linguaggio Fortran 90: 3. Procedure e Funzioni. Stefano Leonardi Dipartimento di Informatica e Sistemistica. Procedure. Il problema da risolvere viene spesso decomposto in tante parti logiche di facile soluzione.

bela
Download Presentation

Il linguaggio Fortran 90: 3. Procedure e Funzioni

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  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_1 !lunghezza primo cateto REAL, INTENT(IN) :: lato_2 !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 :: c1 !Lunghezza primo cateto REAL :: c2 !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 END DO 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) = '*' END DO DO i = 1, dim WRITE (*,*) linea END DO 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() IMPLICIT NONE cont = 0 RETURN END SUBROUTINE init

  22. Modulo Contatore (cont.) SUBROUTINE incrementa() IMPLICIT NONE cont = cont + 1 RETURN END SUBROUTINE incrementa FUNCTION valore() IMPLICIT NONE INTEGER :: valore valore = cont RETURN END FUNCTION valore END MODULE counter_mod !================================================================ PROGRAM counter USE counter_mod IMPLICIT NONE 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

More Related