manuale ephic - capitolo 2

12
Ephic LA GUIDA UFFICIALE

Upload: giuseppe-criscione

Post on 19-Jun-2015

334 views

Category:

Sports


0 download

TRANSCRIPT

Page 1: Manuale Ephic - Capitolo 2

Ephic

LA GUIDA UFFICIALE

Page 2: Manuale Ephic - Capitolo 2

Capitolo 2

Strutture di datiderivate

e conversori

2

Page 3: Manuale Ephic - Capitolo 2

RecordNel precedente capitolo si è trattato delle variabili come contenitori di dati di un solo tipo. Un record invece consente di definire strutture formate da più variabili, che in questo caso vengono definite campi. Concettualmente ogni entità complessa può essere rappresentata con un record.

L’entità “Persona” può essere espressa come record che definiamo person. Il record person contiene i seguenti campi, che sono vere e proprie variabili (che quindi possiedono un nome, un tipo ed un valore):

Campo Nome Tipo Descrizione

Nome firstName string Rappresenta il nomeCognome lastName string Rappresenta il cognome

Età age integer Rappresenta l’età

Sesso gender bool Rappresenta il genere true = M, false = F

Nazionalità nationality string Rappresenta la nazionalità

Professione job string Rappresenta la professione‡ Il tipo bool per rappresentare il sesso di una persona può sembrare inappropriato, tuttavia nel prossimo paragrafo sarà messo in evidenza come creare un tipo di dati ad hoc più appropriato.

Il costrutto record si ha la seguente sintassi:

Sintassi:

record <nome>

record;

I campi si definiscono invece col costrutto var, presentato nel capitolo precedente:

record personvar firstName, lastName, nationality, job type stringvar age type integervar gender type boolrecord;

Nota: quando è necessario dichiarare allo stesso tempo più variabili dello stesso tipo, è possibile separare i vari nomi con delle virgole e dichiarare il tipo una sola volta alla fine.

Nota: poiché un record è un costrutto di livello pari ai metodi (vedi capitolo 6) va inserito fuori da essi, nel caso specifico, esso va messo prima o dopo method Main(), non al suo interno.

Dopo aver terminato la definizione del record, è possibile dichiarare variabili di tipo person di cui sarà possibile definire i campi.

Per creare una variabile che genera un’istanza di un oggetto (in questo caso del record) bisogna utilizzare il costruttore new.

Sintassi:

var <nome> type new <oggetto>

Se si vuole definire una variabile chiamata Hans che genera un’istanza dell’oggetto person definito precedentemente, si scriverà:

3

Page 4: Manuale Ephic - Capitolo 2

var Hans type new person

L’istruzione va inserita nel method Main(), dove in seguito verranno attribuiti i valori ai campi della variabile Hans che è collegata al record person.

Per accedere ai campi di un oggetto si utilizza il carattere punto (.) con la seguente sintassi:

Sintassi:

oggetto.campo

Una volta che si accede ad un campo, è possibile trattarlo come una variabile, quindi è possibile assegnarvi dei valori.

Con il seguente codice è possibile definire i valori dei campi dell’oggetto Hans precedentemente dichiarato:

Hans.firstName = "Hans Felix"Hans.lastName = "Ernst"Hans.age = 23Hans.gender = trueHans.nationality = "German"Hans.job = "Engineer"

In questo caso si sta accedendo ai campi in scrittura, infatti gli si sta assegnando un valore. E’ anche possibile accedere ai campi in lettura, ovvero senza modificare il valore che possiedono. Questo è utile, ad esempio, qualora si voglia stampare a schermo il valore dei campi dell’oggetto Hans:

WriteLine("Nome: " & Hans.firstName)WriteLine("Cognome: " & Hans.lastName)WriteLine("Nazionalità: " & Hans.nationality)WriteLine("Professione: " & Hans.job)WriteLine("Età: " & Hans.age)WriteLine("Sesso: " & Hans.gender & " (true = M, false = F)")

Il pezzo di codice sopra farà in modo di visualizzare a schermo il valore assunto dai campi dell’oggetto Hans.

Ecco quindi il codice del method Main()dell’applicazione che crea l’oggetto Hans e vi assegna i valori su cui è stata fatta luce nel corso del paragrafo.

method Main()var Hans type new personHans.firstName = "Hans Felix"Hans.lastName = "Ernst"Hans.age = 23Hans.gender = trueHans.nationality = "German"Hans.job = "Engineer"WriteLine("Nome: " & Hans.firstName)WriteLine("Cognome: " & Hans.lastName)WriteLine("Nazionalità: " & Hans.nationality)WriteLine("Professione: " & Hans.job)WriteLine("Età: " & Hans.age)WriteLine("Sesso: " & Hans.gender & " (true = M, false = F)")ReadKey()method;

