fortran - rip tutorial · 2019-01-18 · fortran 95 procedure pure ed elementali 1997/06/15 fortran...

85
Fortran #fortran

Upload: others

Post on 15-Apr-2020

10 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Fortran

#fortran

Page 2: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Sommario

Di 1

Capitolo 1: Iniziare con Fortran 2

Osservazioni 2

Versioni 2

Examples 2

Installazione o configurazione 2

Ciao mondo 3

Equazione quadrata 4

Case insensibilità 5

Capitolo 2: Alternative moderne a caratteristiche storiche 6

Examples 6

Tipi di variabili implicite 6

Aritmetica se dichiarazione 7

Costrutti DO non bloccanti 8

Ritorno alternativo 8

Modulo Fisso 10

Blocchi comuni 11

GOTO assegnato 13

GOTO calcolato 14

Specificatori di formato assegnati 14

Funzioni di dichiarazione 15

Capitolo 3: Array 17

Examples 17

Notazione di base 17

Matrici allocative 18

Costruttori di array 18

Specifica della natura della matrice: rango e forma 20

Forma esplicita 21

Forma assunta 21

Dimensione presunta 21

Page 3: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Forma differita 22

Forma implicita 22

Intere matrici, elementi di array e sezioni di array 22

Interi array 23

Elementi di matrice 23

Sezioni di matrice 23

Componenti dell'array di array 24

Operazioni di matrice 25

Addizione e sottrazione 25

Funzione 25

Moltiplicazione e divisione 25

Operazioni con matrici 26

Sezioni di array avanzate: triplet di pedici e pedici vettoriali 26

Triplette degli abbonati 26

Sottoscrizioni del vettore 27

Sezioni dell'array di rank più alto 27

Capitolo 4: Controllo dell'esecuzione 29

Examples 29

Se costrutto 29

SELEZIONA il costrutto CASE 30

Costruisci il blocco DO 31

DOVE costruisci 33

Capitolo 5: Estensioni di file di origine (.f, .f90, .f95, ...) e in che modo sono correla 35

introduzione 35

Examples 35

Estensioni e significati 35

Capitolo 6: I / O 37

Sintassi 37

Examples 37

I / O semplice 37

Leggi con alcuni errori di controllo 37

Passando gli argomenti della riga di comando 38

Page 4: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 7: Interfacce esplicite e implicite 41

Examples 41

Sottoprogrammi interni / moduli e interfacce esplicite 41

Sottoprogrammi esterni e interfacce implicite 42

Capitolo 8: Interoperabilità C 44

Examples 44

Chiamando C da Fortran 44

C structs in Fortran 45

Capitolo 9: Procedure intrinseche 46

Osservazioni 46

Examples 46

Usando PACK per selezionare elementi che soddisfano una condizione 46

Capitolo 10: Procedure: funzioni e subroutine 48

Osservazioni 48

Examples 48

Sintassi della funzione 48

Dichiarazione di ritorno 49

Procedure ricorsive 49

L'intento di argomenti fittizi 50

Fare riferimento a una procedura 51

Capitolo 11: Programmazione orientata agli oggetti 54

Examples 54

Definizione del tipo derivato 54

Digitare le procedure 54

Tipi derivati astratti 55

Digita estensione 56

Tipo costruttore 57

Capitolo 12: Tipi di dati 59

Examples 59

Tipi intrinseci 59

Tipi di dati derivati 60

Precisione dei numeri in virgola mobile 61

Page 5: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Parametri di tipo lunghezza presunta e differita 63

Costanti letterali 64

Accesso alle sottostringhe dei caratteri 66

Accesso a componenti complessi 67

Dichiarazione e attributi 67

Capitolo 13: Unità di programma e layout di file 69

Examples 69

Programmi Fortran 69

Moduli e sottomoduli 70

Procedure esterne 70

Blocca le unità del programma di dati 71

Sottoprogrammi interni 71

File di codice sorgente 72

Capitolo 14: Utilizzo dei moduli 74

Examples 74

Sintassi del modulo 74

Utilizzo di moduli da altre unità di programma 74

Moduli intrinseci 76

Controllo di accesso 76

Entità modulo protetto 78

Titoli di coda 79

Page 6: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Di

You can share this PDF with anyone you feel could benefit from it, downloaded the latest version from: fortran

It is an unofficial and free Fortran ebook created for educational purposes. All the content is extracted from Stack Overflow Documentation, which is written by many hardworking individuals at Stack Overflow. It is neither affiliated with Stack Overflow nor official Fortran.

The content is released under Creative Commons BY-SA, and the list of contributors to each chapter are provided in the credits section at the end of this book. Images may be copyright of their respective owners unless otherwise specified. All trademarks and registered trademarks are the property of their respective company owners.

Use the content presented in this book at your own risk; it is not guaranteed to be correct nor accurate, please send your feedback and corrections to [email protected]

https://riptutorial.com/it/home 1

Page 7: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 1: Iniziare con Fortran

Osservazioni

Fortran è un linguaggio ampiamente utilizzato nella comunità scientifica per la sua idoneità al calcolo numerico. Particolarmente interessante è la notazione intuitiva degli array, che semplifica la scrittura di calcoli vettoriali veloci.

Nonostante la sua età, Fortran è ancora attivamente sviluppato, con numerose implementazioni, tra cui GNU, Intel, PGI e Cray.

Versioni

Versione Nota pubblicazione

FORTRAN 66 Prima standardizzazione di ASA (ora ANSI) 1966/03/07

FORTRAN 77 Fixed Form, Historic 1978/04/15

Fortran 90 Forma libera, standard ISO, operazioni di matrice 1991/06/15

Fortran 95 Procedure pure ed elementali 1997/06/15

Fortran 2003 Programmazione orientata agli oggetti 2004/04/04

Fortran 2008 Co-Array 2010-09-10

Examples

Installazione o configurazione

Fortran è un linguaggio che può essere compilato utilizzando i compilatori forniti da molti fornitori. Sono disponibili diversi compilatori per diverse piattaforme hardware e sistemi operativi. Alcuni compilatori sono software gratuiti, alcuni possono essere utilizzati gratuitamente e alcuni richiedono l'acquisto di una licenza.

Il compilatore Fortran gratuito più comune è GNU Fortran o gfortran. Il codice sorgente è disponibile da GNU come parte di GCC, la raccolta del compilatore GNU. I binari per molti sistemi operativi sono disponibili su https://gcc.gnu.org/wiki/GFortranBinaries . Le distribuzioni Linux contengono spesso gfortran nel loro gestore di pacchetti.

Ulteriori compilatori sono disponibili ad esempio:

EKOPath di PathScale•LLVM (backend via DragonEgg)•

https://riptutorial.com/it/home 2

Page 8: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Oracle Developer Studio•

Absoft Fortran Compiler•Intel Fortran Compiler•NAG Fortran Compiler•Compilatori IGP•

Sui sistemi HPC esistono spesso compilatori specializzati disponibili dal fornitore del sistema come ad esempio i compilatori IBM o Cray .

Tutti questi compilatori supportano lo standard Fortran 95. Una panoramica sullo stato di Fortran 2003 e lo stato di Fortran 2008 da parte di vari compilatori è offerta dal forum Fortran ACM e disponibile in Fortran Wiki.

Ciao mondo

Qualsiasi programma Fortran deve includere la end come ultima dichiarazione. Pertanto, il programma Fortran più semplice ha il seguente aspetto:

end

Ecco alcuni esempi di programmi "ciao, mondo":

print *, "Hello, world" end

Con la dichiarazione di write :

write(*,*) "Hello, world" end

Per chiarezza ora è comune usare l'istruzione del program per avviare un programma e dargli un nome. L'istruzione end può quindi fare riferimento a questo nome per rendere evidente ciò a cui si riferisce e lasciare che il compilatore verifichi il codice per la correttezza. Inoltre, tutti i programmi Fortran dovrebbero includere implicit none dichiarazione implicit none . Pertanto, un programma Fortran minimamente dovrebbe apparire come segue:

program hello implicit none write(*,*) 'Hello world!' end program hello

Il prossimo passo logico da questo punto è come vedere il risultato del programma Hello World. Questa sezione mostra come ottenerlo in un ambiente simile a Linux. Assumiamo che tu abbia alcune nozioni di base sui comandi della shell , principalmente sai come arrivare al terminale della shell. Supponiamo anche che tu abbia già configurato il tuo ambiente fortran . Usando il tuo editor di testo preferito (notepad, notepad ++, vi, vim, emacs, gedit, kate, ecc.), Salva il programma ciao sopra (copia e incolla) in un file chiamato hello.f90 nella tua home directory. hello.f90 è il tuo file

https://riptutorial.com/it/home 3

Page 9: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

sorgente. Quindi vai alla riga di comando e vai alla directory (home directory?) In cui hai salvato il file sorgente, quindi digita il seguente comando:

>gfortran -o hello hello.f90

Hai appena creato il tuo programma Hello World eseguibile. In termini tecnici, hai appena compilato il tuo programma. Per eseguirlo, digitare il seguente comando:

>./hello

Dovresti vedere la seguente riga stampata sul tuo terminale shell.

> Hello world!

Congratulazioni, hai appena scritto, compilato e eseguito il programma "Hello World".

Equazione quadrata

Oggi Fortran è utilizzato principalmente per il calcolo numerico. Questo esempio molto semplice illustra la struttura di base del programma per risolvere equazioni di secondo grado:

program quadratic !a comment !should be present in every separate program unit implicit none real :: a, b, c real :: discriminant real :: x1, x2 print *, "Enter the quadratic equation coefficients a, b and c:" read *, a, b, c discriminant = b**2 - 4*a*c if ( discriminant>0 ) then x1 = ( -b + sqrt(discriminant)) / (2 * a) x2 = ( -b - sqrt(discriminant)) / (2 * a) print *, "Real roots:" print *, x1, x2 ! Comparison of floating point numbers for equality is often not recommended. ! Here, it serves the purpose of illustrating the "else if" construct. else if ( discriminant==0 ) then x1 = - b / (2 * a) print *, "Real root:" print *, x1 else print *, "No real roots." end if

https://riptutorial.com/it/home 4

Page 10: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

end program quadratic

Case insensibilità

Le lettere maiuscole e minuscole dell'alfabeto sono equivalenti nel set di caratteri di Fortran. In altre parole, Fortran non fa distinzione tra maiuscole e minuscole . Questo comportamento è in contrasto con i linguaggi case-sensitive, come C ++ e molti altri.

Di conseguenza, le variabili a e A sono la stessa variabile. In linea di principio si potrebbe scrivere un programma come segue

pROgrAm MYproGRaM .. enD mYPrOgrAM

È per il buon programmatore evitare queste brutte scelte.

Leggi Iniziare con Fortran online: https://riptutorial.com/it/fortran/topic/904/iniziare-con-fortran

https://riptutorial.com/it/home 5

Page 11: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 2: Alternative moderne a caratteristiche storiche

Examples

Tipi di variabili implicite

Quando Fortran era originariamente sviluppato, la memoria era un premio. Le variabili e i nomi delle procedure potevano avere un massimo di 6 caratteri e le variabili venivano spesso digitate implicitamente . Ciò significa che la prima lettera del nome della variabile determina il suo tipo.

le variabili che iniziano con i, j, ..., n sono integer•tutto il resto (a, b, ..., h, e o, p, ..., z) sono real•

Programmi come il seguente sono accettabili Fortran:

program badbadnotgood j = 4 key = 5 ! only the first letter determines the type x = 3.142 print*, "j = ", j, "key = ", key, "x = ", x end program badbadnotgood

Potresti anche definire le tue regole implicite con la dichiarazione implicit :

! all variables are real by default implicit real (a-z)

o

! variables starting with x, y, z are complex ! variables starting with c, s are character with length of 4 bytes ! and all other letters have their default implicit type implicit complex (x,y,z), character*4 (c,s)

La tipizzazione implicita non è più considerata la migliore pratica. È molto facile commettere un errore utilizzando la digitazione implicita, poiché gli errori di battitura possono passare inosservati, ad es

program oops real :: somelongandcomplicatedname ... call expensive_subroutine(somelongandcomplEcatedname) end program oops

Questo programma funzionerà felicemente e farà la cosa sbagliata.

https://riptutorial.com/it/home 6

Page 12: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Per disattivare la digitazione implicita, è possibile utilizzare l'istruzione implicit none .

program much_better implicit none integer :: j = 4 real :: x = 3.142 print*, "j = ", j, "x = ", x end program much_better

Se avessimo usato implicit none nel programma oops sopra, il compilatore si sarebbe accorto immediatamente e avrebbe prodotto un errore.

Aritmetica se dichiarazione

L'istruzione aritmetica if consente di utilizzare tre rami in base al risultato di un'espressione aritmetica

if (arith_expr) label1, label2, label3

Questa istruzione if trasferisce il flusso di controllo a una delle etichette in un codice. Se il risultato di arith_expr è negativo, l' label1 è coinvolta, se il risultato è zero label2 viene utilizzato e se il risultato è positivo, viene applicata l'ultima label3 . Aritmetica if richiede tutte e tre le etichette ma consente il riutilizzo di etichette, quindi questa affermazione può essere semplificata in due rami if .

Esempi:

if (N * N - N / 2) 130, 140, 130 if (X) 100, 110, 120

Ora, questa funzione è obsoleta con la stessa funzionalità offerti dal if dichiarazione e if-else costrutto. Ad esempio, il frammento

if (X) 100, 110, 120 100 print*, "Negative" goto 200 110 print*, "Zero" goto 200 120 print*, "Positive" 200 continue

può essere scritto come il costrutto if-else

if (X<0) then print*, "Negative" else if (X==0) then print*, "Zero" else print*, "Positive" end if

https://riptutorial.com/it/home 7

Page 13: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Una sostituzione di dichiarazione if per

if (X) 100, 100, 200 100 print *, "Negative or zero" 200 continue

può essere

if (X<=0) print*, "Negative or zero"

Costrutti DO non bloccanti

La non-blocco do costruire assomiglia

integer i do 100, i=1, 5 100 print *, i

Cioè, dove la dichiarazione di terminazione etichettata non è una dichiarazione continue . Ci sono varie restrizioni sulla dichiarazione che può essere usata come dichiarazione di terminazione e l'intera faccenda è generalmente molto confusa.

Tale costrutto non blocco può essere riscritto in forma di blocco come

integer i do 100 i=1,5 print *, i 100 continue

o meglio, usando una dichiarazione di end do ,

integer i do i=1,5 print *, i end do

