next up previous contents index
Next: L'ingresso dei dati Up: Primi passi Previous: L'uscita dei dati   Indice   Indice analitico

Variabili e tipi

Introduciamo in questo paragrafo due concetti fondamentali per qualunque linguaggio di programmazione moderno, come il C++: tipo e oggetto. Un tipo è una struttura astratta avente delle proprietà particolari, mentre un oggetto è un qualcosa di concreto, il quale è di un certo tipo. La differenza, sebbene non sembri, è piuttosto sottile e diverrà sempre più chiara con il procedere nello studio del linguaggio. Come inizio, è sufficiente fornire una idea intuitiva di cosa essi siano, distaccandoci per il momento dalla programmazione: ``mela'' è un tipo, si tratta cioè di un concetto astratto che noi utilizziamo per riferirci agli oggetti ``mela'', che invece sono concreti: si può acquistare o mangiare un oggetto ``mela'', mentre tali operazioni sono prive di senso per il tipo ``mela''; esistono nel mondo tantissimi oggetti ``mela'' mentre la definizione astratta del tipo ``mela'' è univoca e ci permette di identificarne una quando la vediamo o tocchiamo. Normalmente non eseguiamo alcuna distinzione mentale tra tipi e oggetti, perché è il nostro cervello ad effettuare volta per volta i percorsi mentali appropriati: sappiamo in maniera del tutto automatica che ``I promessi sposi'' sono un romanzo, ma se vogliamo leggerlo dobbiamo procurarci un oggetto ``I promessi sposi''. Un tipo esiste anche senza che oggetti che lo rappresentino, ma non il contrario: possiamo definire il tipo ``elfo'', sebbene oggetti di tale tipo esistano solo nella mente degli scrittori di romanzi fantasy; al contrario un oggetto deve appartenere ad un tipo per avere una ragione di esistere, infatti quando vediamo qualcosa di ignoto siamo istintivamente portati a chiederci cosa esso sia, ossia in termini di un linguaggio di programmazione, di che tipo esso sia.

Ogni tipo permette in C++ delle operazioni sugli oggetti di tale tipo e ne vieta altre, avvertendoci in fase di compilazione; questo, che potrebbe sembrare un ovvio dettaglio, non lo è affatto, datosi che esistono numerosi linguaggi in cui ciò non avviente; non è il nostro caso, per cui se sommiamo un oggetto ``libro'' ad un oggetto ``mela'', oppure se estraiamo la radice quadrata da una copia di ``I promessi sposi'', mettiamo il compilatore nella impossibilità di effettuare la traduzione in linguaggio macchina. I primi tipi C++ che incontriamo sono alcuni dei tipi primitivi 2.4:

int numeri interi, negativi e positivi
double numeri reali
char caratteri
A proposito del tipo double, c'è da dire che numeri reali, intesi in senso matematico, non possono esistere all'interno di un calcolatore, per il semplice fatto che essi sono costituiti da un numero infinito di cifre decimali, mentre la memoria disponibile è finita; in realtà l'insieme di numeri che meglio rappresenta astrattamente il tipo double è l'insieme dei numeri razionali; all'interno del testo non terremo conto di questa sottigliezza ``tecnica'' matematica e faremo sempre riferimento a numeri reali.

Il primo oggetto di cui facciamo conoscenza è la variabile; una variabile è un oggetto di un certo tipo per il quale il nostro programma riserva una zona nella memoria centrale; in ogni momento possiamo cambiare il valore delle variabili, ma non possiamo cancellarle dalla memoria, ovvero non possiamo fare in modo che lo spazio da esse occupato venga utilizzato in altro modo. Le variabili vengono poi distrutte in maniera del tutto automatica dal programma, nel momento in cui esso termina. Vediamo come si usano le variabili nel seguente esempio:


// ex2_3_1.cpp
#include <iostream.h>
void main() {
   int i;
   int j = 19;
   i = -7;
   double pi = 3.14592; // pi greco, rapporto tra una
                        // circonferenza ed il suo diametro
   char c = 'a';
   cout << "i vale \t" << i << "\n";
   cout << "j vale \t" << j << "\n";
   cout << "pi vale \t" << pi << "\n";
   cout << "c vale \t" << c << "\n";
}

output:
i vale -7
j vale 19
pi vale 3.141592
c vale a