4

Page 5: Manuale Ephic - Capitolo 2

Nota: qualora si abbiano problemi nella creazione dell’applicazione suggerita nel corso del capitolo, alla fine del testo è disponibile il codice sorgente in versione integrale.

Compilando ed eseguendo l’applicazione, a schermo verranno visualizzati tutti i valori assegnati all’ oggetto Hans.

EnumeratoriE’ emerso che nel record definito nel precedente paragrafo, il tipo bool per rappresentare il sesso di una persona può sembrare inappropriato. Sarebbe più appropriato definire una sorta di tipo in cui è possibile definire i valori maschio e femmina.

Gli enumeratori consentono di definire dei tipi ad hoc dove ogni valore è rappresentato da una singola parola.

La sintassi degli enumeratori (costrutto enum) è la seguente:

Sintassi:

enum <nome>valore1

valore2

...enum;

Nel nostro caso, si vuole definire un enumeratore genders che definisce il genere maschile e quello femminile:

enum gendersmalefemaleenum;

Nota: poiché anche un enumeratore è un costrutto di livello pari ai record e ai metodi (vedi capitolo 6) va inserito fuori da essi, nel caso specifico, esso va messo prima o dopo method Main(), non al suo interno.

All’interno del programma, genders viene riconosciuto come se fosse un tipo, quindi è possibile definire una variabile in questo modo:

var <nome> type <enum>

A questo punto è necessario modificare il record definito nel precedente capitolo in modo tale da utilizzare l’enumeratore genders:

record personvar firstName, lastName, nationality, job type stringvar age type integervar gender type gendersrecord;

Rispetto a come era stato definito in precedenza, è stato cambiato il tipo di dato della variabile gender che da bool è diventato genders.

5

Page 6: Manuale Ephic - Capitolo 2

Cambierà anche il modo in cui si assegna un valore al campo gender del record. Per assegnare un valore appartenente ad un enumeratore, bisogna scrivere prima il nome dell’enumeratore, poi separandolo col carattere punto, il valore interno all’enumeratore che deve essere assegnato alla variabile.

In poche parole, se si vuole assegnare il valore male al campo gender dell’oggetto Hans, bisognerà cambiare la riga:

Hans.gender = true

In una riga dove viene assegnato un valore del nostro enumeratore:

Hans.gender = genders.male

Dove genders indica l’enumeratore e male un valore interno ad esso.

Effettuando queste modifiche che fanno in modo di implementare il nostro enumeratore, compilando ed eseguendo il programma, si noterà che anziché comparire Sesso: true, compare Sesso: 0, questo è dovuto al fatto che il computer memorizza i valori di un enumeratore sottoforma di numeri, i quali non essendo ancora specificati sono stati attribuiti dal sistema a partire da zero in ordine decrescente, quindi genders.female avrà 1 come vero valore.

Fortunatamente è possibile esplicitare i valori ed assegnarli a piacimento, nel nostro caso, possiamo ampliare il nostro enumeratore inserendo valori che prima non avevamo considerato ovvero: sconosciuto e non specificato.

In accordo con la norma ISO 5218, che definisce una rappresentazione universale e codificata dei sessi, si hanno i seguenti valori:

Codice numerico Sesso corrispondente

0 Sconosciuto1 Sesso maschile

2 Sesso femminile

9 Sesso non specificato

Quindi l’enumeratore precedente dovrà essere definito in modo che ogni valore abbia il suo corrispondente numerico.

Per definire il valore numerico di un valore di un enumeratore bisogna inserirlo dopo il segno uguale.

Sintassi:

enum <nome>valore1 = numero1

valore2 = numero2

...enum;

Nel nostro specifico caso, ridefiniremo l’enumeratore precedente in questo modo:

enum gendersnotKnown = 0male = 1female = 2notApplicable = 9enum;

6

Page 7: Manuale Ephic - Capitolo 2

In ogni caso sarebbe superfluo esplicitare i valori dei primi tre elementi, poiché il computer li enumera automaticamente se non specificati. Se ad un certo punto viene definito un valore in un enumeratore, ed il successivo non viene esplicitato, il computer continuerà ad ogni modo nell’enumerare i valori, a partire dal numero del valore immediatamente precedente.

Avendo quindi un altro enumeratore fruits definito nel seguente modo:

enum fruitsbananakiwi = 7lemonapricot = 5enum;

