Abbiamo accennato nelle pagine precedenti al fatto che l'elaboratore
elettronico è in grado di memorizzare i dati su cui opera in apposite celle
di memoria. Queste celle possono essere utilizzate con un linguaggio di
programmazione di alto livello, mediante l'uso delle variabili.
1.5.1. Variabili e tipi
Le variabili sono delle strutture in cui è possibile memorizzare dei
dati. L'uso delle variabili semplifica di molto l'accesso diretto alle
locazioni di memoria[3]. La memoria RAM di
un computer è un insieme molto grande di bit, che possono assumere il
valore di zero o uno (acceso o spento). Un gruppo di 8 bit costituisce un
byte; gruppi di due, tre, quattro, otto byte costituiscono una parola,
la cui lunghezza varia a seconda dell'architettura hardware della macchina (si
parla in questo caso di macchine a 16, 24, 32 o 64 bit).
Per rappresentare in notazione binaria un numero intero compreso tra 0 e 255,
sono necessari 8 bit (1 byte). Ogni carattere alfabetico e di punteggiatura può
essere codificato mediante un numero compreso tra 0 e 127, quindi per
rappresentare un carattere alfanumerico nella memoria di un computer è
sufficiente un byte. Per memorizzare una parola di 10 caratteri saranno
necessari 10 byte.
Esistono diversi tipi di dato che possono essere memorizzati all'interno di
un calcolatore elettronico, in particolare di solito distinguiamo i seguenti:
- numeri interi;
- numeri razionali, cioè i numeri ``con la virgola'' (floating
point);
- caratteri alfanumerici;
- stringhe (sequenze di caratteri alfanumerici);
- puntatori.
I puntatori sono un tipo di dato fondamentale in un linguaggio come il C. In
pratica un puntatore è una struttura dati che permette di memorizzare
l'indirizzo di memoria di un'altra variabile. In Perl non faremo uso di
puntatori, visto che non si accede mai direttamente alle locazioni di memoria
della macchina.
La maggior comodità nell'uso delle variabili sta nel non doversi preoccupare
(se non in casi particolari) della dimensione in bit del dato che intendiamo
trattare e nel poter attribuire un identificativo mnemonico (nome della
variabile) alle variabili stesse.
Così invece di dover lavorare a diretto contatto con le locazioni di memoria
e i loro indirizzi, per memorizzare un numero o una parola ci basterà assegnarla
ad una variabile: ``$a=13'', oppure ``$b="casa"'',
``$nome="Marco"'', ``$x=$y+$z-17'' e così via.
I linguaggi di programmazione tradizonali, come il Fortran, il Pascal o il
BASIC, richiedono che sia definita a priori il tipo di ogni variabile: se la
variabile ``a'' è di tipo numerico intero, non potrà contenere
null'altro che numeri interi; se la variabile ``b'' è una variabile
stringa, non potrà contenere altro che sequenze di caratteri alfanumerici.
Inoltre le operazioni consentite sulle variabili dipenderanno dal tipo di
variabili usate (ad esempio sarà possibile effettuare il prodotto tra due
numeri, ma non tra due stringhe).
In Perl (ma già in C è presente questo principio) i tipi di dato tendono a
confondersi; in ogni caso l'interprete del linguaggio si regola di volta in
volta in base al contesto. Ad esempio se imposteremo ``$a=3'', allora
vorrà dire che la variabile $a è intera, mentre impostando
``$a="gatto"'' comunicheremo automaticamente all'interprete che la
variabile $a in questo contesto è da considerarsi una stringa.
Un array è una struttura dati che ci permette di accedere ad un
insieme di variabili identificate da uno stesso nome. Un array ha una lunghezza
pari al numero di variabili di cui è costituito. Può essere comodo pensare ad un
array come ad una tabella costituita da una o più righe e da più colonne. Se
l'array è formato da un'unica riga allora si parlerà di vettore,
altrimenti parleremo di matrice.
Gli elementi dell'array (le variabili che lo costituiscono) sono identificate
dallo stesso nome dell'array e da uno o più indici, che indicano la posizione
dell'elemento all'intero del vettore o della matrice.
Ad esempio, pensiamo di voler memorizzare i nomi dei giorni della settimana
all'interno dell'array di tipo stringa chiamato giorno; avremo la
seguente struttura:
$giorno[0] = "lunedi'"
$giorno[1] = "martedi'"
$giorno[2] = "mercoledi'"
$giorno[3] = "giovedi'"
$giorno[4] = "venerdi'"
$giorno[5] = "sabato"
$giorno[6] = "domenica"
In Perl, come vedremo in seguito, gli indici degli elementi degli array
cominciano dal numero 0; se l'array ha n elementi, allora l'indice
dell'ultimo elemento sarà n-1.
1.5.3. Liste e grafi
Una lista è una struttura simile a quella di un vettore; a
differenza degli array, la lunghezza della lista può variare in ogni momento
aggiungendo o rimuovendo elementi; inoltre non è possibile raggiungere
direttamente un preciso elemento della lista stessa, perché gli elementi non
sono indicizzati come in un vettore: è necessario quindi scorrere la lista dal
primo elemento, fino a quando non viene identificato l'elemento desiderato.
Un grafo è una generalizzazione di una lista: nelle liste ogni
elemento ha un successore (escluso l'ultimo) ed un predecessore (escluso il
primo); in un grafo invece la struttura può essere molto più ``intricata'': un
elemento può avere più successori e più predecessori.
Fig. 4:
Esempio di lista e grafo
1.5.4. File
Quando si memorizza un dato su un supporto magnetico come un hard disk o un
nastro, o più in generale su un'unità di memoria di massa, lo si memorizza
utilizzando una struttura chiamata file. Un file è una sequenza di
byte; ai nostri fini un byte equivale ad un carattere. Il sistema non impone al
file nessun tipo di struttura e non assegna nessun significato al suo contenuto.
I byte assumono significato in funzione del programma che li interpreta .
Inoltre, come vedremo, tutto questo è vero non solo per i file su disco, ma
anche per le periferiche. I dischi, i messaggi di posta elettronica in partenza
ed in arrivo, i caratteri battuti sulla tastiera, l'output sul video del
terminale, i dati che passano da un programma all'altro attraverso i
pipe sono tutti visti dal sistema e dai programmi da esso gestiti come
file, ed in quanto tali non sono altro che sequenze di byte.
Per operare su di un file è necessario ``aprirlo'' associandogli un puntatore
(handler) per successivi riferimenti. Al termine delle operazioni sul
file, questo dovrà essere ``chiuso''; questa operazione implica la distruzione
del puntatore al file stesso.