Ritorno alternativo

Il ritorno alternativo è una funzione per controllare il flusso di esecuzione al ritorno da una subroutine. È spesso usato come una forma di gestione degli errori:

real x call sub(x, 1, *100, *200) print*, "Success:", x stop 100 print*, "Negative input value" stop 200 print*, "Input value too large"

https://riptutorial.com/it/home 8

Page 14: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

stop end subroutine sub(x, i, *, *) real, intent(out) :: x integer, intent(in) :: i if (i<0) return 1 if (i>10) return 2 x = i end subroutine

Il ritorno alternativo è contrassegnato dagli argomenti * nell'elenco degli argomenti fittizi subroutine.

Nell'istruzione di call sopra *100 e *200 riferiscono rispettivamente alle dichiarazioni 100 e 200 .

Nella subroutine stessa le dichiarazioni di return corrispondenti al ritorno alternativo hanno un numero. Questo numero non è un valore di ritorno, ma indica l'etichetta fornita a cui viene trasmessa l'esecuzione al reso. In questo caso, return 1 passa l'esecuzione all'istruzione 100 e return 2 passaggi all'esecuzione etichettata 200 . Una dichiarazione di return senza ornamenti, o il completamento dell'esecuzione di subroutine senza una dichiarazione di return , l'esecuzione della passata immediatamente dopo l'istruzione di chiamata.

La sintassi di ritorno alternativa è molto diversa dalle altre forme di associazione degli argomenti e la struttura introduce il controllo del flusso contrario ai gusti moderni. Un controllo di flusso più gradevole può essere gestito con la restituzione di un codice di "stato" intero.

real x integer status call sub(x, 1, status) select case (status) case (0) print*, "Success:", x case (1) print*, "Negative input value" case (2) print*, "Input value too large" end select end subroutine sub(x, i, status) real, intent(out) :: x integer, intent(in) :: i integer, intent(out) :: status status = 0 if (i<0) then status = 1 else if (i>10) status = 2 else x = i

https://riptutorial.com/it/home 9

Page 15: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

end if end subroutine

Modulo Fisso

Originariamente Fortran è stato progettato per un formato di formato fisso basato su una scheda perforata a 80 colonne:

Sì: questa è una riga del codice dell'autore

Questi sono stati creati su una macchina punch card, molto simile a questo:

Le immagini sono fotografie originali dell'autore

Il formato, come mostrato nella scheda campione illustrata, aveva le prime cinque colonne riservate per le etichette di istruzioni. La prima colonna è stata utilizzata per denotare i commenti con una lettera C. La sesta colonna è stata utilizzata per indicare una continuazione dell'istruzione (inserendo un carattere diverso da zero '0'). Le ultime 8 colonne sono state utilizzate per l'identificazione e il sequenziamento delle carte, il che è stato di grande valore se hai lasciato cadere il mazzo di carte sul pavimento! La codifica dei caratteri per le schede perforate aveva solo un numero limitato di caratteri ed era solo in maiuscolo. Di conseguenza, i programmi Fortran

https://riptutorial.com/it/home 10

Page 16: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

assomigliavano a questo:

DIMENSION A(10) 00000001 C THIS IS A COMMENT STATEMENT TO EXPLAIN THIS EXAMPLE PROGRAM 00000002 WRITE (6,100) 00000003 100 FORMAT(169HTHIS IS A RATHER LONG STRING BEING OUTPUT WHICH GOES OVE00000004 1R MORE THAN ONE LINE, AND USES THE STATEMENT CONTINUATION MARKER IN00000005 2COLUMN 6, AND ALSO USES HOLLERITH STRING FORMAT) 00000006 STOP 00000007 END 00000008

Anche il carattere dello spazio è stato ignorato ovunque, tranne all'interno di una costante di carattere di Hollerith (come mostrato sopra). Ciò significava che gli spazi potevano verificarsi all'interno di parole e costanti riservate, o completamente persi. Ciò ha avuto l'effetto collaterale di alcune affermazioni piuttosto fuorvianti come:

DO 1 I = 1.0

è un compito assegnato alla variabile DO1I mentre:

DO1I = 1,0

è in realtà un ciclo DO sulla variabile I

Il moderno Fortran non richiede ora questa forma di input fissa e consente la forma libera utilizzando qualsiasi colonna. I commenti ora sono indicati da un ! che può anche essere aggiunto a una riga di istruzioni. Gli spazi ora non sono consentiti da nessuna parte e devono essere usati come separatori, proprio come nella maggior parte delle altre lingue. Il suddetto programma potrebbe essere scritto in Fortran moderno come:

! This is a comment statement to explain this example program Print *,"THIS IS A RATHER LONG STRING BEING OUTPUT WHICH no longer GOES OVER MORE THAN ONE LINE, AND does not need to USE THE STATEMENT CONTINUATION MARKER IN COLUMN 6, or the HOLLERITH STRING FORMAT"

Sebbene la continuazione vecchio stile non sia più utilizzata, l'esempio sopra illustra che si verificano ancora dichiarazioni molto lunghe. Il Fortran moderno usa un simbolo & alla fine e all'inizio della continuazione. Ad esempio, potremmo scrivere quanto sopra in una forma più leggibile:

! This is a comment statement to explain this example program Print *,"THIS IS A RATHER LONG STRING BEING OUTPUT WHICH still & &GOES OVER MORE THAN ONE LINE, AND does need to USE THE STATEMENT & &CONTINUATION notation"

Blocchi comuni

Nelle prime versioni di Fortran, l'unico meccanismo per la creazione di archivi di variabili globali visibili da subroutine e funzioni consiste nell'utilizzare il meccanismo di blocco COMMON . Questo

https://riptutorial.com/it/home 11

Page 17: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

consentiva che le sequenze di variabili fossero nomi e condivisi in comune.

Oltre ai blocchi comuni denominati potrebbe esserci anche un blocco comune vuoto (senza nome).

Un blocco comune vuoto potrebbe essere dichiarato come

common i, j

mentre le variables blocco nominate potrebbero essere dichiarate come

common /variables/ i, j

Come esempio completo, possiamo immaginare un archivio di heap che viene utilizzato da routine che possono aggiungere e rimuovere valori:

PROGRAM STACKING COMMON /HEAP/ ICOUNT, ISTACK(1023) ICOUNT = 0 READ *, IVAL CALL PUSH(IVAL) CALL POP(IVAL) END SUBROUTINE PUSH(IVAL) COMMON /HEAP/ ICOUNT, ISTACK(1023) ICOUNT = ICOUNT + 1 ISTACK(ICOUNT) = IVAL RETURN END SUBROUTINE POP(IVAL) COMMON /HEAP/ ICOUNT, ISTACK(1023) IVAL = ISTACK(ICOUNT) ICOUNT = ICOUNT - 1 RETURN END

È possibile utilizzare dichiarazioni comuni per dichiarare implicitamente il tipo di una variabile e specificare l'attributo della dimension . Questo comportamento da solo è spesso una fonte sufficiente di confusione. Inoltre, l'associazione di memorizzazione implicita ei requisiti per le definizioni ripetute su unità di programma rendono l'uso di blocchi comuni inclini all'errore.

Infine, i blocchi comuni sono molto limitati negli oggetti che contengono. Ad esempio, una matrice in un blocco comune deve essere di dimensioni esplicite; gli oggetti allocabili potrebbero non verificarsi; i tipi derivati non devono avere l'inizializzazione predefinita.

Nel moderno Fortran questa condivisione di variabili può essere gestita mediante l'uso di moduli . L'esempio sopra può essere scritto come:

module heap implicit none

https://riptutorial.com/it/home 12

Page 18: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

! In Fortran 2008 all module variables are implicitly saved integer, save :: count = 0 integer, save :: stack(1023) end module heap program stacking implicit none integer val read *, val call push(val) call pop(val) contains subroutine push(val) use heap, only : count, stack integer val count = count + 1 stack(count) = val end subroutine push subroutine pop(val) use heap, only : count, stack integer val val = stack(count) count = count - 1 end subroutine pop end program stacking

I blocchi comuni nominati e vuoti presentano comportamenti leggermente diversi. Di nota:

gli oggetti in blocchi comuni denominati possono essere inizialmente definiti; gli oggetti in bianco comune non devono essere

gli oggetti nei blocchi comuni vuoti si comportano come se il blocco comune avesse l'attributo di save ; gli oggetti nei blocchi comuni denominati senza l'attributo di save potrebbero non essere definiti quando il blocco non si trova nell'ambito di un'unità di programma attiva

Quest'ultimo punto può essere contrapposto al comportamento delle variabili del modulo nel codice moderno. Tutte le variabili del modulo in Fortran 2008 vengono salvate in modo implicito e non diventano indefinite quando il modulo esce dal campo di applicazione. Prima che le variabili del modulo di Fortran 2008, come le variabili nei blocchi comuni denominati, diventassero indefinite anche quando il modulo usciva dall'ambito.

GOTO assegnato

GOTO assegnato utilizza la variabile intera a cui è assegnata un'etichetta di istruzione utilizzando l'istruzione ASSIGN.

100 CONTINUE ... ASSIGN 100 TO ILABEL

https://riptutorial.com/it/home 13

Page 19: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

... GOTO ILABEL

GOTO assegnato è obsoleto in Fortran 90 e eliminato in Fortran 95 e versioni successive. Può essere evitato nel codice moderno utilizzando procedure, procedure interne, indicatori di procedura e altre funzionalità.

GOTO calcolato

GOTO calcolato consente la diramazione del programma in base al valore di un'espressione intera.

GOTO (label_1, label_2,... label_n) scalar-integer-expression

Se l' scalar-integer-expression è uguale a 1, il programma continua con l'etichetta label_1 , se è uguale a 2 va a label_2 e così via. Se è inferiore a 1 o maggiore di n programma continua sulla riga successiva.

Esempio:

ivar = 2 ... GOTO (10, 20, 30, 40) ivar

salterà all'etichetta dell'istruzione 20.

Questa forma di goto è obsoleta in Fortran 95 e successivi, essendo sostituita dal costrutto di select case .

Specificatori di formato assegnati

Prima di Fortran 95 era possibile utilizzare i formati assegnati per l'input o l'output. Tenere conto

integer i, fmt read *, i assign 100 to fmt if (i<100000) assign 200 to fmt print fmt, i 100 format ("This is a big number", I10) 200 format ("This is a small number", I6) end

L'istruzione assign assegna un'etichetta di istruzione a una variabile intera. Questa variabile intera

https://riptutorial.com/it/home 14

Page 20: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

viene in seguito utilizzata come identificatore di formato nell'istruzione print .

Tale attribuzione di identificatori di formato è stata eliminata in Fortran 95. Invece, un codice più moderno può utilizzare un'altra forma di controllo del flusso di esecuzione

integer i read *, i if (i<100000) then print 100, i else print 200, i end if 100 format ("This is a big number", I10) 200 format ("This is a small number", I6) end

o una variabile di carattere può essere usata come specificatore di formato

character(29), target :: big_fmt='("This is a big number", I10)' character(30), target :: small_fmt='("This is a small number", I6)' character(:), pointer :: fmt integer i read *, i fmt=>big_fmt if (i<100000) fmt=>small_fmt print fmt, i end

Funzioni di dichiarazione

Considera il programma

implicit none integer f, i f(i)=i print *, f(1) end

Qui f è una funzione di dichiarazione. Ha un tipo di risultato intero, prendendo un argomento fittizio intero. 1

Tale funzione di dichiarazione esiste all'interno dell'ambito in cui è definita. In particolare, ha accesso a variabili e costanti con nome accessibili in tale ambito.

