- Learn
- Guida Delphi
- I tipi (parte prima)
I tipi (parte prima)
- di Carlo Marona
Nelle sezioni precedenti del corso abbiamo visto, in particolare nelle sezioni che spiegavano gli operatori, cose come Integer, String, Boolean. Si tratta dei tipi di dati. Un tipo è essenzialmente un nome che identifica un particolare genere di dati. Un tipo determina anche il range di valori validi per quel tipo. Quando si definisce una variabile si deve specificarne il tipo.
L’Object Pascal è un linguaggio fortemente tipizzato. Ciò significa che distingue un gran numero di dati. Solitamente, questa caratteristica permette al compilatore di trattare i dati in maniera intelligente e di poter rilevare degli errori in fase di compilazione che altrimenti sarebbero difficili da diagnosticare.
Esistono diversi tipi di dati in Object Pascal; questi sono organizzati in tipi fondamentali (definiti direttamente dal linguaggio), generici, predefiniti e definiti dall’utente.
I tipi fondamentali sono implementati direttamente nel linguaggio Object Pascal; i loro formati e intervalli di validità sono gli stessi in tutte le implementazioni e sono indipendenti dalla CPU e dal sistema operativo. I tipi generici invece, possono variare da un’implementazione all’altra e sono specifici della piattaforma. È consigliabile l’utilizzo dei tipi generici in quanto facilitano il porting tra piattaforme differenti.
I tipi predefiniti sono automaticamente riconosciuti dal compilatore e non hanno necessità di essere dichiarati.
I tipi Object Pascal possono essere classificati come segue: simple, string, structured, pointer, procedural, variant.
I tipi Simple
I tipi simple definiscono insiemi ordinati di valori. Appartengono a questa categoria di tipi, i tipi ordinal e real.
I tipi ordinal
I tipi ordinal definiscono insiemi ordinati di valori in cui tutti i valori hanno un predecessore ed un successore univoci ad esclusione del primo valore e dell’ultimo. Sono tipi ordinal i tipi integer, boolean, character, subrange.
Ogni valore è caratterizzato da una ordinalità che ne determina l’ordinamento nel tipo. Solamente per il tipo integer l’ordinalità corrisponde con il valore stesso. In tutti gli altri tipi, ad esclusione del subrange, il primo valore ha ordinalità 0, successivo 1 e così a seguire. Delphi, o meglio l’Object Pascal, mettono a disposizione diverse funzioni predefinite che permettono di lavorare sulla ordinalità di questa categoria di tipi.
Le più importanti tra queste sono le seguenti:
Funzione | Valore restituito |
---|---|
Ord
|
restituisce l’ordinalità di un valore |
Pred
|
restituisce il predecessore del valore specificato |
Succ
|
restituisce il successore del valore specificato |
High
|
restituisce il valore più alto nel tipo |
Low
|
restituisce il valore più basso nel tipo |
Vediamo alcuni esempi: High(Byte) restituisce 255 in quanto il valore più alto del tipo è 255; Succ(4) è 5 poiché 5 è il successore di 4.
Esistono due funzioni deifnite in Object Pascal che che si usano per incrementare e decrementare il valore di una variabile ordinal e sono Inc e Dec. La prima incrementa il valore ed equivale al Succ del valore stesso, la seconda lo decrementa ed equivale al Pred del valore indicato.
I tipi Integer
I tipi Integer sono un sottoinsieme dei numeri interi. Esistono vari tipi di interi in Object Pascal che si differenziano per intervallo di valori rappresentabili e per formato. Per quanto riguarda i tipi interi generici abbiamo il tipo Integer e Cardinal. I tipi integer fondamentali sono: Shortint, Smallint, Longint, Int64, Byte, Word, Longword. Nella tabella seguente sono riportate le differenze tra i tipi menzionati.
Tipo | Intervallo | Formato |
---|---|---|
Integer | -2147483648..2147483647 | 32 bit + segno |
Cardinal | 0..4294967295 | 32 bit |
Shortint | -128..127 | 8 bit + segno |
Smallint | -32768..32767 | 16 bit + segno |
Longint | -2147483648..2147483647 | 32 bit + segno |
Int64 | -263..263-1 | 64 bit + segno |
Byte | 0.255 | 8 bit |
Word | 0..65535 | 16 bit |
Longword | 0..4294967295 | 32 bit |
Incrementando l’ultimo valore o decrementando il primo valore di un tipo integer il risultato sconfina all’inizio od alla fine dell’intervallo valido per quel tipo. Ad esempio, nel caso del tipo Byte che ha come intervallo 0..255 l’esecuzione del codice
var I : Byte;
…
I := High(Byte);
I := I + 1;
assegna ad I il valore 0. Da notare che se è stato attivato il controllo sugli intervalli, il codice precedente genererà un errore di runtime.
I tipi character
Fanno parte dei tipi ordinal anche i tipi character i cui tipi fondamentali sono AnsiChar e WideChar. Gli AnsiChar sono caratteri che occupano un byte (8 bit) mentre i tipi WideChar sono caratteri che occupano due byte ovvero una word (16 bit). Il rpimo tipo è ordinato secondo il set di caratteri esteso ANSI mentre il secondo è ordinato secondo il set UNICODE i cui primi 256 caratteri corrispondono ai caratteri ANSI.
Il tipi generico è Char che nell’implementazione corrente equivale ad AnsiChar.
Esistono anche per questo tipo delle funzioni predefinite dell’Object Pascal come la Chr che restituisce il carattere associato ad un intero compreso nell’intervallo AnsiChar o WideChar. Ad esempio Chr(65) restituisce ‘A’. Come per tutti i tipi ordinali, è possibile applicare al tipo character la funzione predefinita Ord che restituisce l’ordinale del valore character. Ad esempio, riprendendo l’esempio precedente, Ord(‘A’) restituisce 65 che è appunto l’ordinalità del carattere ‘A’ all’interno di AnsiChar o WideChar.
Valgono anche per i tipi character gli sconfinamenti come visto per i tipi integer.
I tipi Boolean
I tipi boolean predefiniti sono quattro e sono: Boolean, ByteBool, WordBool e LongBool. Si utilizza preferibilmente il tipo boolean mentre gli altri esistono per compatibilità con altri linguaggi e con l’ambiente Windows.
Una variabile boolean equivale a ByteBool ed occupa un byte (8 bit) mentre una WordBool occupa due byte (16 bit) ed una LongBool due word (32 bit). L’intervallo di valori per questo tipo è composto da due costanti predefinite che sono true e False.
Un valore boolean viene considerato true quando la sua ordinalità è diversa da zero. Da notare che se questo valore compare in un contesto in cui è atteso un valore boolean, questo viene automaticamente convertito dal compilatore in true la dove la sua ordinalità sia diversa da 0.
I tipi Enumerated
Il tipo enumerated serve a definire insiemi ordinati di valori. Da notare che l’ordinalità di questi valori segue l’ordine con cui sono stati elencati i valori al momento della dichiarazione del tipo.
Per dichiarare un tipo enumerated si utilizza la seguente sintassi
Type EnumeratedTypeName = (val1, val2, …, valn);
Un esempio pratico potrebbe essere la dichiarazione di un tipo enumersto “Seme” in un gioco di carte
Type Seme = (Cuori, Quadri, Fiori, Picche);
Nel caso del nostro esempio, i valori validi per il tipi “Seme” da noi dichiarato sono: Cuori, Quadri, Fiori, Picche. In pratica quando si dichiara un tipo enumerated si dichiarano delle costanti (val) del tipo enumerated dichiarato (EnumeratedTypeName). Sempre facendo riferimento al nostro esempio, Cuori, Quadri, Fiori, Picche sono costanti di tipo Seme.
Bisogna fare attenzione, al momento della dichiarazione del tipo, a non utilizzare, per gli identificatori dei valori, nome che possano andare in conflitto con altri nomi dichiarati nello stesso campo d’azione. Ad esempio, dichiarando un tipo
Type TSound = (Click, Clack, Clock);
ed utilizzando il valore Click come nel codice seguente, si verificherà un conflitto di nome; questo perché Click è anche il nome di un metodo della classe TControl e di tutti i sui discendenti (nel senso degli oggetti che discendono da esso!).
Procedure TForm1.Edit1Exit(Sender : TObject);
Var Snd : TSound;
Begin
…
Snd := Click;
…
End;
Si può aggirare questo tipo di inconveniente facendo riferimento al valore Click qualificandolo con il nome della unit in cui è stato dichiarato. Ammettiamo che il tipo TSound sia dichiarato nella unit SoundFuncs, si potrebbe utilizzare il seguente codice
Snd := SoundFuncs.Click;
Comunque, benché sia possibile utilizzare il codice precedente, si consiglia di cercare di definire, per i valori dei tipi eneumerated, dei nomi che non entrino in conflitto con altri identificatori. Una buona pratica è quella di anteporre al nome del valore enumerated le iniziali del nome del tipo enumerated. Nell’esempio precedente abbiamo dichiarato un tipo TSound; possiamo ridefinire i nomi dei suoi valori anteponendo “ts” al loro nome in questo modo
Type TSound = (tsClick, tsClack, tsClock);
Come anche
Type TMyType = (mtVal1, mtVal2, mtVal3);
I tipi Subrange
Come dice il nome stesso, questi tipi identificano dei sottoinsiemi di valori appartenenti ad un altro tipo ordinale che viene definito tipo base. Per definire un tipo subrange, si utilizza la seguente sintassi
Type SubrangeTypeName = Low..High;
dove Low ed High appartengono allo stesso tipo ordinal e Low è minore di High. Questo costrutto definisce quel sottoinsieme di valori compresi tra Low ed High.
Per esempio
Type PrimiDieciNumeri = 1..10;
definisce un tipo subrange di nome PrimiDieciNumeri che conterrà i valori 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.
Non valgono per questo tipo gli sconfinamenti visti per i tipi precedenti.
Se vuoi aggiornamenti su I tipi (parte prima) inserisci la tua email nel box qui sotto:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
La tua iscrizione è andata a buon fine. Se vuoi ricevere informazioni personalizzate compila anche i seguenti campi opzionali:
Compilando il presente form acconsento a ricevere le informazioni relative ai servizi di cui alla presente pagina ai sensi dell'informativa sulla privacy.
I Video di HTML.it
Costruire una pagina con Twitter Bootstrap – Parte 3
Dopo aver scaricato ed inserito tutti i componenti necessari per usare Bootstrap all’interno della nostra pagina web, sarà necessario utilizzare […]