Pascal/Tipi di dati
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
modificaIl 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 ";".
Char
modificaFrequentemente 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.
Real
modificaLe 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:
Boolean
modificaL'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.
String
modificaLe 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
modificaOperatore | 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
modificaPascal 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:
< | 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
modificaAlcuni 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.
program secondi;
var giorni, ore, min, sec: integer;
totsecondi, totminuti, totore: longint;
begin
write('Introduci il tempo, espresso in secondi: '); readln(totsecondi);
totminuti := totsecondi div 60;
sec := totsecondi mod 60;
totore := totminuti div 60;
min := totminuti mod 60;
giorni := totore div 24;
ore := totore mod 24;
writeln(totsecondi, ' secondi equivalgono a ', giorni, ' giorno/i, ', ore, ' ora/e, ', min, ' minuti e ', sec, ' secondi.');
readln;
end.
- Scrivere un programma che faccia il contrario, converta cioè una misura espressa in giorni, ore, minuti e secondi in secondi.
program secondi2;
var giorni, ore, min, sec: integer;
totsecondi: longint;
begin
writeln('Introduci il tempo: ');
write(' giorni: '); readln(giorni);
write(' ore: '); readln(ore);
write(' minuti: '); readln(min);
write(' secondi: '); readln(sec);
totsecondi := sec;
totsecondi := totsecondi + min * 60;
totsecondi := totsecondi + ore * 60 * 60;
totsecondi := totsecondi + giorni * 60 * 60 * 24;
writeln(giorni, ' giorno/i, ', ore, ' ora/e, ', min, ' minuti e ', sec, ' secondi equivalgono a ', totsecondi, ' secondi.');
readln;
end.
- Scrivere un programma "dado" che simuli il lancio di un dado usando la funzione random.
program dado;
var d: integer;
begin
randomize;
d := trunc(random() * 6) +1;
writeln(d);
readln;
end.
Per trasformare il numero restituito da randomize in un numero da 1 a 6, abbiamo usato questo procedimento:
- il valore minimo che restituisce è quasi 0, mentre quello massimo è quasi 1
- quindi moltiplicando per 6, otterremo un numero che è compreso tra quasi 0 ancora e quasi 6, ma sempre minore
- per ottenere un numero intero, tronchiamo: avremo così un numero tra 0 e 5 inclusi
- a questo punto aggiungiamo 1, e siamo sicuri che il risultato sarà compreso tra 1 e 6 inclusi.
program convertitore;
uses crt;
var v, e, l: real;
begin
clrscr;
write('Introdurre il valore da convertire: ');
readln(v);
if v>0 then
begin
e:=v/1936.2;
l:=v*1936.27;
writeln(v:10:2, ' lire valgono ', e:10:2, ' euro');
writeln(v:10:2, ' euro valgono ', l:10:2, ' lire');
end
else
writeln('Dati non validi');
readln;
end.