Tuttavia, le funzioni di dichiarazione sono soggette a molte restrizioni e sono potenzialmente confuse (guardando un'occhiata casuale come una dichiarazione di assegnazione di elementi

https://riptutorial.com/it/home 15

Page 21: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

dell'array). Restrizioni importanti sono:

il risultato della funzione e gli argomenti fittizi devono essere scalari•gli argomenti fittizi sono nella stessa portata della funzione•le funzioni di istruzione non hanno variabili locali•le funzioni di istruzioni non possono essere passate come argomenti reali•

I principali vantaggi delle funzioni di statement sono ripetuti dalle funzioni interne

implicit none print *, f(1) contains integer function f(i) integer i f = i end function end

Le funzioni interne non sono soggette alle restrizioni sopra menzionate, anche se è forse interessante notare che un sottoprogramma interno non può contenere ulteriori sottoprogrammi interni (ma può contenere una funzione di istruzione).

Le funzioni interne hanno il loro ambito ma hanno anche un'associazione host disponibile.

1 Negli esempi di codice vecchio e reale, non sarebbe inusuale vedere gli argomenti fittizi di una funzione di istruzione digitati implicitamente, anche se il risultato ha un tipo esplicito.

Leggi Alternative moderne a caratteristiche storiche online: https://riptutorial.com/it/fortran/topic/2103/alternative-moderne-a-caratteristiche-storiche

https://riptutorial.com/it/home 16

Page 22: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 3: Array

Examples

Notazione di base

Qualsiasi tipo può essere dichiarato come matrice utilizzando l'attributo dimensione o semplicemente indicando direttamente la dimension (o le dimension ) dell'array:

! One dimensional array with 4 elements integer, dimension(4) :: foo ! Two dimensional array with 4 rows and 2 columns real, dimension(4, 2) :: bar ! Three dimensional array type(mytype), dimension(6, 7, 8) :: myarray ! Same as above without using the dimension keyword integer :: foo2(4) real :: bar2(4, 2) type(mytype) :: myarray2(6, 7, 8)

Quest'ultimo modo di dichiarare array multidimensionali, consente la dichiarazione di array di rango / dimensioni di stesso tipo in una riga, come segue

real :: pencil(5), plate(3,-2:4), cuboid(0:3,-10:5,6)

Il rango massimo (numero di dimensioni) consentito è 15 nello standard Fortran 2008 ed era 7 prima.

Fortran memorizza gli array nell'ordine delle colonne . Cioè, gli elementi della bar sono memorizzati nella memoria come segue:

bar(1, 1), bar(2, 1), bar(3, 1), bar(4, 1), bar(1, 2), bar(2, 2), ...

In Fortran, la numerazione degli array inizia da 1 di default, in contrasto con C che inizia da 0 . Infatti, in Fortran, è possibile specificare i limiti superiore e inferiore per ogni dimensione in modo esplicito:

integer, dimension(7:12, -3:-1) :: geese

Questo dichiara una matrice di forma (6, 3) , il cui primo elemento è geese(7, -3) .

I limiti inferiore e superiore lungo le 2 (o più) dimensioni sono accessibili dalle funzioni intrinseche ubound e lbound . Infatti lbound(geese,2) ritornerebbe -3 , mentre ubound(geese,1) ritornerebbe 12 .

È possibile accedere alle dimensioni di una matrice per size funzione intrinseca. Ad esempio,

https://riptutorial.com/it/home 17

Page 23: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

size(geese, dim = 1) restituisce la dimensione della prima dimensione che è 6.

Matrici allocative

Le matrici possono avere l'attributo allocatable :

! One dimensional allocatable array integer, dimension(:), allocatable :: foo ! Two dimensional allocatable array real, dimension(:,:), allocatable :: bar

Questo dichiara la variabile ma non alloca alcuno spazio per essa.

! We can specify the bounds as usual allocate(foo(3:5)) ! It is an error to allocate an array twice ! so check it has not been allocated first if (.not. allocated(foo)) then allocate(bar(10, 2)) end if

Una volta che una variabile non è più necessaria, può essere deallocata :

deallocate(foo)

Se per qualche ragione un'istruzione allocate fallisce, il programma si fermerà. Questo può essere evitato se lo stato è controllato tramite la parola chiave stat :

real, dimension(:), allocatable :: geese integer :: status allocate(geese(17), stat=status) if (stat /= 0) then print*, "Something went wrong trying to allocate 'geese'" stop 1 end if

Anche l'istruzione deallocate ha una parola chiave stat :

deallocate (geese, stat=status)

status è una variabile intera il cui valore è 0 se l'allocazione o deallocazione ha avuto esito positivo.

Costruttori di array

Un valore dell'array rank-1 può essere creato utilizzando un costruttore di array , con la sintassi

(/ ... /) [ ... ]

https://riptutorial.com/it/home 18

Page 24: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Il modulo [...] stato introdotto in Fortran 2003 ed è generalmente considerato più chiaro da leggere, specialmente nelle espressioni complesse. Questo modulo è utilizzato esclusivamente in questo esempio.

I valori che caratterizzano un costruttore di array possono essere valori scalari, valori di array o loop impliciti.

I parametri di tipo e tipo dell'array costruito corrispondono a quelli dei valori nel costruttore di array

[1, 2, 3] ! A rank-1 length-3 array of default integer type [1., 2., 3.] ! A rank-1 length-3 array of default real type ["A", "B"] ! A rank-1 length-2 array of default character type integer, parameter :: A = [2, 4] [1, A, 3] ! A rank-1 length-4 array of default integer type, with A's elements integer i [1, (i, i=2, 5), 6] ! A rank-1 length-6 array of default integer type with an implied-do

Nei moduli sopra, tutti i valori dati devono essere dello stesso tipo e parametro di tipo. Non sono consentiti tipi di missaggio o parametri di tipo. I seguenti esempi non sono validi

[1, 2.] ! INVALID: Mixing integer and default real [1e0, 2d0] ! INVALID: Mixing default real and double precision [1., 2._dp] ! INVALID: Allowed only if kind `dp` corresponds to default real ["Hello", "Frederick"] ! INVALID: Different length parameters

Per costruire un array usando diversi tipi, deve essere fornita una specifica di tipo per l'array

[integer :: 1, 2., 3d0] ! A default integer array [real(dp) :: 1, 2, 3._sp] ! A real(dp) array [character(len=9) :: "Hello", "Frederick"] ! A length-2 array of length-9 characters

Quest'ultima forma per gli array di caratteri è particolarmente comoda per evitare spazi vuoti, come l'alternativa

["Hello ", "Frederick"] ! A length-2 array of length-9 characters

La dimensione di un array chiamato constant può essere implicita dal costruttore di array utilizzato per impostarne il valore

integer, parameter :: ids(*) = [1, 2, 3, 4]

e per i tipi con parametri di lunghezza può essere assunto il parametro della lunghezza

character(len=*), parameter :: names(*) = [character(3) :: "Me", "You", "Her"]

La specifica del tipo è richiesta anche nella costruzione di array a lunghezza zero. A partire dal

[ ] ! Not a valid array constructor

https://riptutorial.com/it/home 19

Page 25: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

i parametri di tipo e tipo non possono essere determinati dal set di valori non esistenti. Per creare un array intero predefinito a lunghezza zero:

[integer :: ]

I costruttori di array costruiscono solo array di livello 1. A volte, ad esempio nell'impostazione del valore di una costante denominata, in un'espressione sono richiesti anche array di rango superiore. Array di rank più alti possono essere presi dal risultato di reshape con un array rank-1 costruito

integer, parameter :: multi_rank_ids(2,2) = RESHAPE([1,2,3,4], shape=[2,2])

In un costruttore di array, i valori dell'array nell'ordine degli elementi con qualsiasi array nella lista valori sono come se i singoli elemets fossero stati dati nell'ordine di elementi dell'array. Quindi, l'esempio precedente

integer, parameter :: A = [2, 4] [1, A, 3] ! A rank-1 length-4 array of default integer type, with A's elements

è equivalente a

[1, 2, 4, 3] ! With the array written out in array element order

Generalmente i valori nel costruttore possono essere espressioni arbitrarie, compresi i costruttori di array annidati. Affinché tale costruttore di array soddisfi determinate condizioni, ad esempio un'espressione costante o specifica, si applicano restrizioni ai valori dei componenti.

Sebbene non sia un costruttore di array, alcuni valori dell'array possono anche essere opportunamente creati usando la funzione intrinseca spread . Per esempio

[(0, i=1,10)] ! An array with 10 default integers each of value 0

è anche il risultato del riferimento alla funzione

SPREAD(0, 1, 10)

Specifica della natura della matrice: rango e forma

L'attributo dimension su un oggetto specifica che quell'oggetto è una matrice. Ci sono, in Fortran 2008, cinque tipi di array: 1

forma esplicita•forma assunta•dimensione assunta•forma differita•

https://riptutorial.com/it/home 20

Page 26: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

forma implicita•

Prendi i tre array rank-1 2

integer a, b, c dimension(5) a ! Explicit shape (default lower bound 1), extent 5 dimension(:) b ! Assumed or deferred shape dimension(*) c ! Assumed size or implied shape array

Con questi si può vedere che è necessario un ulteriore contesto per determinare pienamente la natura di un array.

Forma esplicita

Un array di forme esplicito è sempre la forma della sua dichiarazione. A meno che la matrice non sia dichiarata locale a un sottoprogramma oa un costrutto di block , i limiti che definiscono la forma devono essere espressioni costanti. In altri casi, un array di forme esplicite può essere un oggetto automatico, utilizzando estensioni che possono variare a seconda di ogni chiamata di un sottoprogramma o di un block .

subroutine sub(n) integer, intent(in) :: n integer a(5) ! A local explicit shape array with constant bound integer b(n) ! A local explicit shape array, automatic object end subroutine

Forma assunta

Un array di forme presunte è un argomento fittizio senza l'attributo allocatable o pointer . Tale matrice prende la sua forma dall'argomento reale con cui è associato.

integer a(5), b(10) call sub(a) ! In this call the dummy argument is like x(5) call sub(b) ! In this call the dummy argument is like x(10) contains subroutine sub(x) integer x(:) ! Assumed shape dummy argument end subroutine sub end

Quando un argomento fittizio ha assunto la forma, l'ambito che fa riferimento alla procedura deve disporre di un'interfaccia esplicita disponibile per tale procedura.

Dimensione presunta

Un array di dimensioni presunte è un argomento fittizio che ha la sua dimensione assunta dal suo

https://riptutorial.com/it/home 21

Page 27: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

argomento reale.

subroutine sub(x) integer x(*) ! Assumed size array end subroutine

Gli array di dimensioni presunte si comportano in modo molto diverso dagli array di forme presunte e queste differenze sono documentate altrove.

Forma differita

Una matrice di forme differite è una matrice che ha l'attributo allocatable o pointer . La forma di tale array è determinata dalla sua allocazione o dall'assegnazione del puntatore.

integer, allocatable :: a(:) integer, pointer :: b(:)

Forma implicita

Una matrice di forme implicite è una costante denominata che prende la sua forma dall'espressione utilizzata per stabilirne il valore

integer, parameter :: a(*) = [1,2,3,4]

Le implicazioni di queste dichiarazioni di array sugli argomenti fittizi devono essere documentate altrove.

1 A Specifiche tecniche che si estendono Fortran 2008 aggiunge una sesta natura di array: rango assunto. Questo non è coperto qui.

2 Questi possono essere equivalentemente scritti come

integer, dimension(5) :: a integer, dimension(:) :: b integer, dimension(*) :: c

o

integer a(5) integer b(:) integer c(*)

Intere matrici, elementi di array e sezioni di array

Considera la matrice dichiarata come

https://riptutorial.com/it/home 22

Page 28: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

real x(10)

Quindi abbiamo tre aspetti di interesse:

L'intero array x ;1. Elementi di matrice, come x(1) ;2. Sezioni di array, come x(2:6) .3.

Interi array

Nella maggior parte dei casi l'intero array x riferisce a tutti gli elementi dell'array come entità singola. Può apparire in istruzioni eseguibili come print *, SUM(x) , print *, SIZE(x) o x=1 .

Un intero array può fare riferimento a matrici che non hanno una forma esplicita (come x sopra):

function f(y) real, intent(out) :: y(:) real, allocatable :: z(:) y = 1. ! Intrinsic assignment for the whole array z = [1., 2.,] ! Intrinsic assignment for the whole array, invoking allocation end function

Una matrice di dimensioni presunte può anche apparire come un intero array, ma solo in circostanze limitate (da documentare altrove).

Elementi di matrice

Si riferisce che un elemento dell'array fornisce indici interi, uno per ogni rango dell'array, che indica la posizione nell'intero array:

real x(5,2) x(1,1) = 0.2 x(2,4) = 0.3

Un elemento dell'array è uno scalare.

Sezioni di matrice

Una sezione array è un riferimento a un numero di elementi (forse solo uno) di un intero array, utilizzando una sintassi che coinvolge due punti:

real x(5,2) x(:,1) = 0. ! Referring to x(1,1), x(2,1), x(3,1), x(4,1) and x(5,1) x(2,:) = 0. ! Referring to x(2,1), x(2,2) x(2:4,1) = 0. ! Referring to x(2,1), x(3,1) and x(4,1) x(2:3,1:2) = 0. ! Referring to x(2,1), x(3,1), x(2,2) and x(3,2) x(1:1,1) = 0. ! Referring to x(1,1) x([1,3,5],2) = 0. ! Referring to x(1,2), x(3,2) and x(5,2)

https://riptutorial.com/it/home 23

Page 29: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Il modulo finale sopra utilizza un indice vettoriale . Questo è soggetto a una serie di restrizioni oltre le altre sezioni dell'array.

Ogni sezione dell'array è essa stessa una matrice, anche quando viene fatto riferimento a un solo elemento. Quello è x(1:1,1) è un array di rank 1 e x(1:1,1:1) è un array di rank 2.

Le sezioni delle matrici in generale non hanno un attributo dell'intero array. In particolare, dove

real, allocatable :: x(:) x = [1,2,3] ! x is allocated as part of the assignment x = [1,2,3,4] ! x is dealloacted then allocated to a new shape in the assignment

L'incarico

x(:) = [1,2,3,4,5] ! This is bad when x isn't the same shape as the right-hand side

non è consentito: x(:) , sebbene una sezione di matrice con tutti gli elementi di x , non sia una matrice allocabile.

x(:) = [5,6,7,8]

va bene quando x è della forma del lato destro.

Componenti dell'array di array

type t real y(5) end type t type(t) x(2)

Potremmo anche fare riferimento a interi array, elementi di array e sezioni di array in impostazioni più complicate.

Da quanto sopra, x è un intero array. Abbiamo anche

x(1)%y ! A whole array x(1)%y(1) ! An array element x%y(1) ! An array section x(1)%y(:) ! An array section x([1,2]%y(1) ! An array section x(1)%y(1:1) ! An array section

In tali casi non è consentito avere più di una parte del riferimento costituito da una matrice di rango 1. Ad esempio, non sono consentiti i seguenti aspetti

x%y ! Both the x and y parts are arrays x(1:1)%y(1:1) ! Recall that each part is still an array section

https://riptutorial.com/it/home 24

Page 30: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Operazioni di matrice

A causa dei suoi obiettivi computazionali, le operazioni matematiche sugli array sono semplici in Fortran.

Addizione e sottrazione

Le operazioni su array della stessa forma e dimensione sono molto simili all'algebra della matrice. Invece di scorrere tutti gli indici con i loop, si può scrivere addizione (e sottrazione):

real, dimension(2,3) :: A, B, C real, dimension(5,6,3) :: D A = 3. ! Assigning single value to the whole array B = 5. ! Equivalent writing for assignment C = A + B ! All elements of C now have value 8. D = A + B ! Compiler will raise an error. The shapes and dimensions are not the same

Anche gli array di slicing sono validi:

integer :: i, j real, dimension(3,2) :: Mat = 0. real, dimension(3) :: Vec1 = 0., Vec2 = 0., Vec3 = 0. i = 0 j = 0 do i = 1,3 do j = 1,2 Mat(i,j) = i+j enddo enddo Vec1 = Mat(:,1) Vec2 = Mat(:,2) Vec3 = Mat(1:2,1) + Mat(2:3,2)

Funzione

Allo stesso modo, la maggior parte delle funzioni intrinseche può essere utilizzata implicitamente assumendo l'operazione componente-saggio (sebbene ciò non sia sistematico):

real, dimension(2) :: A, B A(1) = 6 A(2) = 44 ! Random values B = sin(A) ! Identical to B(1) = sin(6), B(2) = sin(44).

Moltiplicazione e divisione

Bisogna fare attenzione al prodotto e alla divisione: le operazioni intrinseche che usano * e / simboli sono element-wise:

real, dimension(2) :: A, B, C A(1) = 2

https://riptutorial.com/it/home 25

Page 31: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

A(2) = 4 B(1) = 1 B(2) = 3 C = A*B ! Returns C(1) = 2*1 and C(2) = 4*3

Questo non deve essere confuso con le operazioni con la matrice (vedi sotto).

Operazioni con matrici

Le operazioni della matrice sono procedure intrinseche. Ad esempio, il prodotto matrice degli array della sezione precedente è scritto come segue:

real, dimension(2,1) :: A, B real, dimension(1,1) :: C A(1) = 2 A(2) = 4 B(1) = 1 B(2) = 3 C = matmul(transpose(A),B) ! Returns the scalar product of vectors A and B

Le operazioni complesse consentono di incapsulare le funzioni creando array temporanei. Sebbene consentito da alcuni compilatori e opzioni di compilazione, questo non è raccomandato. Ad esempio, un prodotto che include una trasposizione di matrice può essere scritto:

real, dimension(3,3) :: A, B, C A(:) = 4 B(:) = 5 C = matmul(transpose(A),matmul(B,matmul(A,transpose(B)))) ! Equivalent to A^t.B.A.B^T

Sezioni di array avanzate: triplet di pedici e pedici vettoriali

Come menzionato in un altro esempio, un sottoinsieme degli elementi di un array, chiamato sezione dell'array, può essere referenziato. Da quell'esempio che potremmo avere

real x(10) x(:) = 0. x(2:6) = 1. x(3:4) = [3., 5.]

Le sezioni delle matrici possono essere più generali di questa, però. Possono assumere la forma di triplette sottoscritte o di pedici vettoriali.

Triplette degli abbonati

Una triplice pedice assume la forma [bound1]:[bound2][:stride] . Per esempio

real x(10) x(1:10) = ... ! Elements x(1), x(2), ..., x(10) x(1:) = ... ! The omitted second bound is equivalent to the upper, same as above x(:10) = ... ! The omitted first bound is equivalent to the lower, same as above

https://riptutorial.com/it/home 26

Page 32: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

x(1:6:2) = ... ! Elements x(1), x(3), x(5) x(5:1) = ... ! No elements: the lower bound is greater than the upper x(5:1:-1) = ... ! Elements x(5), x(4), x(3), x(2), x(1) x(::3) = ... ! Elements x(1), x(4), x(7), x(10), assuming omitted bounds x(::-3) = ... ! No elements: the bounds are assumed with the first the lower, negative stride

Quando viene specificato un passo (che non deve essere zero), la sequenza di elementi inizia con il primo limite specificato. Se la falcata è positiva (o negativa), gli elementi selezionati seguono una sequenza incrementata (risp. Decrementata) dalla falcata fino a quando non viene preso l'ultimo elemento non più grande (o più piccolo) del secondo limite. Se il passo è omesso, viene trattato come se fosse uno.

Se il primo limite è maggiore del secondo limite e la falcata è positiva, non viene specificato alcun elemento. Se il primo limite è inferiore al secondo limite e la falcata è negativa, non viene specificato alcun elemento.

Va notato che x(10:1:-1) non è uguale a x(1:10:1) anche se ciascun elemento di x appare in entrambi i casi.

Sottoscrizioni del vettore

Un indice vettoriale è un array intero di grado 1. Questo designa una sequenza di elementi corrispondenti ai valori dell'array.

real x(10) integer i x([1,6,4]) = ... ! Elements x(1), x(6), x(4) x([(i,i=2,4)]) = ... ! Elements x(2), x(3) and x(4) print*, x([2,5,2]) ! Elements x(2), x(5) and x(2)

Una sezione di array con un indice vettoriale è limitata nel modo in cui può essere utilizzata:

potrebbe non essere un argomento associato ad un argomento fittizio definito nella procedura;

potrebbe non essere il bersaglio in un'istruzione di assegnazione puntatore;•potrebbe non essere un file interno in un'istruzione di trasferimento dati.•

Inoltre, una tale sezione di array potrebbe non apparire in un'istruzione che implica la sua definizione quando lo stesso elemento viene selezionato due volte. Da sopra:

print*, x([2,5,2]) ! Elements x(2), x(5) and x(2) are printed x([2,5,2]) = 1. ! Not permitted: x(2) appears twice in this definition

Sezioni dell'array di rank più alto

real x(5,2) print*, x(::2,2:1:-1) ! Elements x(1,2), x(3,2), x(5,2), x(1,1), x(3,1), x(5,1)

https://riptutorial.com/it/home 27

Page 33: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Leggi Array online: https://riptutorial.com/it/fortran/topic/996/array

https://riptutorial.com/it/home 28

Page 34: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 4: Controllo dell'esecuzione

Examples

Se costrutto

Il costrutto if (chiamato istruzione IF blocco in FORTRAN 77) è comune in molti linguaggi di programmazione. Esegue condizionatamente un blocco di codice quando un'espressione logica viene valutata su true.

[name:] IF (expr) THEN block [ELSE IF (expr) THEN [name] block] [ELSE [name] block] END IF [name]

dove,

nome : il nome del costrutto if (facoltativo)•expr - un'espressione logica scalare racchiusa tra parentesi•block - una sequenza di zero o più istruzioni o costrutti•

Un nome di costrutto all'inizio di un'istruzione if then deve avere lo stesso valore del nome del costrutto alla end if dell'istruzione, e dovrebbe essere univoco per l'attuale unità di ambito.

Nelle istruzioni if , (in) le uguaglianze e le espressioni logiche che valutano un'istruzione possono essere utilizzate con i seguenti operatori:

.LT. which is < ! less than

.LE. <= ! less than or equal

.GT. > ! greater than

.GE. >= ! greater than or equal

.EQ. = ! equal

.NE. /= ! not equal

.AND. ! logical and

.OR. ! logical or

.NOT. ! negation

Esempi:

! simplest form of if construct if (a > b) then c = b / 2 end if !equivalent example with alternate syntax if(a.gt.b)then c=b/2 endif

https://riptutorial.com/it/home 29

Page 35: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

! named if construct circle: if (r >= 0) then l = 2 * pi * r end if circle ! complex example with nested if construct block: if (a < e) then if (abs(c - e) <= d) then a = a * c else a = a * d end if else a = a * e end if block

Un uso storico del costrutto if è in quella che viene definita un'istruzione "aritmetica se". Poiché questo può essere sostituito da costrutti più moderni, tuttavia, non è coperto qui. Maggiori dettagli possono essere trovati qui .

SELEZIONA il costrutto CASE

Un costrutto di select case esegue condizionalmente un blocco di costrutti o istruzioni in base al valore di un'espressione scalare in un'istruzione select case . Questo costrutto di controllo può essere considerato come una sostituzione del goto calcolato.

[name:] SELECT CASE (expr) [CASE (case-value [, case-value] ...) [name] block]... [CASE DEFAULT [name] block] END SELECT [name]

dove,

nome : il nome del costrutto di select case (facoltativo)•expr - un'espressione scalare di tipo intero, logico o carattere (racchiusa tra parentesi)•case-value : una o più espressioni scalari di intero, logico o di inizializzazione del carattere racchiuse tra parentesi

block - una sequenza di zero o più istruzioni o costrutti•

Esempi:

! simplest form of select case construct select case(i) case(:-1) s = -1 case(0) s = 0 case(1:) s = 1 case default print "Something strange is happened"

https://riptutorial.com/it/home 30

Page 36: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

end select

In questo esempio, (:-1) valore del caso è un intervallo di valori corrispondenti a tutti i valori inferiori a zero, (0) corrisponde agli zeri e (1:) corrisponde a tutti i valori sopra lo zero, la sezione default interessa se altre sezioni lo hanno fatto non eseguito.

Costruisci il blocco DO

Un costrutto do è un costrutto ciclico che ha un numero di iterazioni governate da un controllo di ciclo

integer i do i=1, 5 print *, i end do print *, i

Nella forma in alto, la variabile loop i passa attraverso il loop 5 volte, prendendo a turno i valori da 1 a 5. Dopo che il costrutto ha completato la variabile di ciclo ha il valore 6, cioè la variabile di ciclo viene incrementata ancora una volta dopo il completamento del ciclo .

Più in generale, il costrutto do loop può essere compreso come segue

integer i, first, last, step do i=first, last, step end do

Il ciclo inizia con i con il valore per first , incrementando ogni iterazione per step fino a quando i è maggiore last (o meno last se la dimensione del passo è negativa).

È importante notare che poiché Fortran 95, la variabile di ciclo e le espressioni di controllo del ciclo devono essere numeri interi.

Un'iterazione può essere interrotta prematuramente con l'istruzione del cycle

do i=1, 5 if (i==4) cycle end do

e l'intero costrutto potrebbe cessare l'esecuzione con l'istruzione exit

do i=1, 5 if (i==4) exit end do print *, i

do costrutti possono essere nominati:

do_name: do i=1, 5

https://riptutorial.com/it/home 31

Page 37: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

end do do_name

che è particolarmente utile quando vi sono annidati do costrutti

do1: do i=1, 5 do j=1,6 if (j==3) cycle ! This cycles the j construct if (j==4) cycle ! This cycles the j construct if (i+j==7) cycle do1 ! This cycles the i construct if (i*j==15) exit do1 ! This exits the i construct end do end do1

do costrutti possono anche avere un controllo di ciclo indeterminato, "per sempre" o fino a quando una determinata condizione non viene soddisfatta

integer :: i=0 do i=i+1 if (i==5) exit end do

o

integer :: i=0 do while (i<6) i=i+1 end do

Ciò consente anche di un infinito do ciclo attraverso un .true. dichiarazione

print *,'forever' do while(.true.) print *,'and ever' end do

Un costrutto do può anche lasciare l'ordine delle iterazioni indeterminato

do concurrent (i=1:5) end do

notando che la forma del controllo del ciclo è la stessa di un controllo forall .

Esistono varie restrizioni sulle istruzioni che possono essere eseguite all'interno dell'intervallo di un costrutto do concurrent che sono progettate per garantire che non vi siano dipendenze tra le iterazioni del costrutto. Questa indicazione esplicita da parte del programmatore può consentire una maggiore ottimizzazione (inclusa la parallelizzazione) da parte del compilatore, che può essere difficile da determinare diversamente.

Le variabili "private" all'interno di un'interazione possono essere realizzate utilizzando un costrutto

https://riptutorial.com/it/home 32

Page 38: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

di block all'interno del do concurrent :

do concurrent (i=1:5, j=2:7) block real tempval ! This is independent across iterations end block end do

Un'altra forma di blocco do costruire utilizza un marcato continue dichiarazione invece di un end do :

do 100, i=1, 5 100 continue

È persino possibile annidare tali costrutti con un'istruzione di terminazione condivisa

do 100, i=1,5 do 100, j=1,5 100 continue

Entrambe queste forme, e specialmente la seconda (che è obsolescente), devono essere generalmente evitate per motivi di chiarezza.

Infine, v'è anche un non-blocco do costruire. Ciò è ritenuto essere anche obsoleti e viene descritto altrove , insieme a metodi per ristrutturare come blocco do costruire.

DOVE costruisci

Il costrutto where , disponibile in Fortran90 in poi, rappresenta un costrutto do mascherato. L'istruzione masking segue le stesse regole dell'istruzione if , ma viene applicata a tutti gli elementi dell'array dato. L'utilizzo di where consente di eseguire operazioni su un array (o più array della stessa dimensione), i cui elementi soddisfano una determinata regola. Questo può essere usato per semplificare le operazioni simultanee su più variabili.

Sintassi:

[name]: where (mask) block [elsewhere (mask) block] [elsewhere block] end where [name]

Qui,

nome - è il nome dato al blocco (se nominato)•mask - è un'espressione logica applicata a tutti gli elementi•block - serie di comandi da eseguire•

https://riptutorial.com/it/home 33

Page 39: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Esempi:

! Example variables real:: A(5),B(5),C(5) A = 0.0 B = 1.0 C = [0.0, 4.0, 5.0, 10.0, 0.0] ! Simple where construct use where (C/=0) A=B/C elsewhere A=0.0 end ! Named where construct Block: where (C/=0) A=B/C elsewhere A=0.0 end where Block

Leggi Controllo dell'esecuzione online: https://riptutorial.com/it/fortran/topic/1657/controllo-dell-esecuzione

https://riptutorial.com/it/home 34

Page 40: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 5: Estensioni di file di origine (.f, .f90, .f95, ...) e in che modo sono correlati al compilatore.

introduzione

I file Fortran hanno una varietà di estensioni e ognuno di essi ha un significato separato. Specificano la versione di rilascio di Fortran, lo stile di formattazione del codice e l'uso delle direttive del preprocessore simile al linguaggio di programmazione C.

Examples

Estensioni e significati

Di seguito sono riportate alcune delle estensioni comuni utilizzate nei file di origine Fortran e le funzionalità su cui possono essere eseguite.

F minuscola nell'estensione

Questi file non hanno le caratteristiche delle direttive del preprocessore simili al linguaggio di programmazione C. Possono essere compilati direttamente per creare file oggetto. ad es .: .f, .for, .f95

F maiuscola nell'estensione

Questi file hanno le caratteristiche delle direttive del preprocessore simili al linguaggio di programmazione C. I preprocessori sono definiti all'interno dei file o usando come file di intestazione C / C ++ o entrambi. Questi file devono essere pre-elaborati per ottenere i file di estensione in minuscolo che possono essere utilizzati per la compilazione. ad esempio: .F, .FOR, .F95

.f, .for, .f77, .ftn

Questi sono usati per i file di Fortran che usano il formato di stile fisso e quindi usano la versione di rilascio di Fortran 77 . Dal momento che sono estensioni in minuscolo, non possono avere direttive per il preprocessore.

.F, .FOR, .F77, .FTN

Questi sono usati per i file di Fortran che usano il formato di stile fisso e quindi usano la versione di rilascio di Fortran 77 . Poiché sono estensioni maiuscole, possono avere direttive di preprocessore e quindi devono essere preelaborate per ottenere i file di estensione minuscoli.

.f90, .f95, .f03, .f08 Questi sono usati per i file Fortran che usano il formato stile libero e quindi

https://riptutorial.com/it/home 35

Page 41: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

usano versioni successive di Fortran. Le versioni di rilascio sono nel nome.

f90 - Fortran 90•f95 - Fortran 95•f03 - Fortran 2003•f08 - Fortran 2008•

Dal momento che sono estensioni in minuscolo, non possono avere direttive per il preprocessore.

.F90, .F95, .F03, .F08 Questi sono usati per i file Fortran che usano il formato Stile libero e quindi usano versioni successive di Fortran. Le versioni di rilascio sono nel nome.

F90 - Fortran 90•F95 - Fortran 95•F03 - Fortran 2003•F08 - Fortran 2008•

Poiché sono estensioni maiuscole, hanno direttive per il preprocessore e quindi devono essere preelaborate per ottenere i file di estensione in minuscolo.

Leggi Estensioni di file di origine (.f, .f90, .f95, ...) e in che modo sono correlati al compilatore. online: https://riptutorial.com/it/fortran/topic/10265/estensioni-di-file-di-origine---f---f90---f95-------e-in-che-modo-sono-correlati-al-compilatore-

https://riptutorial.com/it/home 36

Page 42: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 6: I / O

Sintassi

WRITE(unit num, format num) restituisce i dati dopo le parentesi in una nuova riga.•READ(unit num, format num) ingressi alla variabile dopo le parentesi.•OPEN(unit num, FILE=file) apre un file. (Ci sono più opzioni per aprire i file, ma non sono importanti per I / O.

CLOSE(unit num) chiude un file.•

Examples

I / O semplice

Come esempio di input e output di scrittura, acquisiremo un valore reale e restituiremo il valore e il relativo quadrato finché l'utente non immetterà un numero negativo.

Come specificato di seguito, il comando read accetta due argomenti: il numero di unità e l'identificatore di formato. Nell'esempio seguente, usiamo * per il numero di unità (che indica stdin) e * per il formato (che indica l'impostazione predefinita per i valori reali, in questo caso). Specifichiamo anche il formato per la dichiarazione di print . In alternativa, puoi usare write(*,"The value....") o semplicemente ignorare la formattazione e averlo come

print *,"The entered value was ", x," and its square is ",x*x

che risulterà probabilmente in alcune stringhe e valori stranamente distanziati.

program SimpleIO implicit none integer, parameter :: wp = selected_real_kind(15,307) real(kind=wp) :: x ! we'll loop over until user enters a negative number print '("Enter a number >= 0 to see its square. Enter a number < 0 to exit.")' do ! this reads the input as a double-pricision value read(*,*) x if (x < 0d0) exit ! print the entered value and it's square print '("The entered value was ",f12.6,", its square is ",f12.6,".")',x,x*x end do print '("Thank you!")' end program SimpleIO

Leggi con alcuni errori di controllo

Un moderno esempio di Fortran che include il controllo degli errori e una funzione per ottenere un

https://riptutorial.com/it/home 37

Page 43: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

nuovo numero di unità per il file.

module functions contains function get_new_fileunit() result (f) implicit none logical :: op integer :: f f = 1 do inquire(f,opened=op) if (op .eqv. .false.) exit f = f + 1 enddo end function end module program file_read use functions, only : get_new_fileunit implicit none integer :: unitno, ierr, readerr logical :: exists real(kind(0.d0)) :: somevalue character(len=128) :: filename filename = "somefile.txt" inquire(file=trim(filename), exist=exists) if (exists) then unitno = get_new_fileunit() open(unitno, file=trim(filename), action="read", iostat=ierr) if (ierr .eq. 0) then read(unitno, *, iostat=readerr) somevalue if (readerr .eq. 0) then print*, "Value in file ", trim(filename), " is ", somevalue else print*, "Error ", readerr, & " attempting to read file ", & trim(filename) endif else print*, "Error ", ierr ," attempting to open file ", trim(filename) stop endif else print*, "Error -- cannot find file: ", trim(filename) stop endif end program file_read

Passando gli argomenti della riga di comando

https://riptutorial.com/it/home 38

Page 44: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Dove gli argomenti della riga di comando sono supportati, possono essere letti tramite il get_command_argument intrinsico (introdotto nello standard Fortran 2003). Il command_argument_count intrinsic fornisce un modo per conoscere il numero di argomenti forniti nella riga di comando.

Tutti gli argomenti della riga di comando vengono letti come stringhe, pertanto è necessario eseguire una conversione del tipo interno per i dati numerici. Ad esempio, questo semplice codice somma i due numeri forniti sulla riga di comando:

PROGRAM cmdlnsum IMPLICIT NONE CHARACTER(100) :: num1char CHARACTER(100) :: num2char REAL :: num1 REAL :: num2 REAL :: numsum !First, make sure the right number of inputs have been provided IF(COMMAND_ARGUMENT_COUNT().NE.2)THEN WRITE(*,*)'ERROR, TWO COMMAND-LINE ARGUMENTS REQUIRED, STOPPING' STOP ENDIF CALL GET_COMMAND_ARGUMENT(1,num1char) !first, read in the two values CALL GET_COMMAND_ARGUMENT(2,num2char) READ(num1char,*)num1 !then, convert them to REALs READ(num2char,*)num2 numsum=num1+num2 !sum numbers WRITE(*,*)numsum !write out value END PROGRAM

L'argomento numero in get_command_argument varia utilmente tra 0 e il risultato di command_argument_count . Se il valore è 0 viene fornito il nome del comando (se supportato).

Molti compilatori offrono anche elementi intrinseci non standard (come getarg ) per accedere agli argomenti della riga di comando. Poiché questi non sono standard, dovrebbe essere consultata la corrispondente documentazione del compilatore.

L'uso di get_command_argument può essere esteso oltre l'esempio precedente con gli argomenti length e status . Ad esempio, con

character(5) arg integer stat call get_command_argument(number=1, value=arg, status=stat)

il valore di stat sarà -1 se il primo argomento esiste e ha lunghezza maggiore di 5. Se c'è qualche altra difficoltà nel recuperare l'argomento il valore di stat sarà un numero positivo (e arg sarà composto interamente da spazi vuoti). Altrimenti il suo valore sarà 0 .

L'argomento della length può essere combinato con una variabile di carattere di lunghezza differita, come nell'esempio seguente.

https://riptutorial.com/it/home 39

Page 45: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

character(:), allocatable :: arg integer arglen, stat call get_command_argument(number=1, length=arglen) ! Assume for simplicity success allocate (character(arglen) :: arg) call get_command_argument(number=1, value=arg, status=stat)

Leggi I / O online: https://riptutorial.com/it/fortran/topic/6778/i---o

https://riptutorial.com/it/home 40

Page 46: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 7: Interfacce esplicite e implicite

Examples

Sottoprogrammi interni / moduli e interfacce esplicite

Un sottoprogramma (che definisce una procedura ) può essere una subroutine o una function ; si dice che sia un sottoprogramma interno se viene chiamato o invocato dallo stesso program o sottoprogramma che lo contains , come segue

program my_program ! declarations ! executable statements, ! among which an invocation to ! internal procedure(s), call my_sub(arg1,arg2,...) fx = my_fun(xx1,xx2,...) contains subroutine my_sub(a1,a2,...) ! declarations ! executable statements end subroutine my_sub function my_fun(x1,x2,...) result(f) ! declarations ! executable statements end function my_fun end program my_program

In questo caso il compilatore saprà tutto su qualsiasi procedura interna, poiché tratta l'unità di programma come un tutto. In particolare, "vedrà" l' interface della procedura, cioè

se si tratta di una function o subroutine ,•quali sono i nomi e le proprietà degli argomenti a1 , a2 , x1 , x2 , ...,•quali sono le proprietà del risultato f (nel caso di una function ).•

Essendo l'interfaccia nota, il compilatore può verificare se gli argomenti effettivi ( arg1 , arg2 , xx1 , xx2 , fx , ...) passati alla procedura coincidono con gli argomenti dummy ( a1 , a2 , x1 , x2 , f , .. .).

In questo caso diciamo che l'interfaccia è esplicita .

Si dice che un sottoprogramma è un sottoprogramma del modulo quando viene invocato da un'istruzione nel modulo contenitore stesso,

module my_mod ! declarations

https://riptutorial.com/it/home 41

Page 47: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

contains subroutine my_mod_sub(b1,b2,...) ! declarations ! executable statements r = my_mod_fun(b1,b2,...) end subroutine my_sub function my_mod_fun(y1,y2,...) result(g) ! declarations ! executable statements end function my_fun end module my_mod

o da una dichiarazione in un'altra unità di programma che use quel modulo,

program my_prog use my_mod call my_mod_sub(...) end program my_prog

Come nella situazione precedente, il compilatore saprà tutto sul sottoprogramma e, quindi, diciamo che l'interfaccia è esplicita .

Sottoprogrammi esterni e interfacce implicite

Si dice che un sottoprogramma è esterno quando non è contenuto nel programma principale, né in un modulo o sottoprogramma antoher. In particolare, può essere definito mediante un linguaggio di programmazione diverso da Fortran.

Quando viene richiamato un sottoprogramma esterno, il compilatore non può accedere al suo codice, quindi tutte le informazioni permesse al compilatore sono implicitamente contenute nell'istruzione chiamante del programma chiamante e nel tipo una proprietà degli argomenti acutali, non gli argomenti fittizi ( la cui dichiarazione è sconosciuta al compilatore). In questo caso diciamo che l'interfaccia è implicita .

È possibile utilizzare un'istruzione external per specificare che il nome di una procedura è relativo a una procedura esterna,

external external_name_list

ma anche così, l'interfaccia rimane implicita.

Un blocco di interface può essere usato per specificare l'interfaccia di una procedura esterna,

interface interface_body

https://riptutorial.com/it/home 42

Page 48: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

end interface

dove l' interface_body è normalmente una copia esatta dell'intestazione della procedura seguita dalla dichiarazione di tutti i suoi argomenti e, se si tratta di una funzione, del risultato.

Ad esempio, per la funzione WindSpeed

real function WindSpeed(u, v) real, intent(in) :: u, v WindSpeed = sqrt(u*u + v*v) end function WindSpeed

Puoi scrivere la seguente interfaccia

interface real function WindSpeed(u, v) real, intent(in) :: u, v end function WindSpeed end interface

Leggi Interfacce esplicite e implicite online: https://riptutorial.com/it/fortran/topic/2882/interfacce-esplicite-e-implicite

https://riptutorial.com/it/home 43

Page 49: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 8: Interoperabilità C

Examples

Chiamando C da Fortran

Fortran 2003 ha introdotto caratteristiche linguistiche che possono garantire l'interoperabilità tra C e Fortran (e in più lingue usando C come intermediario). Queste funzionalità sono per lo più accessibili tramite il modulo intrinseco iso_c_binding :

use, intrinsic :: iso_c_binding

La parola chiave intrinsic garantisce che venga utilizzato il modulo corretto e non un modulo creato dall'utente con lo stesso nome.

iso_c_binding fornisce l'accesso a parametri di tipo di tipo interoperabile :

integer(c_int) :: foo ! equivalent of 'int foo' in C real(c_float) :: bar ! equivalent of 'float bar' in C

L'uso di parametri di tipo C garantisce che i dati possano essere trasferiti tra i programmi C e Fortran.

L'interoperabilità dei caratteri C char e Fortran è probabilmente un argomento per sé e quindi non è discussa qui

Per chiamare effettivamente una funzione C da Fortran, prima l'interfaccia deve essere dichiarata. Questo è sostanzialmente equivalente al prototipo della funzione C, e consente al compilatore di conoscere il numero e il tipo degli argomenti, ecc. L'attributo bind viene usato per indicare al compilatore il nome della funzione in C, che potrebbe essere diverso dal Fortran nome.

geese.h

// Count how many geese are in a given flock int howManyGeese(int flock);

geese.f90

! Interface to C routine interface integer(c_int) function how_many_geese(flock_num) bind(C, 'howManyGeese') ! Interface blocks don't know about their context, ! so we need to use iso_c_binding to get c_int definition use, intrinsic :: iso_c_binding, only : c_int integer(c_int) :: flock_num end function how_many_geese end interface

https://riptutorial.com/it/home 44

Page 50: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Il programma Fortran deve essere collegato alla libreria C ( dipendente dal compilatore, includi qui? ) Che include l'implementazione di howManyGeese() , quindi how_many_geese() può essere chiamato da Fortran.

C structs in Fortran

L'attributo bind può anche essere applicato ai tipi derivati:

geese.h

struct Goose { int flock; float buoyancy; } struct Goose goose_c;

geese.f90

use, intrinsic :: iso_c_binding, only : c_int, c_float type, bind(C) :: goose_t integer(c_int) :: flock real(c_float) :: buoyancy end type goose_t type(goose_t) :: goose_f

Ora i dati possono essere trasferiti tra goose_c e goose_f . Le routine C che accettano argomenti di tipo Goose possono essere chiamate da Fortran con type(goose_t) .

Leggi Interoperabilità C online: https://riptutorial.com/it/fortran/topic/2184/interoperabilita-c

https://riptutorial.com/it/home 45

Page 51: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 9: Procedure intrinseche

Osservazioni

Molte delle procedure intrinseche disponibili hanno in comune tipi di argomenti. Per esempio:

un argomento logico MASK che seleziona elementi di matrici di input da elaborare•un argomento scalare intero KIND che determina il tipo di risultato della funzione•un argomento intero DIM per una funzione di riduzione che controlla la dimensione su cui viene eseguita la riduzione

Examples

Usando PACK per selezionare elementi che soddisfano una condizione

La funzione del pack intrinseco racchiude una matrice in un vettore, selezionando gli elementi in base a una determinata maschera. La funzione ha due forme

PACK(array, mask) PACK(array, mask, vector)

(cioè, l'argomento vector è facoltativo).

In entrambi i casi la array è una matrice e una mask di tipo logico e conforme array (uno scalare o una matrice della stessa forma).

Nel primo caso il risultato è un array di tipo 1 di tipo e parametri di tipo di array con il numero di elementi che rappresenta il numero di elementi reali nella maschera.

integer, allocatable :: positive_values(:) integer :: values(5) = [2, -1, 3, -2, 5] positive_values = PACK(values, values>0)

risultati in positive_values come matrice [2, 3, 5] .

Con l'argomento vector rank-1 presente il risultato è ora la dimensione del vector (che deve avere almeno tanti elementi quanti sono i veri valori nella mask .

L'effetto con vector è restituire quella matrice con gli elementi iniziali di quella matrice sovrascritta dagli elementi mascherati array . Per esempio

integer, allocatable :: positive_values(:) integer :: values(5) = [2, -1, 3, -2, 5] positive_values = PACK(values, values>0, [10,20,30,40,50])

Risultati in positive_values essendo la matrice [2,3,5,40,50] .

https://riptutorial.com/it/home 46

Page 52: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Va notato che, indipendentemente dalla forma array degli argomenti, il risultato è sempre un array di rank-1.

Oltre a selezionare gli elementi di un array che soddisfano una condizione di mascheramento, è spesso utile determinare gli indici per i quali viene soddisfatta la condizione di mascheramento. Questo linguaggio comune può essere espresso come

integer, allocatable :: indices(:) integer i indices = PACK([(i, i=1,5)], [2, -1, 3, -2, 5]>0)

risultando negli indices l'array [1,3,5] .

Leggi Procedure intrinseche online: https://riptutorial.com/it/fortran/topic/2643/procedure-intrinseche

https://riptutorial.com/it/home 47

Page 53: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 10: Procedure: funzioni e subroutine

Osservazioni

Funzioni e subroutine , insieme ai moduli , sono gli strumenti per suddividere un programma in unità. Ciò rende il programma più leggibile e gestibile. Ciascuna di queste unità può essere pensata come parte del codice che, idealmente, potrebbe essere compilato e testato separatamente. I programmi principali possono chiamare (o richiamare) tali sottoprogrammi (funzioni o subroutine) per eseguire un'attività.

Le funzioni e le subroutine sono diverse nel seguente senso:

Le funzioni restituiscono un singolo oggetto e - di solito - non alterano i valori dei suoi argomenti (cioè si comportano esattamente come una funzione matematica!);

Le subroutine di solito svolgono un compito più complicato e ordinariamente alterano i loro argomenti (se ne esiste qualcuno), così come altre variabili (ad es. Quelle dichiarate nel modulo che contiene la subroutine).

Le funzioni e le subroutine vanno sotto il nome di procedure . (Nel seguito useremo il verbo "call" come sinonimo di "invocare" anche se tecnicamente le procedure da call sono subroutine s, mentre le function s appaiono come lato destro del compito o nelle espressioni.)

Examples

Sintassi della funzione

Le funzioni possono essere scritte utilizzando diversi tipi di sintassi

function name() integer name name = 42 end function

integer function name() name = 42 end function

function name() result(res) integer res res = 42 end function

Le funzioni restituiscono valori attraverso un risultato di funzione . A meno che l'istruzione della funzione non abbia una clausola di result , il result della funzione ha lo stesso nome della funzione. Con result il result della funzione è quello dato dal result . In ciascuno dei primi due esempi sopra il risultato della funzione è dato dal name ; nel terzo da res .

https://riptutorial.com/it/home 48

Page 54: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Il risultato della funzione deve essere definito durante l'esecuzione della funzione.

Le funzioni consentono di utilizzare alcuni prefissi speciali.

Funzione pura significa che questa funzione non ha effetti collaterali:

pure real function square(x) real, intent(in) :: x square = x * x end function

La funzione elementale è definita come operatore scalare, ma può essere invocata con array come argomento effettivo, nel qual caso la funzione verrà applicata a livello di elemento. A meno che non sia specificato il prefisso impure (introdotto in Fortran 2008), una funzione elementare è anche una funzione pura .

elemental real function square(x) real, intent(in) :: x square = x * x end function

Dichiarazione di ritorno

L'istruzione return può essere utilizzata per uscire dalla funzione e dalla subroutine. A differenza di molti altri linguaggi di programmazione non è usato per impostare il valore di ritorno.

real function f(x) real, intent(in) :: x integer :: i f = x do i = 1, 10 f = sqrt(f) - 1.0 if (f < 0) then f = -1000. return end if end do end function

Questa funzione esegue un calcolo iterativo. Se il valore di f diventa negativo, la funzione restituisce il valore -1000.

Procedure ricorsive

In Fortran, le funzioni e le subroutine devono essere esplicitamente dichiarate come ricorsive , se devono chiamarsi di nuovo, direttamente o indirettamente. Pertanto, un'implementazione ricorsiva della serie di Fibonacci potrebbe essere simile a questa:

https://riptutorial.com/it/home 49

Page 55: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

recursive function fibonacci(term) result(fibo) integer, intent(in) :: term integer :: fibo if (term <= 1) then fibo = 1 else fibo = fibonacci(term-1) + fibonacci(term-2) end if end function fibonacci

Un altro esempio può calcolare fattoriale:

recursive function factorial(n) result(f) integer :: f integer, intent(in) :: n if(n == 0) then f = 1 else f = n * f(n-1) end if end function factorial

Affinché una funzione faccia riferimento direttamente a se stessa, la sua definizione deve utilizzare il suffisso del result . Non è possibile che una funzione sia sia recursive che elemental .

L'intento di argomenti fittizi

L'attributo intent di un argomento fittizio in una subroutine o funzione dichiara l'uso previsto. La sintassi è uno dei due

intent(IN) intent(OUT) intent(INOUT)

Ad esempio, considera questa funzione:

real function f(x) real, intent(IN) :: x f = x*x end function

L' intent(IN) specifica che l'argomento dummy (non puntatore) x non può mai essere definito o diventare indefinito in tutta la funzione o nella sua inizializzazione. Se un argomento fittizio puntatore ha l' intent(IN) attributo intent(IN) , questo vale per la sua associazione.

intent(OUT) per un argomento fittizio senza puntatore indica che l'argomento dummy diventa indefinito in caso di invocazione del sottoprogramma (ad eccezione di qualsiasi componente di un tipo derivato con inizializzazione predefinita) e deve essere impostato durante l'esecuzione. L'argomento effettivo passato come argomento fittizio deve essere definibile: il passaggio di una

https://riptutorial.com/it/home 50

Page 56: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

costante denominata o letterale o un'espressione non è consentito.

Analogamente a prima, se un argomento fittizio puntatore è intent(OUT) lo stato di associazione del puntatore diventa indefinito. L'argomento attuale qui deve essere una variabile puntatore.

intent(INOUT) specifica che l'argomento attuale è definibile ed è adatto sia per l'inoltro che per il ritorno dei dati dalla procedura.

Infine, un argomento fittizio può essere senza l'attributo intent . Tale argomento fittizio ha il suo uso limitato dall'argomento passato.

Ad esempio, considera

integer :: i = 0 call sub(i, .TRUE.) call sub(1, .FALSE.) end subroutine sub(i, update) integer i logical, intent(in) :: update if (update) i = i+1 end subroutine

L'argomento i può avere alcun intent attributo che permette sia delle chiamate subroutine del programma principale.

Fare riferimento a una procedura

Affinché una funzione o una subroutine siano utili, è necessario fare riferimento. A una subroutine viene fatto riferimento in una dichiarazione di call

call sub(...)

e una funzione all'interno di un'espressione. A differenza di molti altri linguaggi, un'espressione non costituisce un'istruzione completa, quindi un riferimento alla funzione è spesso visto in un'istruzione di assegnazione o utilizzato in altro modo:

x = func(...) y = 1 + 2*func(...)

Esistono tre modi per designare una procedura a cui si fa riferimento:

come il nome di un puntatore di procedura o procedura•un componente di procedura di un oggetto di tipo derivato•un nome vincolante alla procedura di tipo binding•

Il primo può essere visto come

https://riptutorial.com/it/home 51

Page 57: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

procedure(), pointer :: sub_ptr=>sub call sub() ! With no argument list the parentheses are optional call sub_ptr() end subroutine sub() end subroutine

e gli ultimi due come

module mod type t procedure(sub), pointer, nopass :: sub_ptr=>sub contains procedure, nopass :: sub end type contains subroutine sub() end subroutine end module use mod type(t) x call x%sub_ptr() ! Procedure component call x%sub() ! Binding name end

Per una procedura con argomenti fittizi, il riferimento richiede argomenti effettivi corrispondenti, sebbene non sia possibile fornire argomenti fittizi facoltativi.

Considera la subroutine

subroutine sub(a, b, c) integer a, b integer, optional :: c end subroutine

Questo può essere fatto riferimento nei seguenti due modi

call sub(1, 2, 3) ! Passing to the optional dummy c call sub(1, 2) ! Not passing to the optional dummy c

Questo è il cosiddetto riferimento posizionale : gli argomenti reali sono associati in base alla posizione negli elenchi degli argomenti. Qui, il dummy a è associato con 1 , b con 2 c (se specificato) con 3 .

In alternativa, è possibile utilizzare la referenziazione delle parole chiave quando la procedura ha un'interfaccia esplicita disponibile

https://riptutorial.com/it/home 52

Page 58: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

call sub(a=1, b=2, c=3) call sub(a=1, b=2)

che è lo stesso di sopra.

Tuttavia, con le parole chiave gli argomenti reali possono essere offerti in qualsiasi ordine

call sub(b=2, c=3, a=1) call sub(b=2, a=1)

Possono essere utilizzati entrambi i riferimenti di posizione e parola chiave

call sub(1, c=3, b=2)

purché venga fornita una parola chiave per ogni argomento che segue la prima apparizione di una parola chiave

call sub(b=2, 1, 3) ! Not valid: all keywords must be specified

Il valore del riferimento alla parola chiave è particolarmente pronunciato quando ci sono più argomenti fittizi facoltativi, come mostrato di seguito se nella definizione della subroutine sopra b erano anche facoltativi

call sub(1, c=3) ! Optional b is not passed

Gli elenchi degli argomenti per le procedure con collegamento del testo oi puntatori alle procedure del componente con un argomento passato vengono considerati separatamente.

Leggi Procedure: funzioni e subroutine online: https://riptutorial.com/it/fortran/topic/1106/procedure--funzioni-e-subroutine

https://riptutorial.com/it/home 53

Page 59: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 11: Programmazione orientata agli oggetti

Examples

Definizione del tipo derivato

Fortran 2003 ha introdotto il supporto per la programmazione orientata agli oggetti. Questa funzione consente di sfruttare le moderne tecniche di programmazione. I tipi derivati sono definiti con il seguente formato:

TYPE [[, attr-list] :: ] name [(name-list)] [def-stmts] [PRIVATE statement or SEQUENCE statement]. . . [component-definition]. . . [procedure-part] END TYPE [name]

dove,

attr-list : una lista di specificatori di attributi•nome : il nome del tipo di dati derivato•nome-elenco : un elenco di nomi di parametri di tipo separati da virgole•def-stmts : una o più dichiarazioni INTEGER dei parametri di tipo nominati nell'elenco dei nomi

definizione del componente - una o più istruzioni di dichiarazione del tipo o istruzioni del puntatore di procedura che definiscono il componente del tipo derivato

procedura-parte : un'istruzione CONTAINS, eventualmente seguita da un'istruzione PRIVATE e una o più istruzioni di associazione della procedura

Esempio:

type shape integer :: color end type shape

Digitare le procedure

Per ottenere un comportamento simile alla classe, il tipo e le procedure correlate (subroutine e funzioni) devono essere inseriti in un modulo:

Esempio:

module MShape implicit none private

https://riptutorial.com/it/home 54

Page 60: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

type, public :: Shape private integer :: radius contains procedure :: set => shape_set_radius procedure :: print => shape_print end type Shape contains subroutine shape_set_radius(this, value) class(Shape), intent(in out) :: self integer, intent(in) :: value self%radius = value end subroutine shape_set_radius subroutine shape_print(this) class(Shape), intent(in) :: self print *, 'Shape: r = ', self%radius end subroutine shape_print end module MShape

Più tardi, in un codice, possiamo usare questa classe Shape come segue:

! declare a variable of type Shape type(Shape) :: shape ! call the type-bound subroutine call shape%set(10) call shape%print

Tipi derivati astratti

Un tipo derivato estensibile può essere astratto

type, abstract :: base_type end type

Tale tipo derivato non può mai essere istanziato, ad esempio da

type(base_type) t1 allocate(type(base_type) :: t2)

ma un oggetto polimorfico può avere questo come tipo dichiarato

class(base_type), allocatable :: t1

o

function f(t1) class(base_type) t1 end function

https://riptutorial.com/it/home 55

Page 61: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

I tipi astratti possono avere componenti e procedure legate al tipo

type, abstract :: base_type integer i contains procedure func procedure(func_iface), deferred :: def_func end type

La procedura def_func è una procedura legata al tipo posticipata con interfaccia func_iface . Tale procedura legata al tipo posticipata deve essere implementata da ciascun tipo di estensione.

Digita estensione

Un tipo derivato è estensibile se non ha né l'attributo bind né l'attributo sequence . Un tal tipo può essere esteso da un altro tipo.

module mod type base_type integer i end type base_type type, extends(base_type) :: higher_type integer j end type higher_type end module mod

Una variabile polimorfica con tipo dichiarato base_type è di tipo compatibile con tipo higher_type e può avere questo come tipo dinamico

class(base_type), allocatable :: obj allocate(obj, source=higher_type(1,2))

La compatibilità di tipo discende attraverso una catena di bambini, ma un tipo può estendere solo un altro tipo.

Un tipo derivato estendente eredita le procedure legate al tipo dal genitore, ma questo può essere ignorato

module mod type base_type contains procedure :: sub => sub_base end type base_type type, extends(base_type) :: higher_type contains procedure :: sub => sub_higher end type higher_type

https://riptutorial.com/it/home 56

Page 62: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

contains subroutine sub_base(this) class(base_type) this end subroutine sub_base subroutine sub_higher(this) class(higher_type) this end subroutine sub_higher end module mod program prog use mod class(base_type), allocatable :: obj obj = base_type() call obj%sub obj = higher_type() call obj%sub end program

Tipo costruttore

I costruttori personalizzati possono essere creati per tipi derivati utilizzando un'interfaccia per sovraccaricare il nome del tipo. In questo modo, gli argomenti delle parole chiave che non corrispondono ai componenti possono essere utilizzati durante la costruzione di un oggetto di quel tipo.

module ball_mod implicit none ! only export the derived type, and not any of the ! constructors themselves private public :: ball type :: ball_t real :: mass end type ball_t ! Writing an interface overloading 'ball_t' allows us to ! overload the type constructor interface ball_t procedure :: new_ball end interface ball_t contains type(ball_t) function new_ball(heavy) logical, intent(in) :: heavy if (heavy) then new_ball%mass = 100 else

https://riptutorial.com/it/home 57

Page 63: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

new_ball%mass = 1 end if end function new_ball end module ball_mod program test use ball_mod implicit none type(ball_t) :: football type(ball_t) :: boulder ! sets football%mass to 4.5 football = ball_t(4.5) ! calls 'ball_mod::new_ball' boulder = ball_t(heavy=.true.) end program test

Questo può essere usato per creare un'API più ordinata rispetto all'utilizzo di routine di inizializzazione separate:

subroutine make_heavy_ball(ball) type(ball_t), intent(inout) :: ball ball%mass = 100 end subroutine make_heavy_ball ... call make_heavy_ball(boulder)

Leggi Programmazione orientata agli oggetti online: https://riptutorial.com/it/fortran/topic/2374/programmazione-orientata-agli-oggetti

https://riptutorial.com/it/home 58

Page 64: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 12: Tipi di dati

Examples

Tipi intrinseci

I seguenti sono tipi di dati intrinseci a Fortran:

integer real character complex logical

integer , real e complex sono tipi numerici.

character è un tipo usato per memorizzare stringhe di caratteri.

logical è usato per memorizzare valori .true. o .false. .

Tutti i tipi numerici e logici intrinseci sono parametrizzati utilizzando i tipi.

integer(kind=specific_kind)

o semplicemente

integer(specific_kind)

dove specific_kind è un numero intero chiamato constant.

Le variabili di caratteri, oltre ad avere un parametro gentile, hanno anche un parametro di lunghezza:

character char

dichiara che char è una variabile di lunghezza 1 di tipo predefinito, mentre

character(len=len) name

dichiara che il name è una variabile di carattere di tipo predefinito e lunghezza len . Il tipo può anche essere specificato

character(len=len, kind=specific_kind) name character(kind=specific_kind) char

dichiara che il name è un personaggio di tipo kind e lunghezza len . char è un carattere lunghezza-1 di tipo kind .

https://riptutorial.com/it/home 59

Page 65: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

In alternativa, il modulo obsoleto per la dichiarazione dei caratteri

character*len name

può essere visto nel vecchio codice, dichiarando che il name è di lunghezza len e tipo di carattere predefinito.

La dichiarazione di una variabile di tipo intrinseco può essere nella forma in alto, ma può anche usare il type(...) :

integer i real x double precision y

è equivalente a (ma molto preferito sopra)

type(integer) i type(real) x type(double precision) y

Tipi di dati derivati

Definisci un nuovo tipo, mytype :

type :: mytype integer :: int real :: float end type mytype

Dichiarare una variabile di tipo mytype :

type(mytype) :: foo

È possibile accedere ai componenti di un tipo derivato con % operator 1 :

foo%int = 4 foo%float = 3.142

Una funzionalità di Fortran 2003 (non ancora implementata da tutti i compilatori) consente di definire tipi di dati parametrizzati:

type, public :: matrix(rows, cols, k) integer, len :: rows, cols integer, kind :: k = kind(0.0) real(kind = k), dimension(rows, cols) :: values end type matrix

Il tipo derivato matrix ha tre parametri tipo che sono elencati in parentesi dopo il nome tipo (sono

https://riptutorial.com/it/home 60

Page 66: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

rows , cols e k ). Nella dichiarazione di ogni parametro di tipo deve essere indicato se sono di tipo gentile ( kind ) o lunghezza ( len ).

I parametri tipo tipo, come quelli dei tipi intrinseci, devono essere espressioni costanti, mentre i parametri del tipo di lunghezza, come la lunghezza di una variabile di carattere intrinseco, possono variare durante l'esecuzione.

Si noti che il parametro k ha un valore predefinito, quindi può essere fornito o omesso quando viene dichiarata una variabile di tipo matrix , come segue

type (matrix (55, 65, kind=double)) :: b, c ! default parameter provided type (matrix (rows=40, cols=50) :: m ! default parameter omitted

Il nome di un tipo derivato potrebbe non essere a doubleprecision o uguale a uno qualsiasi dei tipi intrinseci.

Molte persone si chiedono perché Fortran usi % come operatore di accesso ai componenti, anziché il più comune . . Questo perché . è già utilizzato dalla sintassi dell'operatore, ad esempio .not. , .and. , .my_own_operator. .

1.

Precisione dei numeri in virgola mobile

I numeri in virgola mobile di tipo real non possono avere alcun valore reale. Possono rappresentare numeri reali fino a una certa quantità di cifre decimali.

FORTRAN 77 ha garantito due tipi di virgola mobile e standard più recenti garantiscono almeno due tipi reali. Le variabili reali possono essere dichiarate come

real x double precision y

x qui è un vero tipo di default e y è un vero tipo con una precisione decimale maggiore di x . In Fortran 2008, la precisione decimale di y è almeno 10 e il suo intervallo di esponenti decimali almeno 37.

real, parameter :: single = 1.12345678901234567890 double precision, parameter :: double = 1.12345678901234567890d0 print *, single print *, double

stampe

1.12345684 1.1234567890123457

nei compilatori comuni che utilizzano la configurazione predefinita.

https://riptutorial.com/it/home 61

Page 67: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Notare il d0 nella costante a doppia precisione. Un vero letterale contenente d invece di e per denotare l'esponente viene usato per indicare la doppia precisione.

! Default single precision constant 1.23e45 ! Double precision constant 1.23d45

Fortran 90 ha introdotto tipi real parametrizzati usando i tipi. Il tipo di un tipo reale è un numero denominato costante costante o letterale:

real(kind=real_kind) :: x

o semplicemente

real(real_kind) :: x

Questa dichiarazione dichiara che x è di tipo real con una certa precisione a seconda del valore di real_kind .

I letterali in virgola mobile possono essere dichiarati con un tipo specifico usando un suffisso

1.23456e78_real_kind

Il valore esatto di real_kind non è standardizzato e differisce da compilatore a compilatore. Per verificare il tipo di qualsiasi variabile o costante reale, è possibile utilizzare il kind() funzione kind() :

print *, kind(1.0), kind(1.d0)

tipicamente stamperà

4 8

o

1 2

a seconda del compilatore.

I numeri di tipo possono essere impostati in diversi modi:

Singolo (predefinito) e doppia precisione:

integer, parameter :: single_kind = kind(1.) integer, parameter :: double_kind = kind(1.d0)

1.

Usando la funzione intrinseca selected_real_kind([p, r]) per specificare la precisione decimale richiesta. Il tipo restituito ha una precisione di almeno p cifre e consente l'esponente di almeno r .

2.

https://riptutorial.com/it/home 62

Page 68: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

integer, parameter :: single_kind = selected_real_kind( p=6, r=37 ) integer, parameter :: double_kind = selected_real_kind( p=15, r=200 )

A partire da Fortran 2003, le costanti predefinite sono disponibili tramite il modulo intrinseco ISO_C_Binding per garantire che i tipi reali siano interoperabili con i tipi float , double o long_double del compilatore C associato:

use ISO_C_Binding integer, parameter :: single_kind = c_float integer, parameter :: double_kind = c_double integer, parameter :: long_kind = c_long_double

3.

A partire da Fortran 2008, le costanti predefinite sono disponibili tramite il modulo intrinseco ISO_Fortran_env . Queste costanti forniscono tipi reali con determinate dimensioni di memoria in bit

use ISO_Fortran_env integer, parameter :: single_kind = real32 integer, parameter :: double_kind = real64 integer, parameter :: quadruple_kind = real128

4.

Se un determinato tipo non è disponibile nel compilatore, il valore restituito da selected_real_kind() o il valore della costante intera è -1 .

Parametri di tipo lunghezza presunta e differita

Le variabili di tipo carattere o di tipo derivato con parametro lunghezza possono avere il parametro lunghezza assunto o differito . Il name variabile di carattere

character(len=len) name

è di lunghezza len durante l'esecuzione. Viceversa lo specificatore della lunghezza può essere o

character(len=*) ... ! Assumed length

o

character(len=:) ... ! Deferred length

Le variabili di lunghezza ipotizzate assumono la loro lunghezza da un'altra entità.

Nella funzione

function f(dummy_name) character(len=*) dummy_name end function f

https://riptutorial.com/it/home 63

Page 69: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

l'argomento fittizio dummy_name ha lunghezza quella dell'argomento effettivo.

La costante const_name con nome in

character(len=*), parameter :: const_name = 'Name from which length is assumed'

ha lunghezza data dall'espressione costante sul lato destro.

I parametri di tipo lunghezza differita possono variare durante l'esecuzione. Una variabile con lunghezza posticipata deve avere l'attributo allocatable o pointer

character(len=:), allocatable :: alloc_name character(len=:), pointer :: ptr_name

La lunghezza di tale variabile può essere impostata in uno dei seguenti modi

allocate(character(len=5) :: alloc_name, ptr_name) alloc_name = 'Name' ! Using allocation on intrinsic assignment ptr_name => another_name ! For given target

Per i tipi derivati con parametrizzazione della lunghezza la sintassi è simile

type t(len) integer, len :: len integer i(len) end type t type(t(:)), allocatable :: t1 type(t(5)) t2 call sub(t2) allocate(type(t(5)) :: t1) contains subroutine sub(t2) type(t(*)), intent(out) :: t2 end subroutine sub end

Costanti letterali

Le unità di programma usano spesso costanti letterali. Questi coprono i casi ovvi come

print *, "Hello", 1, 1.0

Tranne che in un caso, ogni costante letterale è uno scalare che ha tipo, parametri di tipo e valore dati dalla sintassi.

https://riptutorial.com/it/home 64

Page 70: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Le costanti letterali intere sono della forma

1 -1 -1_1 ! For valid kind parameter 1 1_ik ! For the named constant ik being a valid kind paramter

Le vere costanti letterali sono della forma

1.0 ! Default real 1e0 ! Default real using exponent format 1._1 ! Real with kind parameter 1 (if valid) 1.0_sp ! Real with kind paramter named constant sp 1d0 ! Double precision real using exponent format 1e0_dp ! Real with kind named constant dp using exponent format

Le costanti letterali complesse sono della forma

(1, 1.) ! Complex with integer and real components, literal constants (real, imag) ! Complex with named constants as components

Se i componenti reali e immaginari sono entrambi interi, la costante letterale complessa è complessa di default e i componenti interi vengono convertiti in valori reali predefiniti. Se un componente è reale, il parametro gentile della costante letterale complessa è quello reale (e il componente intero viene convertito in quel tipo reale). Se entrambi i componenti sono reali, la costante letterale complessa è del tipo del reale con la massima precisione.

Le costanti letterali logiche sono

.TRUE. ! Default kind, with true value

.FALSE. ! Default kind, with false value

.TRUE._1 ! Of kind 1 (if valid), with true value

.TRUE._lk ! Of kind named constant lk (if valid), with true value

I valori letterali dei caratteri differiscono leggermente nel concetto, in quanto l'identificatore gentile precede il valore

"Hello" ! Character value of default kind 'Hello' ! Character value of default kind ck_"Hello" ! Character value of kind ck "'Bye" ! Default kind character with a ' '''Bye' ! Default kind character with a ' "" ! A zero-length character of default kind

Come suggerito sopra, le costanti letterali dei caratteri devono essere delimitate da apostrofi o virgolette e il marcatore di inizio e fine deve corrispondere. Gli apostrofi letterali possono essere inclusi tra i delimitatori delle virgolette o apparendo raddoppiati. Lo stesso per le virgolette.

Le costanti BOZ sono distinte da quelle precedenti, in quanto specificano solo un valore: non hanno alcun parametro di tipo o tipo. Una costante BOZ è un modello di bit e viene specificata come

https://riptutorial.com/it/home 65

Page 71: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

B'00000' ! A binary bit pattern B"01010001" ! A binary bit pattern O'012517' ! An octal bit pattern O"1267671" ! An octal bit pattern Z'0A4F' ! A hexadecimal bit pattern Z"FFFFFF" ! A hexadecimal bit pattern

Le costanti letterali BOZ sono limitate dove possono apparire: come costanti nelle dichiarazioni di data e una selezione di procedure intrinseche.

Accesso alle sottostringhe dei caratteri

Per l'entità del personaggio

character(len=5), parameter :: greeting = "Hello"

una sottostringa può essere referenziata con la sintassi

greeting(2:4) ! "ell"

Per accedere a una singola lettera non è sufficiente scrivere

greeting(1) ! This isn't the letter "H"

ma

greeting(1:1) ! This is "H"

Per un array di caratteri

character(len=5), parameter :: greeting(2) = ["Hello", "Yo! "]

abbiamo l'accesso alla sottostringa come

greeting(1)(2:4) ! "ell"

ma non possiamo fare riferimento ai caratteri non contigui

greeting(:)(2:4) ! The parent string here is an array

Possiamo persino accedere a sottostringhe di costanti letterali

"Hello"(2:4)

Una parte di una variabile di carattere può anche essere definita utilizzando una sottostringa come variabile. Per esempio

https://riptutorial.com/it/home 66

Page 72: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

integer :: i=1 character :: filename = 'file000.txt' filename(9:11) = 'dat' write(filename(5:7), '(I3.3)') i

Accesso a componenti complessi

L'entità complessa

complex, parameter :: x = (1., 4.)

ha la parte reale 1. e la parte complessa 4. .. Possiamo accedere a questi singoli componenti come

real(x) ! The real component aimag(x) ! The complex component x%re ! The real component y%im ! The complex component

Il formato x%.. è nuovo per Fortran 2008 e non ampiamente supportato nei compilatori. Questo modulo, tuttavia, può essere utilizzato per impostare direttamente i singoli componenti di una variabile complessa

complex y y%re = 0. y%im = 1.

Dichiarazione e attributi

Attraverso gli argomenti e gli esempi qui vedremo molte dichiarazioni di variabili, funzioni e così via.

Oltre al loro nome, gli oggetti dati possono avere attributi . Coperti in questo argomento sono dichiarazioni dichiarazioni come

integer, parameter :: single_kind = kind(1.)

che dà all'oggetto single_kind l'attributo del parameter (rendendolo una costante nominata).

Ci sono molti altri attributi, come

target•pointer•optional•save•

Gli attributi possono essere specificati con le cosiddette dichiarazioni di specifica degli attributi

integer i ! i is an integer (of default kind)...

https://riptutorial.com/it/home 67

Page 73: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

pointer i ! ... with the POINTER attribute... optional i ! ... and the OPTIONAL attribute

Tuttavia, si ritiene generalmente che sia meglio evitare di utilizzare queste dichiarazioni di specifica degli attributi. Per chiarezza gli attributi possono essere specificati come parte di una singola dichiarazione

integer, pointer, optional :: i

Ciò riduce anche la tentazione di utilizzare la digitazione implicita.

Nella maggior parte dei casi in questa documentazione Fortran questa dichiarazione di dichiarazione singola è preferita.

Leggi Tipi di dati online: https://riptutorial.com/it/fortran/topic/939/tipi-di-dati

https://riptutorial.com/it/home 68

Page 74: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 13: Unità di programma e layout di file

Examples

Programmi Fortran

Un programma Fortran completo è composto da un numero di unità di programma distinte. Le unità del programma sono:

programma principale•funzione o sottoprogramma subroutine•modulo o sottomodulo•bloccare l'unità di programma di dati•

Il programma principale e alcuni sottoprogrammi di routine (funzione o subroutine) possono essere forniti da una lingua diversa da Fortran. Ad esempio, un programma principale C può chiamare una funzione definita da un sottoprogramma della funzione Fortran, oppure un programma principale Fortran può chiamare una procedura definita da C.

Queste unità del programma Fortran possono essere fornite come file distinti o all'interno di un singolo file.

Ad esempio, potremmo vedere i due file:

prog.f90

program main use mod end program main

mod.f90

module mod end module mod

E il compilatore (invocato correttamente) sarà in grado di associare il programma principale al modulo.

Il singolo file può contenere molte unità di programma

everything.f90

module mod end module mod program prog

https://riptutorial.com/it/home 69

Page 75: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

use mod end program prog function f() end function f()

In questo caso, tuttavia, si deve notare che la funzione f è ancora una funzione esterna per quanto riguarda il programma principale e il modulo. Il modulo sarà accessibile dal programma principale, tuttavia.

Le regole dell'ambito di digitazione si applicano a ogni singola unità di programma e non al file in cui sono contenute. Ad esempio, se vogliamo che ogni unità di scoping non abbia una digitazione implicita, il file sopra riportato deve essere scritto come

module mod implicit none end module mod program prog use mod implicit none end program prog function f() implicit none <type> f end function f

Moduli e sottomoduli

I moduli sono documentati altrove .

I compilatori spesso generano i cosiddetti file di modulo : di solito il file che contiene

module my_module end module

risulterà in un file chiamato qualcosa come my_module.mod dal compilatore. In tali casi, affinché un modulo sia accessibile da un'unità di programma, quel file di modulo deve essere visibile prima che quest'ultima unità di programma venga elaborata.

Procedure esterne

Una procedura esterna è quella che è definita al di fuori di un'altra unità di programma o con un mezzo diverso da Fortran.

La funzione contenuta in un file come

integer function f() implicit none end function f

https://riptutorial.com/it/home 70

Page 76: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

è una funzione esterna.

Per le procedure esterne, la loro esistenza può essere dichiarata usando un blocco di interfaccia (a una interfaccia esplicita)

program prog implicit none interface integer function f() end interface end program prog

o da una dichiarazione dichiarazione per dare un'interfaccia implicita

program prog implicit none integer, external :: f end program prog

o anche

program prog implicit none integer f external f end program prog

L'attributo external non è necessario:

program prog implicit none integer i integer f i = f() ! f is now an external function end program prog

Blocca le unità del programma di dati

Le unità del programma di dati di blocco sono unità di programma che forniscono valori iniziali per oggetti in blocchi comuni. Questi sono deliberatamente lasciati senza documenti qui, e saranno presenti nella documentazione delle caratteristiche storiche di Fortran.

Sottoprogrammi interni

Un'unità di programma che non è un sottoprogramma interno può contenere altre unità di programma, chiamate sottoprogrammi interni .

program prog implicit none contains function f() end function f

https://riptutorial.com/it/home 71

Page 77: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

subroutine g() end subroutine g end program

Tale sottoprogramma interno ha una serie di caratteristiche:

esiste un'associazione host tra entità nel sottoprogramma e il programma esterno•le regole di digitazione implicite sono ereditate ( implicit none è in vigore in f sopra)•i sottoprogrammi interni hanno un'interfaccia esplicita disponibile nell'host•

Sottoprogrammi di modulo e sottoprogrammi esterni possono avere sottoprogrammi interni come

module mod implicit none contains function f() contains subroutine s() end subroutine s end function f end module mod

File di codice sorgente

Un file di codice sorgente è un file di testo (generalmente) che deve essere elaborato dal compilatore. Un file di codice sorgente può contenere un massimo di un programma principale e un numero qualsiasi di moduli e sottoprogrammi esterni. Ad esempio, un file di codice sorgente può contenere quanto segue

module mod1 end module mod1 module mod2 end module mod2 function func1() ! An external function end function func1 subroutine sub1() ! An external subroutine end subroutine sub1 program prog ! The main program starts here... end program prog ! ... and ends here function func2() ! An external function end function func2

Qui dovremmo ricordare che, anche se i sottoprogrammi esterni sono dati nello stesso file dei moduli e del programma principale, i sottoprogrammi esterni non sono esplicitamente noti da nessun altro componente.

In alternativa, i singoli componenti possono essere distribuiti su più file e anche compilati in momenti diversi. La documentazione del compilatore dovrebbe essere letta su come combinare

https://riptutorial.com/it/home 72

Page 78: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

più file in un singolo programma.

Un singolo file di codice sorgente può contenere codice sorgente in forma fissa o in formato libero: non possono essere mescolati, sebbene più file combinati in fase di compilazione possano avere stili diversi.

Per indicare al compilatore il modulo sorgente ci sono generalmente due opzioni:

scelta del suffisso del nome file•uso dei flag del compilatore•

Il flag di compilazione per indicare una fonte fissa o di forma libera può essere trovato nella documentazione del compilatore.

I suffissi significativi dei nomi dei file si trovano anche nella documentazione del compilatore, ma come regola generale un file denominato file.f90 viene utilizzato per contenere l'origine in forma libera mentre il file file.f viene utilizzato per contenere l'origine in forma fissa.

L'uso del suffisso .f90 per indicare l'origine in forma libera (che è stata introdotta nello standard Fortran 90) spesso induce il programmatore a utilizzare il suffisso per indicare lo standard di linguaggio a cui il codice sorgente è conforme. Ad esempio, potremmo vedere file con suffissi .f03 o .f08 . Ciò è generalmente da evitare: la maggior parte dei sorgenti di Fortran 2003 è anche compatibile con Fortran 77, Fortran 90/5 e Fortran 2008. Inoltre, molti concorrenti non considerano automaticamente tali suffissi.

I compilatori offrono spesso anche un preprocessore di codice incorporato (generalmente basato su cpp). Ancora una volta, può essere usato un flag in fase di compilazione per indicare che il preprocessore deve essere eseguito prima della compilazione, ma il suffisso del file del codice sorgente può anche indicare tale requisito di pre-elaborazione.

Per i filesystem con distinzione tra maiuscole e minuscole, il file file.F viene spesso considerato come un file sorgente di forma fissa da sottoporre a pre-elaborazione e file.F90 per essere un file di origine in formato libero da sottoporre a pre-elaborazione. Come prima, la documentazione del compilatore dovrebbe essere consultata per tali flag e suffissi di file.

Leggi Unità di programma e layout di file online: https://riptutorial.com/it/fortran/topic/2203/unita-di-programma-e-layout-di-file

https://riptutorial.com/it/home 73

Page 79: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Capitolo 14: Utilizzo dei moduli

Examples

Sintassi del modulo

Il modulo è una raccolta di dichiarazioni di tipo, dichiarazioni di dati e procedure. La sintassi di base è:

module module_name use other_module_being_used ! The use of implicit none here will set it for the scope of the module. ! Therefore, it is not required (although considered good practice) to repeat ! it in the contained subprograms. implicit none ! Parameters declaration real, parameter, public :: pi = 3.14159 ! The keyword private limits access to e parameter only for this module real, parameter, private :: e = 2.71828 ! Type declaration type my_type integer :: my_int_var end type ! Variable declaration integer :: my_integer_variable ! Subroutines and functions belong to the contains section contains subroutine my_subroutine !module variables are accessible print *, my_integer_variable end subroutine real function my_func(x) real, intent(in) :: x my_func = x * x end function my_func end module

Utilizzo di moduli da altre unità di programma

Per accedere a entità dichiarate in un modulo da un'altra unità di programma (modulo, procedura o programma), il modulo deve essere utilizzato con l'istruzione use .

module shared_data implicit none integer :: iarray(4) = [1, 2, 3, 4]

https://riptutorial.com/it/home 74

Page 80: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

real :: rarray(4) = [1., 2., 3., 4.] end module program test !use statements most come before implicit none use shared_data implicit none print *, iarray print *, rarray end program

L'istruzione use supporta l'importazione solo dei nomi selezionati

program test !only iarray is accessible use shared_data, only: iarray implicit none print *, iarray end program

È possibile accedere alle entità anche con un nome diverso utilizzando una lista di ridenominazione :

program test !only iarray is locally renamed to local_name, rarray is still acessible use shared_data, local_name => iarray implicit none print *, local_name print *, rarray end program

Inoltre, la rinomina può essere combinata con l' only opzione

program test use shared_data, only : local_name => iarray end program

in modo che sia accessibile solo l' iarray del modulo, ma ha il nome locale local_name .

Se selezionato per l'importazione di nomi contrassegnati come privati, non è possibile importarli nel programma.

https://riptutorial.com/it/home 75

Page 81: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Moduli intrinseci

Fortran 2003 ha introdotto moduli intrinseci che forniscono accesso a costanti speciali denominate, tipi derivati e procedure modulo. Ora ci sono cinque moduli intrinseci standard:

ISO_C_Binding ; supportare l'interoperabilità C;•ISO_Fortran_env ; dettagliando l'ambiente Fortran;•IEEE_Exceptions , IEEE_Arithmetic e IEEE_Features ; supporto della cosiddetta funzione aritmetica IEEE.

Questi moduli intrinseci fanno parte della libreria Fortran e sono accessibili come altri moduli, tranne che l'istruzione use può avere la natura intrinseca esplicitamente dichiarata:

use, intrinsic :: ISO_C_Binding

Ciò garantisce che il modulo intrinseco venga utilizzato quando è disponibile un modulo fornito dall'utente con lo stesso nome. al contrario

use, non_intrinsic :: ISO_C_Binding

si accerta che lo stesso modulo fornito dall'utente (che deve essere accessibile) sia accessibile al posto del modulo intrinseco. Senza la natura del modulo specificata come in

use ISO_C_Binding

un modulo non intrinseco disponibile sarà preferito rispetto al modulo intrinseco.

I moduli IEEE intrinseci sono diversi dagli altri moduli in quanto la loro accessibilità in una unità di scoping può cambiare il comportamento del codice anche senza riferimento a nessuna delle entità definite in essi.

Controllo di accesso

L'accessibilità dei simboli dichiarati in un modulo può essere controllata utilizzando attributi e dichiarazioni private e public .

Sintassi del modulo di dichiarazione:

!all symbols declared in the module are private by default private !all symbols declared in the module are public by default public !symbols in the list will be private private :: name1, name2 !symbols in the list will be public public :: name3, name4

https://riptutorial.com/it/home 76

Page 82: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Sintassi del modulo di attributo:

integer, parameter, public :: maxn = 1000 real, parameter, private :: local_constant = 42.24

È possibile accedere ai simboli pubblici dalle unità di programma utilizzando il modulo, ma i simboli privati non possono.

Quando non viene utilizzata alcuna specifica, l'impostazione predefinita è public .

La specifica di accesso predefinita usando

private

o

public

può essere modificato specificando un accesso diverso con elenco dichiarazione-entità

public :: name1, name2

o usando attributi.

Questo controllo di accesso influisce anche sui simboli importati da un altro modulo:

module mod1 integer :: var1 end module module mod2 use mod1, only: var1 public end module program test use mod2, only: var1 end program

è possibile, ma

module mod1 integer :: var1 end module module mod2 use mod1, only: var1 public private :: var1 end module

https://riptutorial.com/it/home 77

Page 83: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

program test use mod2, only: var1 end program

non è possibile perché var è privato in mod2 .

Entità modulo protetto

Oltre a consentire alle entità del modulo di avere il controllo dell'accesso (essendo public o private ) le entità dei moduli possono anche avere l'attributo protect . Un'entità pubblica protetta può essere associata all'utilizzo, ma l'entità utilizzata è soggetta a restrizioni sul suo utilizzo.

module mod integer, public, protected :: i=1 end module program test use mod, only : i print *, i ! We are allowed to get the value of i i = 2 ! But we can't change the value end program test

Un obiettivo pubblico protetto non può essere indicato all'esterno del suo modulo

module mod integer, public, target, protected :: i end module mod program test use mod, only : i integer, pointer :: j j => i ! Not allowed, even though we aren't changing the value of i end program test

Per un puntatore protetto pubblico in un modulo le restrizioni sono diverse. Ciò che è protetto è lo stato di associazione del puntatore

module mod integer, public, target :: j integer, public, protected, pointer :: i => j end module mod program test use mod, only : i i = 2 ! We may change the value of the target, just not the association status end program test

Come con i puntatori variabili, anche i puntatori di procedura possono essere protetti, impedendo nuovamente il cambio dell'associazione target.

Leggi Utilizzo dei moduli online: https://riptutorial.com/it/fortran/topic/1139/utilizzo-dei-moduli

https://riptutorial.com/it/home 78

Page 84: Fortran - RIP Tutorial · 2019-01-18 · Fortran 95 Procedure pure ed elementali 1997/06/15 Fortran 2003 Programmazione orientata agli oggetti 2004/04/04 Fortran 2008 Co-Array 2010-09-10

Titoli di coda

S. No

Capitoli Contributors

1 Iniziare con FortranAlexander Vogt, Community, Enrico Maria De Angelis, Gilles, haraldkl, High Performance Mark, Ingve, innoSPG, milancurcic, packet0, RamenChef, Serenity, Vladimir F, Yossarian

2Alternative moderne a caratteristiche storiche

Brian Tompsett - , d_1999, Enrico Maria De Angelis, francescalus, Serenity, TTT, Vladimir F, Yossarian

3 ArrayEnrico Maria De Angelis, francescalus, G.Clavier, Gilles, Serenity, TTT, Vladimir F, Yossarian

4Controllo dell'esecuzione

Enrico Maria De Angelis, francescalus, haraldkl, ptev, Serenity, syscreat, TTT, Vladimir F

5

Estensioni di file di origine (.f, .f90, .f95, ...) e in che modo sono correlati al compilatore.

Arun

6 I / O AL-P, Ed Smith, francescalus, Kyle Kanos, TTT

7Interfacce esplicite e implicite

Enrico Maria De Angelis, Serenity, Vladimir F

8 Interoperabilità C Serenity, Yossarian

9Procedure intrinseche

francescalus

10Procedure: funzioni e subroutine

Alexander Vogt, Enrico Maria De Angelis, francescalus, haraldkl, Serenity, Vladimir F, Yossarian

11Programmazione orientata agli oggetti

Enrico Maria De Angelis, francescalus, syscreat, Yossarian

12 Tipi di datiAlexander Vogt, Enrico Maria De Angelis, francescalus, Vladimir F, Yossarian

13Unità di programma e layout di file

agentp, francescalus, haraldkl, trblnc

Alexander Vogt, Enrico Maria De Angelis, francescalus, 14 Utilizzo dei moduli

https://riptutorial.com/it/home 79