Pascal/Tipi di dati

Indice del libro

In questo modulo analizzeremo i tipi di dati nativi di Pascal (che sono predefiniti e non richiedono l'uso di particolari librerie.

Ricordiamo che la dichiarazione di una variabile segue questa sintassi:

var
   nome : tipo;

Integer

modifica

Il tipo di dato più utilizzato è in genere il tipo integer. Corrisponde ai numeri interi, anche se non proprio a tutti; infatti, per via di problemi di memoria, non può memorizzare tutti i numeri: in Turbo Pascal comprende gli interi da -32768 a 32767 (in questo modo una variabile integer occupa una memoria di 16 bit - 2 byte), ma in altre versioni questo numero può essere maggiore.
Essendo il computer una macchina limitata, infatti, non è possibile fare somme fino all'infinito. Con alcuni semplici programmi si può osservare che esiste un limite superiore per gli interi, oltre al quale si ricade nel limite inferiore, come se fosse una circonferenza. Il fenomeno dello sforamento del limite massimo è detto overflow.

Ogni tipo di dato ha delle operazioni permesse. In questo caso le operazioni che danno come risultato un integer sono:

  • + permette di sommare due valori di tipo integer.
  • - permette di calcolare la differenza fra due valori integer.
  • * permette di moltiplicare due valori, ottenendo sempre un integer.
  • div permette di calcolare la parte intera del rapporto fra due interi.
  • mod permette di calcolare il resto della divisione fra due interi.

Le funzioni matematiche che danno come risultato un intero sono, invece

  • abs(n) che calcola il valore assoluto del numero intero n
  • round(n) che arrotonda qualunque numero all'intero più vicino ad n
  • trunc(n) che tronca il numero n alla parte intera (ad esempio trunc(3.7) restituisce 3,trunc(-3.7) restituisce -3)
  • sqr(n) ne calcola infine il quadrato.

Proviamo a fare un programma che utilizzi alcune operazioni. Ad esempio, il seguente programma valuta se un numero è pari o dispari:

program Pari;
var n:integer;
begin
     readln(n);
     if (n mod 2 = 0) then write ('pari')
                      else write ('dispari');
     readln;
end.

Il programma presenta alcuni costrutti che non abbiamo ancora visto, ma la cui interpretazione è semplice. Analizziamo come al solito riga per riga.

  • Come al solito la prima riga contiene la dichiarazione del titolo.
  • Dichiarazione di una sola variabile n di tipo intero.
  • Inizia il programma.
  • Assegniamo a n il valore 5.
  • Inizia un costrutto condizionale. Letto "alla lettera" significa "se il resto della divisione fra n e 2 è uguale a zero, allora scrivi pari altrimenti scrivi dispari". Da notare, lo rivedremo e faremo alcune considerazioni, che prima di else non va mai messo il ";".

Frequentemente si utilizzano invece degli integer i char, per rappresentare numeri interi piccoli. Infatti i char rappresentano il range di numeri interi che va da 0 a 255 - corrispondente ai codici ASCII - e permettono la visualizzazione nei due formati: intero, ascii. Le operazioni possibili sono le stesse degli integer, ma ci sono due funzioni in più che permettono la trasformazione da intero a carattere e viceversa. Queste funzioni sono

  • chr(x) che permette di trasformare l'intero x nel corrispondente carattere
  • ord(x) che permette di trasformare il carattere x nel corrispondente intero ASCII

Un semplice esempio di uso potrebbe essere la stampa della tabella dei codici ASCII.

program ASCII;
var n:integer;
begin
     for n:=0 to 255 do
     writeln(n, ' ==> ', chr(n));
end.

Come al solito analizziamo riga per riga.

  • Dichiarazione del programma,
  • Definizione della variabile n come char
  • Inizio del programma
  • Il costrutto for...to...do non l'abbiamo ancora visto, ma facendo come prima la traduzione letterale, possiamo intuirne il significato: Per n che va da 0 a 255 fai... È la traduzione in Pascal della struttura della ciclo o iterazione già vista nel modulo sugli algoritmi.
  • scriviamo su schermo il numero n seguito dai caratteri ==> e poi dal corrispondente carattere ASCII.

Per assegnare ad una variabile char un valore è necessario usare la notazione

 nome_variabile := 'carattere';

I due caratteri ' (carattere apice) identificano un valore alfanumerico e non numerico.

Le variabili di tipo real corrispondono ai numeri reali, ovvero i numeri con la virgola. Anche qui, come per gli integer, dobbiamo dare delle limitazioni. Essendo, come già sottolineato un computer una macchina limitata e discreta, inevitabilmente non può superare una certa precisione nel calcolo con i numeri reali. Per questo motivo spesso nelle strutture condizionate si devono cercare di utilizzare stratagemmi per evitare problemi.

Le operazioni di base possibili sembrano meno di quelle possibili con char e integer, ma attraverso l'utilizzo della libreria matematica aumentano in modo incredibile. Comunque le operazioni basilari sono:

  • + permette di sommare due valori di tipo real.
  • - permette di calcolare la differenza fra due valori real.
  • * permette di moltiplicare due valori, ottenendo sempre un real.
  • / permette di calcolare il rapporto fra due real.

Interne all'insieme dei reali troviamo ad esempio funzioni come:

  • sin(a) e cos(a): restituiscono il seno e il coseno dell'angolo a (espresso in radianti)
  • random: fornisce un numero casuale compreso tra 0 e 1 esclusi. Prima di usare questa funzione è bene usare randomize, che reinizializza il generatore di numeri casuali.

Boolean

modifica

L'algebra booleana è fondamentale nell'informatica. Questa permette infatti di fare calcoli sulla veridicità o falsità di una affermazione. Le variabili booleane infatti possono assumere solo i valori logici vero (true) e falso (false). Le operazioni possibili sono diverse da quelle possibili per gli altri tipi di variabile:

  • and che corrisponde al simbolo matematico   e al concetto di e contemporaneamente
  • or che rappresenta   e oppure
  • not operatore che corrisponde alla negazione
  • xor che corrisponde matematicamente all'aut (simbolo matematico  ), cioè il concetto di o uno, o l'altro, ma non tutti e due.

Le variabili di tipo booleano si dichiarano con la parola riservata boolean.

var 
 variabile_booleana:boolean;

Si inizializzano così:

 variabile_booleana:=true;
 {oppure} 
 variabile_booleana2:=false;
 variabile_2 := variabile_booleana or variabile_booleana2;
 variabile_3 := true or variabile_booleana2;
 variabile_4 := true xor false;
 {ma anche}
 num_pari := (n mod 2 = 0);

Potrebbe non essere immediata l'ultima espressione; il suo significato è: assegna alla variabile num_pari il valore dell'espressione n mod 2 = 0; questa espressione contiene un segno di uguaglianza (che è un operatore di confronto) e quindi restituisce vero o falso. L'utilizzo di variabili booleane è in genere limitato all'analisi di particolari aspetti dell'input da utente, o all'utilizzo come 'flag' nella programmazione più avanzata.

Le variabili string sono variabili che possono contenere una stringa alfanumerica di caratteri.

La dichiarazione di una variabile string ha sintassi:

 nome_della_variabile : string[n];

Ovvero afferma che la variabile nome_della_variabile può contenere una riga di massimo n caratteri.

Come per le variabili char, anche le variabili string necessitano una sintassi particolare per l'assegnazione: l'istruzione

 nome_variabile := 'Ma la volpe col suo balzo ha raggiunto il quieto fido 1234';

assegna a nome variabile la stringa alfanumerica (in questo caso Ma la volpe col suo balzo ha raggiunto il quieto fido 1234.

Nel caso si voglia inserire un carattere apice nella propria stringa (per inserire ad esempio un apostrofo) è necessario usare due apici di seguito. Un'istruzione come questa:

 writeln('L'unica soluzione...');

genera infatti un errore, poiché l'apostrofo tra La e unica è interpretato dal compilatore come un apice che delimita la fine della stringa. Un'istruzione invece come questa

 writeln('L''unica soluzione...');

è interpretata correttamente.

L'unico operatore possibile con il tipo string è l'operatore di concatenazione +, che è possibile capire con un esempio:

var1 := 'Ma la volpe col suo balzo ';
var2 := 'ha raggiunto il quieto fido';
var3 := var1 + var2 + ' 1234';

La variabile var3 alla fine di questo breve listato conterrà così il valore Ma la volpe col suo balzo ha raggiunto il quieto fido 1234, in quanto le stringhe sono state concatenate in una stringa unica.

Si noti lo spazio inserito prima dell'apice: senza lo spazio, le parole risulterebbero attaccate.

Una funzionalità interessante relativa alle stringhe è l'indicizzazione, per la quale è possibile fare riferimento ad un carattere all'interno della stringa, usando la notazione

variabile[n] {l'n-esimo carattere della stringa in variabile}

Riguardo alle stringhe, ricordiamo la funzione length che restituisce la lunghezza di caratteri della stringa passata come paramero.

Riassumendo

modifica
Operazioni, operatori e funzioni
Operatore Operandi Risultato
+ real o integer o char real o integer o char
- real o integer o char real o integer o char
* real o integer o char real o integer o char
/ real o integer o char real
mod integer o char integer
div integer o char integer
Funzione Argomento Risultato
sqr(x) real o integer o char integer
sqrt(x) real o integer o char real
abs(x) real o integer o char real o integer o char
trunc(x) real o integer o char integer
sin(x) e cos(x) real o integer o char real
random - real

Il significato di questi operatori e di queste funzioni è stato mostrato nei paragrafi precedenti. ad eccezione della funzione sqrt(n), che restituisce la radice quadrata di un n.

Operatori di confronto

modifica

Pascal mette a disposizione inoltre alcuni operatori di confronto che restituiscono sempre un valore booleano e che possono essere usati su due variabili qualsiasi dello stesso tipo di dato:

Gli operatori di confronto in Pascal
< minore
<= minore o uguale
= uguale
<> diverso - si può usare anche not(val1 = val2)
>= maggiore o uguale
> maggiore

È intuibile il loro funzionamento nell'ambito di variabili integer o real; questi operatori tuttavia possono essere anche usati sui tipi di dato char o string; più in particolare:

char1 < char2

è equivalente a scrivere

ord(char1) < ord(char2)

La comparazione tra valori string valuta invece le stringhe in ordine alfabetico (quindi saranno vere le espressioni come, ad esempio, 'abaco' < 'amico' o 'zaino' = 'zaino').

Per quanto riguarda i valori boolean, vale

false < true

e, quindi

true > false

Estensioni dei dati nativi

modifica

Alcuni compilatori moderni forniscono delle estensioni dei dati nativi, per ovviare ad esempio alla limitatezza degli integer: un esempio è il tipo di dato longint, disponibile in alcuni compilatori, che ha le stesse caratteristiche degli integer ma ammette numeri in un intervallo molto maggiore.

Esercizi

modifica
  • Scrivere un programma che prenda una misura di tempo in secondi e la scriva in giorni, ore, minuti e secondi.
  • Scrivere un programma che faccia il contrario, converta cioè una misura espressa in giorni, ore, minuti e secondi in secondi.
  • Scrivere un programma "dado" che simuli il lancio di un dado usando la funzione random.
  • Scrivere un programma che legga una valùta dall'utente e converta la misura in euro considerando la valute espressa in lire, e viceversa.