Si ha che banana assume il valore 0 (il numero dal quale il computer inizia il conteggio), kiwi il valore 7, ma lemon che non ha un valore assegnato in modo esplicito, assumerà il valore successivo a 7, ovvero 8. Non è però necessario che i membri di un enumeratore siano disposti in ordine crescente, infatti apricot assume il valore 5, ma se non fosse stato esplicitato, avrebbe assunto il valore 9.

Leggere valori da tastieraNel capitolo precedente si è trattato della scrittura a schermo di valori tramite le istruzioni WriteLine e Write, ma non si è fatto però conto di come leggere un valore da tastiera.

La lettura di un valore da tastiera avviene in modo simile alla scrittura, esiste infatti l’istruzione ReadLine. Essa funziona in modo simile a WriteLine, infatti manda a capo il flusso di testo ed inizia a ricevere un valore in una nuova linea.

Bisogna dichiarare una variabile che ospiti il valore ricevuto da tastiera, poiché il testo ricevuto da tastiera è una stringa, il tipo della variabile deve essere string (vedi più avanti in questo capitolo), altrimenti verrebbe lanciata un’eccezione (capitolo 7).

Ecco una riga di codice dove viene dichiarata una variabile rd alla quale viene assegnato un valore letto da tastiera:

var rd type string = ReadLine()

Bisogna notare che ReadLine è un’istruzione che restituisce un valore, quindi è una funzione, al contrario di Write e WriteLine che sono metodi (vedi capitolo 6).

Ecco il method Main() di un’applicazione che legge un valore da tastiera e lo stampa a schermo:

method Main()var rd type string = ReadLine()WriteLine("Hai scritto: " & rd)ReadKey()method;

Premendo CTRL + F5 in DevEphic apparirà una console vuota, in realtà non lo è, infatti se si inserisce un valore e si preme INVIO apparirà a schermo il valore inserito preceduto da Hai scritto: :

7

Page 8: Manuale Ephic - Capitolo 2

Figura 1 – Programma che stampa a schermo un valore ricevuto da tastiera.

Infatti l’istruzione WriteLine stampa a schermo Hai scritto: concatenandolo con il valore della variabile rd, la quale ha assunto il valore di ciò che è stato immesso da tastiera.

ConversoriDi solito è poco utile ricevere valori da tastiera che siano stringhe, per esempio se si volesse creare un’applicazione che riceva due numeri interi e restituisca la loro somma, appare superfluo ricevere i due numeri come stringhe.

Non basta però cambiare solamente il tipo della variabile, infatti si genererebbe un’eccezione di tentata conversione di restringimento. Questo è dovuto al fatto che il tipo string contiene più dati del tipo integer e quindi nella conversione si perderebbero dei dati. Non genererebbe invece alcuna eccezione il tentativo di convertire un dato del tipo integer in uno del tipo decimal, questo perché decimal può contenere più dati di integer e dunque non si verifica alcuna perdita di dati (conversione di ampliamento).

Talvolta però è necessario effettuare conversioni di restringimento, e dunque è necessario introdurre i conversori:

Conversore Converte incBool BooleanocByte BytecInt InterocDec DecimalecStr StringacType Nel tipo indicato dal suo secondo parametro ‡

‡ I parametri sono introdotti nel capitolo 6, tuttavia al momento bisogna solo sapere che cType ha paradigma (vedi capitolo 6) cType(oggetto, tipo).

Nel caso specifico l’istruzione del paragrafo precedente che definiva una variabile rd che legge un valore da tastiera va riscritta in questo modo:

var rd type integer = cInt(ReadLine())

Nota: bisogna utilizzare le parentesi subito dopo un conversore per indicare su quale valore esso deve operare.

cInt indica la conversione del tipo del valore restituito dall’istruzione ReadLine, ovvero string nel tipo integer.

8

Page 9: Manuale Ephic - Capitolo 2

Definendo due variabili che assumono un valore intero da tastiera, si può infine creare un’applicazione che restituisce la loro somma, ecco il method Main():

method Main()WriteLine("Somma di valori inseriti da tastiera.")WriteLine("Inserisci il valore della prima variabile:")var n1 type integer = cInt(ReadLine())WriteLine("Inserisci il valore della seconda variabile:")var n2 type integer = cInt(ReadLine())WriteLine("La somma dei valori delle variabili è: " & n1 + n2)ReadKey()method;

Premendo CTRL + F5 in DevEphic apparirà un prompt dove verranno richiesti i valori per le variabili.