In tale esempio creiamo quattro variabili, ``scriviamo'' certi valori da noi scelti su di esse e infine li stampiamo; innanzitutto si noti che le variabili non vanno racchiuse da doppi apici in fase di stampa. Cominciamo l'analisi del nostro esempio con una importante osservazione: per le variabili i e j sono state utilizzate due sintassi differenti; la prima consiste nel creare la variabile, semplicemente scrivendo il suo nome preceduto dal tipo della variabile stessa, per poi assegnare ad essa un valore, mentre la seconda consiste nel compiere queste due operazioni con un unico statement. La differenza tra questi due modi di procedere è profonda e potrà essere compresa appieno solamente alla fine di questo corso; per il momento diamo solo le definizioni di queste due operazioni: assegnamento per la variabile i nello statement i = -7, inizializzazione per la variabile j nello statement int j = 19. Domanda che sorge spontanea è la seguente: quale valore ha i prima che le assegnamo un valore? La risposta è: nessuno; con lo statement int i il programma non fa altro che ``prenotare'' una zona della memoria centrale per una variabile intera, senza preoccuparsi minimamente di cosa vi si trovi, che in generale è privo di significato.

Ragionamento analogo può essere condotto per le variabili reali e carattere, con le seguenti precisazioni: per valori di tipo double si deve usare il punto (.) come separatore decimale (non la virgola, come siamo abitualmente abituati a fare); i valori di tipo char sono i caratteri della tastiera americana (lettere minuscole e maiuscole, cifre, segni di punteggiatura vari e altro, ma non vocali accentate o caratteri troppo nuovi, come il segno dell'Euro), i quali vanno racchiusi da singoli apici (' '). Un valore di tipo char può anche essere una sequenza di escape, che ugualmente è da racchiudere tra singoli apici. Ad esempio un programma che stampi due righe vuote è il seguente:


// ex2_3_2.cpp
#include <iostream.h>
void main() {
   char riga_vuota = '\n';
   cout << riga_vuota << riga_vuota;
}

Consideriamo ora il seguente esempio:


// ex2_3_3.cpp
#include <iostream.h>
void main() {
   int a = 5;
   cout << "a vale \t" << a;
   // int a = 7;     // SBAGLIATO: a esiste gia'
   a = 7;
   cout << "a vale \t" << a;
}

output:
a vale 5
a vale 7

Si noti dunque che non è possibile creare una variabile che abbia lo stesso nome di una che già esiste, di qualunque tipi esse siano, per la banale ragione che si creerebbero ambiguità all'interno di un programma, a meno che non la si crei all'interno di un blocco, che come abbiamo detto gode di una certa indipendenza dal resto del programma; le due variabili omonime in questo caso sono totalmente indipendenti l'una dall'altra, come nel seguente esempio:


// ex2_3_4.cpp
#include <iostream.h>
void main() {
   int a = 5;
   cout << "a =\t" << a << "\n";
   {
      int a = 7;
      cout << "a =\t" << a << "\n";
   }
   cout << "a =\t" << a << "\n";
}

output:
a = 5
a = 7
a = 5

Ci poniamo ora un problema spinoso: quale nome dare ad una variabile? Prima di tutto occorre darle un nome valido in C++, cioè una sequenza di caratteri maiuscoli, caratteri minuscoli, cifre decimali, carattere di sottolineatura (underscore:  _) che non inizi con una cifra. Inoltre, è convenzione universalmente accettata che i nomi delle variabili siano in caratteri minuscoli, tranne quando essi sono costituiti da più parole, nel qual caso si può utilizzare un carattere maiuscolo per l'iniziale della parole successive alla prima, oppure un carattere di underscore per separarle. Ecco qualche esempio commentato di possibili variabili:


int 		 1funzione 		 // non corretto 

int funzione1 // ok
char LETTERA // nome valido ma non
// corretto stilisticamente
char lettera // meglio
double piGreco // ok
double pi_greco // ok
double numerodinepero // valido ma illegibile
double numero_di_nepero // meglio
int I1ll1I // valido ma diabolico, si noti che I, 1, l
// sono praticamente indistinguibili
int nstis // pessimo: cosa vuol dire?
Int n_studenti_iscritti // meglio


next up previous contents index
Next: L'ingresso dei dati Up: Primi passi Previous: L'uscita dei dati   Indice   Indice analitico
Claudio Cicconetti
2000-09-06