Info Fortran 90[/95] Mauro Bianco Usare il compilatore con windows • Aprire una finestra DOS – Si dovrebbe trovare sul menu si avvio – Aprire il menu, selezionare esegui/run e digitare “cmd” o “command” • • • • Posizionarsi sulla cartella di lavoro Lanciare il compilatore come in unix cp=copy, mv=ren, rm=del Attenzione alle estensioni dei file! Potrebbe non essere così facile cambiarle! Linguaggi Imperativi • Stesso approccio del linguaggio macchina • Sequenza di istruzioni • Istruzioni di vario tipo – Aritmetico-logiche – Confronti –… – Concetto di variabile • Utile alla realizzazione di algoritmi come li abbiamo definiti (sequenza di passi) • Il compilatore gfortran per windows funziona? • G95 dovrebbe funzionare abbastanza bene, quindi potete utilizzare quello • Consiglio, comunque, se non avete gfortran di provare i programmi che fate in laboratorio con gfortran Linguaggi di programmazione • Linguaggio Macchina • Linguaggio Assembly • Linguaggi di Alto Livello – Imperativi (C, Pascal, Fortran,…) – Funzionali (Lisp) – Logici (Prolog) – Orientati agli Oggetti (Java, C++,…) Linguaggi Funzionali e Logici • Funzionali – Basati solo sul concetto di funzione – Non esistono le variabili ma solo funzioni che possono essere argomenti di altre funzioni • Logici – Stile dichiarativo: il programmatore specifica quello che sa del problema (fatti) (A IF B C) – Si interroga il sistema che deduce la soluzione del problema dai fatti noti 1 Object Oriented Programming • Derivati dai linguaggi imperativi • I dati sono associati a delle procedure (sequenze di istruzioni) • Possibilità di creare delle entità autonome • Possibilità di creare entità più specifiche da entità più generali Set di Caratteri • Caratteri legali: – Lettere: a-z e A-Z (Fortran non fa differenza tra maiuscole e minuscole) – Cifre: 0-9 – Sottolineatura: _ – Operatori matematici: + - * / ** – Speciali: ( ) . = , $ : ! “ % & ; < > ? – Spazio vuoto PROGRAM my_first_program ! Purpose: ! To illustrate some of the basic features of a ! Fortran program. ! ! Declare the variables used in this program. INTEGER :: i, j, k ! All variables are ! integers ! Get the variables to multiply together. WRITE (*,*) 'Enter the numbers to multiply: ' READ (*,*) i, j ! Multiply the numbers together k = i * j ! Write out the result. WRITE (*,*) 'Result = ', k Fortran: Dove si usa • Calcolo scientifico e tecnico – Calcolo numerico • Calcolo ad alte prestazioni (esistono compilatori molto sofisticati) • Calcolo parallelo (Es. HPF: High Performance Fortran) Tipi di Istruzioni • Eseguibili – Operazioni matematiche e logiche – Confronti – Cicli – I/O • Non eseguibili – Definizioni di tipi e di variabili – Definizioni di routine e funzioni – Inizio e fine dei programmi Struttura di un programma • Sezione dichiarativa: Nome del programma (o della routine, o della funzione), il tipo e il nome delle variabili utilizzate • Sezione esecutiva: Istruzioni che descrivono le azioni che il programma deve compiere • Sezione conclusiva: Dichiarazione di fine programma (o routine, o funzione) ! Finish up. STOP END PROGRAM 2 Nomi di programmi e di variabili Variabili • Composti da 31caratteri • La prima lettera deve essere una lettera dell’alfabeto • Le altre lettere possono essere lettere dell’alfabeto, cifre o “_” • [a-zA-Z][a-zA-Z0-9_]{0,30} • “VaRiaBLe” è uguale a “vAriablE” • Lo stesso vale per tutti i nomi e le parole chiave • Identificatori che possono assumere valori di un certo tipo • Una variabile è il nome dell’indirizzo di memoria che contiene il dato • integer :: num • num è una variabile di tipo intero • Esistono cinque tipi di dati di base (impliciti) in Fortran90 – Integer, real, complex, logical, character Inizializzazione delle variabili program prova Integer :: i WRITE (*,*) i end program prova • Cosa stampa la write? Alcuni compilatori inizializzano a zero, altri danno un messaggio di errore al run-time, altri ancora restituiscono un valore “casuale” – Mantissa – Esponente d m ×10 – mEd, med Valide 0. -10.4 13.E-4 .999E5 -045.9 • INTEGER :: A=100 ! assegna ad A il valore 100 • “100” è una costante • [+-]{0,1}[0-9]+ • Segno + o – opzionale • Sequenza di cifre da 0 a 9 • La lunghezza dipende dal tipo (numero di bit) Valide Non Valide 0 1.000,5 +12 1,000.5 023 --12 999 -45 Costanti caratteri Costanti reali • Deve contentere il punto decimale • Notazione decimale • Notazione scientifica Costanti intere Non Valide 1.000,5 1,000.5 3E4 23.4E3.4 • Tutti i caratteri codificabili sono possibili! • I caratteri sono contenuti in virgolette singole o doppie • Per includere le virgolette ripetere il simbolo Valide Non Valide “Ciao” Ciao ‘Ciao’ “Ciao’ ‘l’’ape’ ‘l’ape’ “l’ape” ‘l’ape “45E3.{” ‘’ciao’ 3 Costanti logiche • Vero: .true. • Falso: .false. Dichiarazioni di tipo Valide Non Valide .true. true .false. .false .TRUE. false. .FAlsE. V .True. F Variabili implicite e esplicite • Se non dichiarate nella sezione dichiarativa le variabili che iniziano con I, J, K, L, M, N sono INTEGER, le altre sono REAL • ERROR PRONE • Evitare i problemi con IMPLICIT NONE • Forza a usare le istruzioni di dichiarazione di tipo • Fornisce errori in compilazione se ci sono variabili non dichiarate PROGRAM my_first_program ! Purpose: ! To illustrate some of the basic features of a ! Fortran program. ! IMPLICIT NONE ! Declare the variables used in this program. INTEGER :: i, j ! All variables are ! integers ! Get the variables to multiply together. WRITE (*,*) 'Enter the numbers to multiply: ' READ (*,*) i, j ! Multiply the numbers together k = i * j ! Write out the result. WRITE (*,*) 'Result = ', k • • • • • TIPO :: nome1, nome2=val, nome3 INTEGER :: age, score=50 REAL :: temp=37., height CHARACTER(15) :: nome, nick=“nick” I “::” sono facoltativi in queste semplici dichiarazioni ma obbligatori in casi più complessi! Usateli sempre per non sbagliare PROGRAM my_first_program ! Purpose: ! To illustrate some of the basic features of a ! Fortran program. ! ! Declare the variables used in this program. INTEGER :: i, j ! All variables are ! integers ! Get the variables to multiply together. WRITE (*,*) 'Enter the numbers to multiply: ' READ (*,*) i, j ! Multiply the numbers together k = i * j ! Write out the result. WRITE (*,*) 'Result = ', k ! Finish up. STOP END PROGRAM Nomi alle costanti • REAL, PARAMETER :: pi=3.14159 • Se nel programma si cerca di modificare il valore di “pi” si ottiene un errore di compilazione • Questo evita errori nel caso in cui il valore 3.14159 debba essere usato più volte! Se si chiamasse “b”? ! Finish up. STOP END PROGRAM 4 Istruzione di assegnazione • Il simbolo “=“ non è il simbolo di ugualianza ma di assegnazione • A=100 assegna ad A il valore 100 • I=I+1 aggiunge 1 al valore di I e assegna il risultato alla variabile I • A sinistra di = il nome di una variabile • A destra di = qualsiasi espressione valida Le istruzioni • Si può andare a capo con una istruzione mettendo il carattere “&” alla fine della riga • I caratteri che seguono, nella riga, il “!” vengono ignorati dal compilatore (COMMENTI!) • output=input1+input2 ! Somma i1 e i2 • output=input1 & ! meta’ istruzione +input2 • 898 output=input1+input2 • L’etichetta non induce un ordinamento delle istruzioni, serve solo a identificare l’istruzione! Operazioni tra reali • Le operazioni tra reali hanno come risultato numeri reali • Attenzione: numero reale non vuol dire appartenente a un continuo. In generale il risultato di una operazione è una approssimazione • 3./4.=0.75, 4./4.=1. • 1.+1e-16=1. Espressioni valide Valide Non Valide a+b*c a(b+c) -a a*-b (gfortran la accetta) a*(b+c) a**-4 (gfortran la accetta) 2**6 a*(b-f a+3.45**c Operazioni tra interi • Le operazioni tra interi hanno come risultato numeri interi • 3/4=0, 4/4=1, 19/5=3, 20/5=4, 21/5=4 • L’operazione eseguita sul risultato è un troncamento Ordine di precedenza • Regole simili all’algebra ordinara 1. Operazioni nelle parentesi da quelle interne a quelle esterna 2. Potenze da sx a dx 3. Prodotti e divisioni da sx a dx 4. Somme e sottrazioni da sx a dx • 1.e-8+1.e-8+1.e-8+1.e-8+1.e-8+1.e-8+1.e-8+1.e8+1.e-8+1.e-8+1.e-8+1. • 1.+1.e-8+1.e-8+1.e-8+1.e-8+1.e-8+1.e-8+1.e-8+1.e8+1.e-8+1.e-8+1.e-8 5 Operazioni miste Operazioni miste • In operazioni miste tra reali e interi i numeri interi vengono convertiti in reali • Bisogna però fare molta attenzione! La conversione avviene in ogni “sottocalcolo” • Elevamento a potenza richiede che l’esponente sia intero! • Altre relazioni vanno applicate per calcolare l’elevamento a potenza con esponenti reali • 1.+1/4=1. • 1.+1./4=1.25 – xy = eylnx • Usare conversioni esplicite: REAL(I), INT(A), NINT(A) Operazioni logiche Operazioni logiche • Variabili logiche del tutto analoghe alle variabili degli altri tipi • LOGICAL :: test1, test2 • test1=.true. Non confondere “=“ • test2=(a>b) con “==“!! • test2=test1 .or. (c<t) Il compilatore dovrebbe avvertire, • test1=(a==b) ma… • .and., .or., .eqv., .neqv., .not. • (.neqv. è chiamato xor nelle dispense) • Valutati dopo gli operatori aritmetici e relazionali (>, <, >=, <=, ==, /=) da sx a dx • “WRITE (*,*) test1” produce “T” o “F” se test1 è .true. o .false. (risp.) • WRITE (*,*) a==b Input/Output in Formato Libero Input/Output in Formato Libero • Input: READ (*,*) <lista di input> • <lista di input> lista di variabili separate da virgole • (*,*) dice di leggere da standard input in formato libero • Quello che viene letto dipende dal tipo delle variabili nella lista • • • • • INTEGER :: a REAL :: b CHARACTER(10) :: c READ (*,*) a,b,c Legge a di tipo intero, b di tipo reale e c di tipo stringa di caratteri di lunghezza 10 (troncandola se più lunga) 6 Input/Output in Formato Libero • WRITE (*,*) <lista di output> • <lista di output> lista di variabili e costanti separate da virgole • (*,*) dice di leggere su standard output in formato libero • Quello che viene scritto dipende dal tipo delle variabili e delle costanti nella lista Errori • Errori di compilazione: errori sintattici: – Errori di battitura – Il compilatore cerca di fornire messaggi amichevoli, indicando riga e colonna in cui l’errore si verifica, ma a volte possono essere fuorvianti • Errori al run-time: il programma si interrompe quando viene eseguito con qualche messaggio di errore – Conoscere il run-time system (l’ambiente di esecuzione) aiuta a eliminare questi errori Debug • Debug: ricerca e correzione degli errori (bug) • Errori in esecuzione e errori logici possono essere trovati inserendo delle istruzioni di stampa dei valori delle variabili utilizzate dal programma • Usare il debugger! Strumento molto flessibile ma anche di non immediata comprensione per i neofiti Input/Output in Formato Libero • • • • INTEGER :: a REAL :: b CHARACTER(10) :: c WRITE (*,*) a, ”Stringa”, b, 34, c Errori • Errori Logici: il programma esegue senza interrompersi ma i risultati sono scorretti – Errori nella progettazione – Errori di battitura • Operatori errati • Variabili sbagliate o non inizializzate • IMPLICIT NONE aiuta a limitare i danni • Più gli errori appaiono tardi nel processo, più sono difficili da individuare! Istruzione IF … IF (espr. logica) THEN istr. 1 istr 2. … END IF … 7 Istruzione IF … IF (espr. logica) THEN istr. 1 … ELSE istr. A … END IF … Esempio IF (a>3) THEN a=a-1 b=b+1 ELSE IF (A<3) THEN a=a+1 b=b+2 ELSE b=b+3 END IF Istruzione IF … [<nome>:] IF (espr. logica) THEN istr. 1 … ELSE [<nome>] istr. A … END IF [<nome>] … Istruzione IF … IF (espr. logica1) THEN istr. 1 … ELSE IF (espr. logica 2) THEN istr. A1 … ELSE istr. B1 … END IF … ELSE e ELSE IF vanno su righe separate e non etichettate Istruzione IF … [<nome>:] IF (espr. logica) THEN istr. 1 istr 2. … END IF [<nome>] … Istruzione IF … [<nome>:] IF (espr. logica1) THEN istr. 1 … ELSE IF (espr. logica 2) THEN [<nome>] istr. A1 … ELSE [<nome>] istr. B1 … END IF [<nome>] … 8 Esempio IF (a>3) THEN a=a-1 IF (b==5) THEN b=6 ELSE b=5 END IF ELSE IF (a<3) THEN a=a+1 END IF Ancora IF • • • • • IF (espressione) istruzione Non c’è THEN Una sola istruzione dopo l’espressione IF (a>max) max=a Equivale a: IF (a>max) THEN max=a END IF SELECT CASE • case_expr è una espressione il cui valore viene confrontato con i selettori • Un selettore specifica un lista di range, se case_expr è nel range di un selettore, il blocco di istruzioni corrispondente viene eseguito • Un range può essere specificato come – – – – valore esegue il blocco se case_expr==valore valore: esegue il blocco se case_expr>=valore :valore esegue il blocco se case_expr<=valore val1:val2 esegue il blocco se val1<=case_expr<=val2 Esempio esterno: IF (a>3) THEN a=a-1 interno: IF (b==5) THEN b=6 ELSE interno b=5 END IF interno ELSE IF (a<3) THEN esterno a=a+1 END IF esterno SELECT CASE [<nome>:] SELECT CASE (case_expr) CASE (selettore1) [<nome>] istr… … CASE (selettore 2) [<nome>] istr… … CASE DEFAULT [<nome>] istr… … END SELECT [<nome>] SELECT CASE INTEGER :: valore SELECT CASE (valore) CASE (1,2,3,5,7,11,13) WRITE (*,*) “Numero primo” CASE (4,6,8:10,12,14:15) WRITE (*,*) “Non primo” CASE (16:) WRITE (*,*) “Troppo grande” CASE DEFAULT WRITE (*,*) “ERRORE!” END SELECT 9 SELECT CASE Progettazione: metodo TOP-DOWN • Permette una maggiore chiarezza rispetto a usare IF-THEN-ELSE IF… • Un certo valore non può apparire in due istruzioni CASE • Le espressioni devono essere intere, logiche o caratteri singoli • Il nome può essere usato se si usano costrutti innestati o se i blocchi di istruzioni sono troppo lunghi • Dalla specifica del problema alla progettazione dell’algoritmo • Divisione del problema in sottoproblemi • Divisione dei sottoproblemi in sottoproblemi fino a che questi non siano ritenuti abbastanza semplici da essere risolti direttamente • Non esagerare nella frammentazione, il programma risultante potrebbe risultare illeggibile • Sfruttare la modularità Progettazione: metodo TOP-DOWN Progettazione: metodo TOP-DOWN • I sottoproblemi devono essere il più possibile indipendenti gli uni dagli altri • Le interfacce (I/O) tra i sottoproblemi devono essere definite in modo chiaro e robusto • Una volta definito il sottoproblema e la sua interfaccia si passa alla sua implementazione • Ogni sottoprogramma va testato indipendentemente dagli altri • Quando i sottoprogrammi sono stati testati si passa alla loro integrazione nel prodotto finito • Il processo può avvenire per passi successivi, ogni passo va però testato con un test di integrazione • Quando tutto il programma è stato prodotto viene eseguito il test di integrazione del programma La fase di specifica • Specificare il problema da risolvere è una componente molto delicata e, tipicamente, poco formale • Necessario specificare l’ingresso e l’uscita del programma • Sono spesso necessarie parecchie iterazioni per stabilire in modo rigoroso quale sia il problema da risolvere • Spesso la fase di definizione del problema prosegue anche in fase di sviluppo e di test Waterfall model Analisi dei requisiti Scomposizione in sottoproblemi Sviluppo delle componenti Test delle componenti Integrazione Test di integrazione Produzione e assistenza 10 Pseudocodice • Per specificare gli algoritmi in fase di progetto non si utilizza il linguaggio di programmazione • Alcuni costrutti linguistici ne sono derivati, come IF, DO, WHILE, etc. • L’assegnazione viene spesso indicata con per l’ambiguità tra l’uguaglianza e l’assegnazione (A 100 al posto di A=100) • L’importante è essere rigorosi ed evitare ambiguità! Diagrammi di flusso Inizio A B Leggi input Funzione 1 Funzione 2 Esegui istruzione Output Ouput .false. Se risultato > 0 B .true. Fine A CICLI • Sequenza di istruzioni da ripetere fino a che una determinata condizione si verifica • I cicli possono essere determinati (si conosce esattamente il numero di iterazioni) o indeterminati (il numero è ignoto a priori – ma finito) • I primi vengono detti cicli iterativi i secondi cicli while DO DO Istr. … IF (condizione) EXIT Istr. … END DO L’istruzione EXIT può essere usata come qualsiasi altra istruzione CICLI Può essere vuoto Istruzione Istruzione … Deve condurre a terminazione il ciclo! .true. Condizione Può essere vuoto .false. Istruzione Istruzione … Avere un solo punto di ingresso e un solo punto di uscita sarebbe auspicabile, ma spesso questa regola non si applica per non complicare ancora di più il programma DO Istr. … DO Istr. … IF (condizione) EXIT Istr. … END DO Istr. … END DO 11 esterno: DO Istr. … interno: DO Istr. … IF (condizione) EXIT esterno Istr. … END DO interno Istr. … END DO esterno DO iterativo [<nome>:] DO i=begin, end, step Istr. Corpo del ciclo (possono esserci EXIT) … END DO [<nome>] • Eseguito (end-begin+step)/step volte • Alla prima iterazione i prende il valore begin • Al termine di ogni itrazione i i+step • Il ciclo termina quando i*step<=end*step } PROGRAM primalita ! Testa se un numero e` primo INTEGER :: n, i ! n e` il numero, i e` l’indice di ciclo LOGICAL :: primo ! Vero se n e` primo WRITE (*,*) “Inserire numero” READ (*,*) n primo=.TRUE. DO i=2,n/2 ! Testa la divisibilita` di n con i if ((n/i)*i == n) primo == .FALSE. END DO IF (primo) THEN WRITE (*,*) n, “e` primo” ELSE WRITE (*,*) n, “non e` primo” END IF END PROGRAM primalita DO WHILE [<nome>:] DO WHILE (condizione) ! Cicla se vera Istr. … [EXIT [<nome>]] ! Possono esserci degli EXIT Istr. … END DO [<nome>] DO iterativo • Il valore di uscita della variabile indice è il primo valore che non soddisfa alla condizione i*step<=end*step • I valori di inizio, fine e incremento vengono fissati all’inizio del ciclo DO i=begin, end, step end=2*end ! Non ha effetto sul numero di iterazioni i=i+3 ! Segnala un errore in compilazione!!! … END DO Algoritmo di Euclide (GCD) • b|a => b=GCD(a,b) • a>b e se m=GCD(a,b) => m=GCD(a-b,b) – m|(a-b) per ipotesi – Se esistesse M>m tale che M=GCD(a-b,b), allora M|b e M|(a-b) => M|a => M>m=GCD(a,b) -> Contraddizione! – Sottraendo numeri piccoli da numeri grandi terminiamo l’algoritmo quando troviamo due numeri uguali 12 program euclide integer :: a,b,MCD write (*,*) "Inserire i due numeri" read (*,*) a,b write (*,*) "MCD tra ", a, "e", b, "e`: " do while ((a-b)/=0) if (a>b) then if (a<=0 .or. b<=0) then a=a-b write (*,*) "I numeri devono essere positivi" else stop b=b-a end if end if end do write (*,*) a stop end program euclide DO Istr. … DO Istr. … IF (condizione) CYCLE Istr. … END DO Istr. … END DO Funzioni intrinseche • Funzioni fornite dal linguaggio • Calcolano un valore (risultato) a partire dai valori dei suoi argomenti • Esempio: y=sin(x), dove x e y sono reali, y conterrà il seno di x. • Alcune funzioni restituiscono un risultato dello stesso tipo dei dati degli argomenti – Esistono funzioni specializzate per tipi specifici CYCLE e EXIT • EXIT [<nome>] può essere usata in qualsiasi tipo di ciclo • CYCLE [<nome>] fa partire la prossima iterazione del ciclo • Può essere usato in qualsiasi tipo di ciclo • Nei cicli iterativi CYCLE l’indice del ciclo viene incrementato Funzioni intrinseche • Fortran fornisce un grande numero di funzioni implicite (nel senso che non devono essere implementate dal programmatore, sono già disponibili) • Esempi: SIN, COS, LOG, LOG10, ABS,… • Esempio: ABS accetta ingressi reali o interi. Per esplicitare il tipo si può usare IABS per gli interi (pag. 539 del libro) Funzioni intrinseche INTEGER :: i REAL :: a ! Singola precisione REAL(4) REAL(8) :: b ! Doppia precisione COMPLEX :: c ! Complesso in singola precisione COMPLEX(8) :: d ! Complesso in doppia precisione ABS(i) è intero Alt. IABS(i) ABS(a) è reale s.p. Alt. ABS(a) ABS(b) è reale d.p. Alt. DABS(b) ABS(c) è reale s.p. Alt. CABS(c) ABS(d) è reale d.p. Alt. ZABS(d) 13 Esempio • Dati giorno, mese e anno determinare il giorno dell’anno corrispondente (da 1 a 366) • Input: 3 numeri interi (non prevediamo messaggi di errore nel caso di dati sbagliati) • Output: un numero intero compreso tra 1 e 366 • Progetto: sottoproblemi Esempio: input • giorno (intero) • mese (intero) • anno (intero) – Capire se un anno è bisestile o no (sottoproblema 1) – Sommare i giorni relativi ai mesi precedenti quelli della data in ingresso (sottoproblema 2) • Dato un mese, quanti giorni ha? (sottoproblema 3) – Sommare i giorni del mese corrente (sottoproblema 4) Esempio: sottoproblema 1 • Un anno è bisestile se – È divisibile per 400 – Altrimenti deve essere divisibile per 4 ma non per 100 • Altrimenti non è bisestile Esempio: sottoproblema 3 • Dato il mese quanti giorni ha? • I mesi hanno durate variabili – 30 giorni ha novembre (11) con aprile (4), giugno (6) e settembre (9) – Febbraio ne ha 28 o 28+1 nel caso di anno bisestile – I mesi 1, 3, 5, 7, 8, 10, 12 ne hanno 31 Esempio: sottoproblema 1 IF (MOD(anno, 400)==0) THEN bisestile = .true. ELSE IF ((MOD(anno, 4)==0) .and. & .not.(MOD(anno, 100)==0)) THEN bisestile = .true. ELSE bisestile = .false. END IF Esempio: sottoproblema 3 CASE SELECT (mese_corrente) CASE (4,6,9,11) giorni_mese=30 CASE (2) giorni_mese=28 if (bisestile) giorni_mese=giorni_mese+1 CASE (1,3,5,7,8,10,12) giorni_mese=31 END SELECT 14 Esempio: sottoproblema 2 giorni=0 DO mese_corrente=1,mese-1 Risolvi sottoproblema 3 giorni=giorni+giorni_mese END DO Esempio: sezione dichiarativa • INTEGER :: giorno, mese, anno ! Input • INTEGER :: giorni, giorni_mese ! Var. ausiliarie • LOGICAL :: bisestile Altre versioni? • Nel libro di testo si usa leap_day che vale zero o uno e va sommato ai giorni del mese di febbraio • Non si usa la variabile giorni ma direttamente giorno che viene incrementato del valore giusto • Di fatto due programmi calcolano la stessa funzione, e sono quindi del tutto equivalenti • Di norma si dovrebbe scegliere la realizzazione in base alle esigenze: in questo corso si preferisce la chiarezza del programma stesso! Esempio: sottoproblema 4 giorni=giorni+giorno Sottoproblema 4 revised bisestile = (MOD(anno,400)==0) .or. & ((MOD(anno, 4)==0) .and. & .not.(MOD(anno, 100)==0)) • Un programma deve raggiungere un compromesso tra chiarezza e sinteticità/efficienza • Questa formula è chiara o è meglio utilizzare gli IF? Caratteri CHARACTER :: c c=‘a’ ! Apici singoli e doppi sono intercambiabili CHARACTER(len=3) :: c c=‘a’ ! Completa c con degli spazi ‘a ‘ CHARACTER(3) :: c c=‘slide’ ! Prende solo le prime cifre c=‘sli’ 15 Caratteri: sottostringhe CHARACTER(9) :: a,b=‘certifico’ a=‘sincopato’ write (*,*) a(2:4) ! Stampa ‘inc’ a(5:8)=‘erat’ write (*,*) a ! Stampa ‘sincerato’ b(3:5)=a(2:7) write (*,*) b ! Stampa ‘ceincfico’ write (*,*) a(3:6) // b(5:7) ! Stampa ‘ncercfi’ Caratteri: confronti • ‘a’==‘a’ • ‘a’/=‘A’, ‘a’>’A’ • ‘Magno’ == ‘Magno’, ‘Magno’ < ‘magno’, ‘Magno’ > ’Magna’ • ‘Magnolia’ > ’Magno’ • ‘Carlo Magno’ < ‘CarloMagno’ Caratteri: confronti • I confronti vengono fatti in base all’ordinamento dei simboli nel set di caratteri del calcolatore • In genere si usa il codice ASCII: a ogni simbolo è associato un numero tra 0 e 255 • Le stringhe vengono confrontate da sinistra a destra carattere per carattere, il primo carattere diverso detta l’ordinamento tra le due stringhe • Quando si raggiunge la fine di una stringa, quella più lunga viene dopo quella corta nell’ordinamento Caratteri: funzioni • ACHAR(i) il carattere corrispondente a i • ICHAR(c) l’intero corrispondente al carattere c • LEN(str) la lunghezza (numero caratteri) della stringa str • LEN_TRIM(str) lunghezza di str senza gli spazi finali (a destra) • TRIM(str) la stringa str senza gli spazi finali • ADJUSTL, ADJUSTR, etc. 16