Nota: bisogna fare attenzione nell’inserire i valori, poiché seppure il conversore converta il valore in un intero, esso non riesce a convertire eventuali lettere inserite, quindi lancerebbe un’eccezione poiché è impossibile convertire alcuni caratteri della stringa.

Nota: se si vuole evitare l’eccezione che eventualmente potrebbe insorgere, basterebbe cambiare il conversore cInt nella funzione Val della libreria standard (vedi capitolo 12 per maggiori informazioni).

Figura 2 – Applicazione che stampa a schermo la somma di due variabili leggendone i valori da tastiera.

Inserendo i valori delle variabili, il programma mostrerà a schermo la somma.

StringheNei primi paragrafi di questo testo si è dato per scontato il significato della parola stringa. Una stringa è, infatti, una semplice sequenza di caratteri. Le stringhe possono essere trattate in svariati modi: Ephic contiene delle funzioni utili per gestire variabili del tipo string (vedi capitolo 12).

In questo capitolo verrà affrontato l’uso della funzione Format per la formattazione di oggetti in stringhe.

Formattare un oggetto in una stringa9

Page 10: Manuale Ephic - Capitolo 2

Formattare un oggetto significa renderlo conforme ad uno specifico formato, facendo in modo, per esempio, di definire con quante cifre decimali deve essere rappresentato un numero oppure rappresentare un valore di un enumeratore col suo vero nome, non con il numero corrispondente.

La funzione Format della libreria standard di Ephic consente di formattare un oggetto con la seguente sintassi:

Format(<strFormat>,<obj>)

Dove strFormat è la stringa di formato contenente la regola per la generazione della stringa formattata.

Le regole per la stringa di formato sono le seguenti:

Regola Formato numerico Formato enumerazione Formato data%d Nessuno Valore numerico Data breve ‡

%c Valuta ‡ Nessuno Nessuno%f Numero decimale ‡ Nome Data estesa ‡

%np Numero con p cifre decimali Nessuno Nessuno%x Numero intero esadecimale Numero esadecimale Nessuno%e Notazione scientifica Nessuno Nessuno%m Nessuno Nessuno Mese e giorno ‡

%y Nessuno Nessuno Anno e mese ‡

%r Nessuno Nessuno Formato RFC1123

‡ I risultati variano a seconda delle impostazioni internazionali del sistema corrente.

Si voglia ad esempio formattare una variabile di tipo decimal chiamata sqrt2 che contiene la radice di 2 (ottenuta con la funzione Root della libreria standard) in modo tale che venga rappresentata con soltanto le prime due cifre decimali.

Per fare questo basta usare il seguente codice:

var sqrt2 type decimal = Root(2)WriteLine(Format("%n2",sqrt2))

La stringa "%n2" stabilisce una regola di formattazione secondo la quale sqrt2 viene rappresentata con due cifre decimali (vedi tabella precedente), ovvero si ottiene il numero 1,41.

Se si prova a scrivere:

WriteLine(sqrt2)

Si ottiene invece la rappresentazione per esteso (con circa 13 cifre decimali) che è 1,4142135623731.

Utilizzando l’enumeratore genders precedente, si può fare in modo che venga rappresentato il valore di un enumeratore sottoforma di testo.

Per fare questo basta formattare il valore dell’enumeratore secondo la regola "%f":

WriteLine(Format("%f",genders.notApplicable))

Il codice precedente stampa a schermo il valore notApplicable; se non fosse stato formattato sarebbe stato visualizzato 9.

10

Page 11: Manuale Ephic - Capitolo 2

CommentiTalvolta è utile commentare il codice, cioè inserire un testo che non influisce in alcun modo nello svolgimento del programma, ma che per chi legge il codice potrebbe renderlo più chiaro.

Il testo commentato è preceduto da due caratteri cancelletto (##) .

WriteLine(Format("%x",65246)) ##Formatta il numero 65246 in esadecimale

Il testo in verde è il commento.

Non bisogna preoccuparsi di un eventuale calo di prestazioni dovuto ad un numero elevato di commenti, infatti in fase di compilazione non vengono considerati in alcun modo.

Esercizi di Riepilogo Definire un record film dove è possibile specificare titolo, paese, anno, durata (in minuti),

genere, regia e trama.

La scala Mohs definisce la durezza dei materiali tale che ad un numero più basso corrisponde un materiale più tenero e ad uno più alto un materiale più duro. Definire un enumeratore Mohs dove si annoverano i seguenti valori:

1. Talco

2. Gesso

3. Calcite

4. Fluorite

5. Apatite

6. Ortoclasio

7. Quarzo

8. Topazio

9. Corindone

10. Diamante

11