- Learn
- Guida Delphi
- I tipi (parte seconda)
I tipi (parte seconda)
- di Carlo Marona
I tipi real
I tipi real definiscono insiemi di numeri che possono essere rappresentati con la notazione in virgola mobile.
I tipi real fondamentali sono riportati di seguito
Tipo | Intervallo | Cifre significative | Dimensione in byte |
---|---|---|---|
Real48 | 2.9 x 10-39..1.7 x 1038 | 11-12 | 6 |
Single | 1.5 x 10-45..3.4 x 1038 | 7-8 | 4 |
Double | 5.0 x 10-45..1.7 x 10308 | 15-16 | 8 |
Extended | 3.6 x 10-4951..1.1 x 104932 | 19-20 | 10 |
Comp | -263 + 1..263 – 1 | 19-20 | 8 |
Currency | -922337203685477.5808.. 922337203685477.5807 | 19-20 | 8 |
Il tipo real generico equivale al double.
Seguono alcune considerazioni sui tipi real fondamentali
- Il tipo Real48 viene mantenuto per compatibilità con il tipo real delle versioni precedenti di Object Pascal. Non essendo un tipo che utilizza un formato di memorizzazione non nativo per le CPU intel determina prestazioni più lente.
- Extended è il tipo real che permette maggiore precisione ma a sua volta è meno portabile.
- Il tipo Comp (computazionale) è nativo per le CPU Intel e rappresenta un integer a 64 bit. Pur essendo un tipo integer viene classificato come real in quanto non si comporta come tipo ordinal; non è infatti possibile incrementare o decrementare un valore comp. Viene mantenuto per compatibilità con le versioni precedenti. Al suo posto si consiglia l’uso del tipo Int64.
- Currency è un tipo di dati che viene utilizzato per i calcoli valutari poiché ne riduce al minimo gli errori di arrotondamento. È caratterizzato da punto decimale fisso e viene memorizzato come un integer a 64 bit scalato, con le ultime quattro cifre meno significative che rappresentano i decimali. Valori di questo tipo vengono automaticamente moltiplicati o divisi per 10000 quando vengono usati in espressioni con altri tipi real.
I tipi String
L’Object Pascal possiede, a differenza di altri linguaggi come ad esempio il C ed il C++, tipi di dati dedicato alla gestione dell stringhe. I tipi string supportati dall’Object Pascal sono i seguenti
Tipo | Lunghezza massima | Memoria richiesta | Usato per |
---|---|---|---|
ShortString | 255 caratteri | da 2 a 256 byte | compatibilità con versioni precedenti |
AnsiString | ~231 caratteri | da 4 byte a 2GB | caratteri a 8 bit (ANSI) |
WideString | ~230 caratteri | da 4 byte a 2GB | caratteri UNICODE; server e interfacce COM |
AnsiString è il tipo preferito per la maggior parte della applicazioni. A volte viene anche chiamato LongString.
I tipi string possono essere mischiati nelle assegnazioni e nelle espressioni in quanto il compilatore effettua automaticamente le conversioni del caso. Bisogna invece fare attenzione nel passaggio di parametri alle funzioni ed alle procedure che deve rispettare il tipo dei parametri dichiarati insieme alla funzione o procedura.
Il tipo generico per il tipo string è string. Non si tratta proprio di un tipo ma di una parola chiave del linguaggio che identifica un tipo di dati contenete una stringa. Come stato predefinito la parola chiave string si riferisce al tipo AnsiString (se non è seguita da un numero fra parentesi quadre). È possibile cambiare string in ShortString tramite la direttiva del compilatore {$H-}.
Anche per il tipo string esistono funzioni predefinite come Length che restituisce la lunghezza in caratteri di una stringa e SetLength che ne regola la lunghezza.
Due variabili di tipo string possono essere confrontate tramite gli operatori relazionali. In tal caso il confronto avviene confrontando l’ordinalità dei caratteri che occupano la stessa posizione. Ad esempio la stringa “AB” risulterà minore di “AC”. Confrontando stringhe di differente lunghezza, la dove i caratteri della stringa più lunga non hanno corrispondenza nella stringa più corta, vengono considerati maggiori. Di conseguenza la stringa “AB” risulterà maggiore della stringa “A”.
Una variabile string può essere indicizzata come se si trattasse di un array. I tal caso è possibile accedere i caratteri di una stringa utilizzando la seguente sintassi.
S[i] dove S è una variabile di tipo string e i un intero indicante la posizione all’interno della stringa S.
Per cui, S[2] := ‘A’ assegna alla posizione 2 della stringa S il carattere ‘A’.
Molta attenzione va fatta nella manipolazione delle stringhe tramite la tecnica vista in precedenza in quanto, in presenza di stringhe di tipo AnsiString o WideString che in realtà rappresentano stringhe terminate con null, la sovrascrittura dell’ultimo carattere (il null appunto) potrebbe causare un errore di violazione di accesso.
I tipi Short String
Come visto nella tabella dei tipi string, il tipo ShortString può essere lungo da 0 a 255 caratteri. Mentre la sua lunghezza varia dinamicamente, la memoria che occupa viene allocata staticamente e corrisponde a 256 byte; all’interno del primo byte è riportata la lunghezza in caratteri della stringa. Ne consegue che per ottenere la lunghezza di una stringa ShortString è possibile leggere il valore ordinale del carattere presente alla posizione 0 secondo la rappresentazione ad array. L’operazione Ord(S[0]) è equivalente a Length(S) dove S è una variabile string.
L’Object Pascal supporta anche dei sottotipi di ShortString la cui lunghezza varia da 0 a 255. Questi tipi vengono definiti specificando un numerale tra parentesi quadre dopo la parola chiave string. Per esempio
Type String50 = String[50];
definisce un tipo String50 la cui lunghezza massima è di 50 caratteri. Questo tipo di dichiarazione permette di risparmiare spazio in memoria poiché per contenere un variabile del tipo String50 verranno allocati solamente 51 byte a differenza dei 256 del tipo base ShortString.
I tipi Long String (AnsiString)
Come accennato in precedenza il tipo AnsiString viene anche definito LongString. Il tipo AnsiString rappresenta una stringa allocata dinamicamente la cui lunghezza massima è limitata solamente dalla memoria disponibile. Una variabile di questo tipo non è altro che un puntatore che occupa 4 byte. Il sistema utilizzato, totalmente gestito in maniera invisibile all’utente, è simile ad una lista di caratteri. Ciò permette appunto di avere una lunghezza dipendente solamente dalla memoria disponibile nel sistema. Un’altra caratteristica di questo tipo è che, trattandosi di puntatori, due o più variabili di questo tipo possono far riferimento allo stesso valore senza spreco aggiuntivo di memoria.
I tipi Wide String
L’allocazione di variabili di questo tipo è il medesimo di quello per variabili di tipo AnsiString con la differenza che le stringhe rappresentate utilizzano caratteri UNICODE a 16 bit. Si differenzia solamente per efficienza che risulta minore in quanto non utilizza accorgimenti come il contatore dei riferimenti utilizzato invece dal tipo AnsiString. Questo tipo è utilizzato prevalentemente per la compatibilità con i tipi nelle funzionalità COM.
I tipi strutturati
Fanno parte di questa categoria di tipi i Set, gli Array, i Record, i file oltre alle classi ed alle interfacce. Una istanza di tipo strutturato raccoglie sotto di se più valori. I tipi Set possono a loro volta contenere valori di tipo strutturato eccezion fatta per il tipo Set che può contenere solamente valori di tipo ordinale.
Set
Il tipo set implementa quello che in matematica viene definito insieme. Un set può contenere solamente valori dello stesso tipo ordinale senza seguire alcun ordinamento intrinseco. Altresì non ha significato che un elemento sia inserito due volte in un Set. L’intervallo di validità dei valori di un tipo Set dipende dall’intervallo di validità del tipo ordinal utilizzato per creare il Set. Questo tipo ordinale che origina il Set viene chiamato tipo base. Il costrutto utilizzato per dichiarare un tipo Set è il seguente
Set of TipoBase
Esempi di dichiarazione di tipi Set sono i seguenti:
Type TChars = ‘A’..’Z’;
TSetOfChars = Set of TChars;
Per assegnare dei valori a varibili di tipo Set, facendo riferimento all’esempio precedente, si procede come segue:
Var Caratteri : TSetOfChars;
…
Caratteri := [‘A’, ‘F’, ‘B’, ‘T’, ‘X’];
Con analogia alla matematica ed agl’insiemi, un tipo Set può essere vuoto e viene rappresentato con [].
Array
Gli array rappresentano una raccolta indicizzata di elementi tutti appartenenti ad uno stesso tipo che, come per i tipi Set, prende il nome di Tipo Base. A differenza dei tipi Set, un array può contenere, proprio perché indicizzato, più volte lo stesso valore. I tipi base utilizzabili nella dichiarazione di array, possono essere qualsiasi dai tipi ordinal ai tipi string, puntatori, altri array etc. Gli array possono essere dichiarati staticamente o dinamicamente ed essere mono o multi dimensionali. Un array monodimensionale rappresenta un vettore di elementi, mentre array multidimensionali rappresentano matrici di elementi.
Array statici
Il costrutto che si utilizza per dichiarare array statici è il seguente
array [TipoIndice1, …, TipoIndicen] of TipoBase;
Il numero di elementi che può contenere un array così definito è dato dal prodotto delle dimensioni dei TipoIndice racchiusi tra parentesi quadre.
Gli array monodimensionali o vettori, hanno un solo TipoIndice come in questo esempio
Type TVettore100 = Array [1..100] of Integer;
In questo esempio è stato definito un vettore che può contenere al massimo 100 valori integer.
Per accedere ai valori di una variabile array come sopra dichiarata si utilizza la sintassi MioVettore[50] dove MioVettore è il nome della variabile di tipo TVettore100 e 50 l’indice dell’elemento 50 all’interno dell’array. Quando si definisce una variabile di tipo array e non si assegnano valori a tutti gli elementi, gli elementi non assegnati vengono comunque allocati e conterranno valori non definiti.
Si possono anche dichiarare array multidimensionali come di seguito
Type TMatrice10X10 = Array [1..10, 1..10] of
Integer;
In questo caso è stato dichiarato un tipo TMatrice10X10 composto da 10 righe e 10 colonne. La dichiarazione precedente equivale a dichiarare un tipo array di array come di seguito
Type TMatrice10X10 = Array [1..10] of Array [1..10] of Integer;
Per accedere i valori di una variabile dichiarata come TMatrice10X10 si procede in maniera simile agli array monodimensionali tranne per il fatto che, essendo questi a più dimensioni, bisogna indicare un indice per ognuna delle dimensioni dell’array. Nel caso dell’esempio precedente MiaMatrice[2, 3], dove la variabile MiaMatrice è di tipo TMatrice10X10, accederà al valore contenuto alla riga 2 colonna 3 della matrice.
In Object Pascal sono definite funzioni per operare con gli indici e le dimensioni degli array statici. Con Low e High si ottiene rispettivamente il limite inferiore e quello superiore del primo tipo dell’array. Con Length si ottiene il numero di elementi nella prima dimensione dell’array.
Array dinamici
A differenza degli array statici, gli array dinamici non hanno dimensioni e lunghezza fisse e quindi la memoria viene riallocata quando si assegna un valore all’array o quando si utilizza la funzione SetLength per impostarne le dimensioni.
Per dichiarare deigli array dinamici si utilizza il costrutto
Type NomeTipo = Array of TipoBase;
Quando si dichara un array dinamico questo non occupa memoria fino a quando non si effettua una chiamata alla funzione SetLength.
Per esempio, se è stata dichiarata una variabile MioArray di tipo TMioArray = Array of Integer per creare effettivamente l’array in memoria effettuando la chiamata SetLength(MioArray, 100), si allocherà memoria per un array di 100 elementi integer. Da ricordare che l’indicizzazione degli array dinamici si basa sempre su integer e comincia da 0. In pratica gli array dinamici sono puntatori similmente ai LongString. Per disallocare un array dinamico, è possibile assegnare alla variabile che lo referenzi il valore Nil oppure passare la variabile stessa alla funzione Finalize; questo verrà disallocato solamente nel caso in cui non siano presenti altri riferimenti ad esso. Array di lunghezza 0 assumono il valore Nil.
Anche per gli array dinamici sono disponibili le funzioni standard Length, Low ed High. Queste restituiscono rispettivamente il numero di elementi dell’array, 0 in ogni caso, e l’indice superiore dell’array. Nel caso di array vuoti High restituisce -1. Interessante notare che si avrà in questo caso High < Low (-1 < 0).
Record
Per fare subito un confronto con altri linguaggi, tra cui C e C++, questo tipo corrisponde ai tipi struct (Struttura). Esso rappresenta un insieme di elementi eterogenei fra loro, ovvero un tipo record può raggruppare in se tipi diversi di elementi. Gli elementi di un record vengono detti campi; nella dichiarazione di un tipo record occorre specificare un nome per il tipo record ed un nome ed un tipo per ciascuno dei suoi campi. Ecco la struttura della dichiarazione di un record
Type NomeTipoRecord = Record
Campo1 : Tipo1;
…
Campon : Tipon;
End;
Come per gli array dinamici, la dichiarazione di una un tipo record, non alloca memoria per i campi in esso contenuti. La memoria viene allocata al momento della dichiarazione di una variabile di quel tipo record.
Un esempio di tipo record è
Type TPersona = Record
Nome : String[40];
Cognome : String[40];
Eta : Integer;
End;
Per accedere ai campi del record si utilizza la sintassi seguente
NomeVariabile.Nomecampo
Dall’esempio precedente
Var Persona : TPersona;
…
Persona.Nome := ‘Carlo’;
Persona.Cognome := ‘Marona’;
Persona.Eta := 25;
Se si devono accedere più volte i campi del record è possibile utilizzare il costrutto With..do nel modo seguente
With Persona do
Begin
Nome := ‘Carlo’;
Cognome := ‘Marona’;
Eta := 25;
End;
Quando si dichiara un tipo record, si ha la possibilità di inserire nella sua dichiarazione delle varianti alla sua struttura. Queste varianti vanno inserite dopo aver dichiarato tutti i campi del record. L sintassi è la seguente
Type NomeTipoRecord = Record
Campo1 : Tipo1;
…
Campon : Tipon;
Case SelettoreVariante : TipoOrdinale of
ListaCostanti1 : (Variante1);
…
ListaCostantin : (Varianten);
End;
Il SelettoreVariante è facoltativo; se si omette è necessario omettere anche i due punti successivi. Il SelettoreVariante deve essere di tipo ordinal.
Ogni ListaCostanti può essere composta da una costante dello stesso tipo di SelettoreVariante o da un elenco di costanti, sempre del tipo di SelettoreVariante, separate da virgole.
Ogni Variante è un elenco di dichiarazioni di con la stessa sintassi vista per la dichiarazione dei campi della parte principale del record.
Le parti variant dei record condividono lo stesso spazio di memoria. Si può leggere o scrivere nei campi variant dei record in qualsiasi momento, tenendo conto che se si scrive in un campo di un variant e subito dopo si scrive in un campo di un altro variant, i dati possono essere sovrascritti. Se si specifica il un SelettoreVariante, questo funziona come un campo normale nella parte principale del record. Per un trattazione più approfondita si rimanda alla guida al linguaggio.
Tipi file
I tipi file rappresentano un insieme ordinato di elementi tutti dello stesso tipo. Un tipo file viene dichiarato come segue
Type NomeTipoFile = File of Tipo;
dove NomeTipofile è un nome di identificatore valido e Tipo un tipo di dato qualsiasi di dimensioni fissate. Non possono essere utilizzati quindi nelle dichiarazioni di tipi file puntatori, array dinamici, long string, altri file o qualsiasi altro tipo strutturato che contenga uno qualsiasi dei tipi precedentemente elencati.
Con riferimento all’esempio per i tipi record possiamo dichiarare un tipo file come segue
Type TFileElenco = File of TPersona;
…
Var FileElenco : TFileElenco;
Dichiarare un tipo od una variabile facendo uso solamente della parola file darà origine ad un tipo di file non tipizzato, senza tipo.
Se vuoi aggiornamenti su I tipi (parte seconda) 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
Gian Maria Ricci
Quali sono gli strumenti più utili per piccoli team di sviluppo.