Sezione 1.2 Variabili. Tipi di dato. Costanti |
||
![]() |
L'utilità del programma "Salve gente" è alquanto dubbia. Abbiamo scritto diverse righe di codice, le abbiamo compilate e quindi abbiamo eseguito il programma risultante per ottenere soltanto una riga di stampa sullo schermo. Ma i programmi non servono soltanto a scrivere qualche frase sullo schermo, se fosse così sarebbe stato più facile e rapido scrivere direttamente la frase risultante sullo schermo. Per poter fare qualcosa di più interessante abbiamo bisogno di introdurre il concetto di variable .
Supponiamo che io vi dica di ricordare il numero 5 nella vostra memoria e poi vi dica di ricordare anche il numero 2. Allora voi avrete registrato due valori nella vostra memoria. Ora, se vi chiedo di sommare 1 dal primo numero voi memorizzerete 6 al posto di 5 come primo numero e quindi ricorderete i due valori 6 (5+1) e 2. A questo punto posso chiedervi di sottrarre i due valori e dirmi il risultato: il valore 4.
Il processo che avete eseguito è simile a quello che il calcolatore può effettuare usando due variabili. In C++ esso viene descritto dalle istruzioni:
Naturalmente questo è un esempio molto semplice che coinvolge soltanto due valori interi molto piccoli, ma un calcolatore può memorizzare milioni di valori ed effettuare operazioni matematiche molto complesse su di essi, il tutto ad una velocità inimmaginabile per una persona.a = 5;
b = 2;
a = a + 1;
risultato = a - b;
Possiamo quindi definire una variabile come una porzione di memoria in cui memorizzare un valore..
Ogni variabile necessita di un identificatore (un nome) che la distingue da ogni altra variabile, ad esempio nel codice precedente gli identificatori sono a , b e risultato , ma avremmo potuto chiamare le variabili con un qualsiasi altro nome inventato da noi, purchè esso sia un identificatore valido.
Un identificatore non deve contenere spazi o altri caratteri. Sono permessi soltanto lettere, cifre e simboli di sottolineatura. Inoltre, gli identificatori di variabile devono sempre iniziare con una lettera. Essi possono anche iniziare con il simbolo di sottolineatura ( _ ), ma questa possibilità viene di solito riservata per collegamenti esterni. In nessun caso un identificatore può iniziare con una cifra.
Un'altra regola da tener presente quando si scelgono gli identificatori è che essi non devono essere uguali ad una delle parole chiave del linguaggio nè ad una di quelle specifiche del compilatore usato, altrimenti gli identificatori potrebbero essere confusi con tali parole chiave. Le parole chiave del C++, secondo lo standard ANSI-C++, sono le seguenti:
asm, auto, bool, break, case, catch, char, class, const, const_cast, continue, default, delete, do, double, dynamic_cast, else, enum, explicit, extern, false, float, for, friend, goto, if, inline, int, long, mutable, namespace, new, operator, private, protected, public, register, reinterpret_cast, return, short, signed, sizeof, static, static_cast, struct, switch, template, this, throw, true, try, typedef, typeid, typename, union, unsigned, using, virtual, void, volatile, wchar_tPertanto queste parole non si possono usare come identificatori. Non si possono inoltre usare come identificatori alcuni nomi alternativi di operatori, da usare nel caso in cui la tastiera non contenga i simboli corrispondenti. Tali nomi sono:
and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor, xor_eqUn compilatore può includere anche qualche altro nome tra le parole riservate. Ad esempio alcuni compilatori che generano codice a 16bit (quali alcuni compilatori per DOS) includono anche le parole far, huge e near tra le parole chiave.
Molto importante: Nel linguaggio C++ le lettere maiuscole sono considerate caratteri diversi dalle corrispondenti lettere minuscole. Quindi, ad esempio, la variabile RISULTATO è diversa sia dalla variabile risultato che dalla variable Risultato .
La memoria di un calcolatore è suddivisa in byte. Il byte è la più piccola quantità di memoria che possiamo gestire, esso può contenere una relativamente piccola quantità di dati: di norma un singolo carattere o un intero fra 0 e 255. Ma il calcolatore può elaborare anche tipi di dato più complessi che occupano più di un byte. Ecco un elenco dei tipi fondamentali del C++ con l'indicazione della quantità di memoria necessaria e del rango di valori che si possono rappresentare:
TIPI DI DATO ELEMENTARI
Nome | Byte* | Descrizione | Rango* |
char | 1 | carattere o intero di 8 bit. | signed: -128 ... 127 unsigned: 0 ... 255 |
short | 2 | intero di 16 bit. | signed: -32768 ... 32767 unsigned: 0 ... 65535 |
long | 4 | intero di 32 bit. | signed:-2147483648 ... 2147483647
unsigned: 0 ... 4294967295 |
int | * | Intero. La sua lunghezza dipende dalla lunghezza del tipo word usato dal sistema operativo. Ad esempio, in MSDOS è di 16 bit mentre in sistemi a 32 bit (quali Windows 9x/2000/NT) è di 32 bit (4 bytes). | See short, long |
float | 4 | numero in virgola mobile. | 3.4e + / - 38 (7 cifre decimali) |
double | 8 | numero in virgola mobile in doppia precisione. | 1.7e + / - 308 (15 cifre decimali) |
long double | 10 | numero in virgola mobile in doppia precisione estesa. | 1.2e + / - 4932 (19 cifre decimali) |
bool | 1 | Valori Booleani. Può assumere uno dei due valori:
true o false. NOTA: è un tipo aggiunto recentemente allo standard ANSI-C++. Non tutti i compilatori lo accettano. |
true or false |
wchar_t | 2 | Carattere esteso. Viene usato per rappresentare tutti i
caratteri internazionali. NOTA: è un tipo introdotto recentemente nello standard ANSI-C++. Non tutti i compilatori lo accettano. |
caratteri estesi |
* I valori nelle colonne Byte e Range possono variare a seconda del sistema. I valori quì riportati sono quelli più comunemente accettati ed usati da quasi tutti i compilatori.
Oltre a questi tipi di dato fondamentali vi sono anche i puntatori ed il tipo void che vedremo in seguito.
int a;Sono dichiarazioni di variabili corrette. La prima dichiara una variabile di tipo int denotata dall'identificatore a . La seconda dichiara una variabile di tipo float denotata dall'identificatore numero . Una volta dichiarate, le variabili a e numero possono essere usate nel programma all'interno del loro campo di validità (lo scope ).
float numero;
Se vogliamo dichiarare più di una variabile dello stesso tipo possiamo farlo in una stessa riga indicando una sola volta il tipo e separando gli identificatori con la virgola. Ad esempio:
int a, b, c;dichiara tre variabili (a, b e c ) di tipo int , ed ha esattamente lo stesso significato di:
int a;I tipi di dato interi (char, short , long e int ) possono essere signed o unsigned a seconda del rango di numeri che si vuole considerare. Quindi per specificare un intero possiamo mettere una delle parole chiave signed o unsigned prima del nome del tipo. Ad esempio:
int b;
int c;
unsigned short NumeroDiFigli;Se non si specifica né signed né unsigned viene assunto signed . Quindi nella seconda dichiarazione avremmo potuto scrivere:
signed int IlMioSaldoBancario;
int IlMioSaldoBancario;con lo stesso significato e nel modo più comunemente usato (infatti la parola chiave non viene quasi mai usata).
L'unica eccezione a questa regola è il tipo char che è considerato diverso sia da signed char che da unsigned char.
Infine possiamo usare signed e unsigned come nomi di tipo con lo stesso significato di signed int e unsigned int rispettivamente. Le seguenti due dichiarazioni sono equivalenti:
unsigned AnnoDiNascita;Per capire come funziona una dichiarazione in un programma riconsideriamo il codice C++ dell'esempio sul nostro lavoro mentale che abbiamo proposto all'inizio della sezione:
unsigned int AnnoDiNascita;
// operazioni con le variabili |
4 |
tipo identificatore = valore_iniziale ;Ad esempio se vogliamo dichiarare una variabile a di tipo int con valore iniziale 0 possiamo scrivere:
int a = 0;Oltre a questo modo di inizializzare variabili (noto come stile C), vi è un altro modo di inizializzare le variabili più consono allo stile C++: racchiudendo il valore iniziale tra parentesi tonde
tipo identificatore(valore_iniziale );Ad esempio:
int a(0);Il C++ accetta entrambe le notazioni.
Resta comunque normalmente preferibile seguire le indicazioni del C per dichiarare le variabili in quanto è comodo, durante la fase di correzione del programma (debugging), avere le dichiarazioni raggruppate assieme: all'inizio di ogni funzione (per le variabili locali) o direttamente nel corpo del programma al di fuori di ogni funzione (variabili globali).
![]() Lo scopo delle variabili locali è invece limitato al blocco in cui sono dichiarate. Se sono dichiarate all'inizio di una funzione (come in main) il loro scopo è l'intero corpo della funzione. Quedto significa che se nell'esempio ci fosse un'altra funzione diversa da main(), le variabili locali dichiarate in main non sarebbero visibili all'interno di tale funzione e viceversa. In C++ lo scopo di una variabile locale
è limitato alla parte del blocco in cui esse sono dichiarate che
segue la dichiarazione stessa (un blocco è un gruppo di istruzioni
racchiuse tra parentesi graffe {}. Oltre allo scopo locale e globale esiste anche uno scopo esterno (external ) che non solo è visibile in tutto il file che contiene il programma ma è visibile anche in ogni altro file di programma che venga collegato con esso. |
Numeri Interi
1776sono letterali che denotano numeri interi decimali. Per scrivere una costante intera non occorre usare le virgolette (") o qualche altro carattere speciale. Non ci sono dubbi sul fatto che i letterali precedenti denotino delle costanti: quando scriviamo 1776 in un programma intendiamo proprio il valore 1776 e non altri.
+707
-273
Oltre ai numeri in notazione decimale (quella comunemente usata) il C++ accetta anche letterali che denotano numeri interi ottali (base 8) e numeri interi esadecimali (base 16). Per scrivere un numero in notazione ottale basta premettere il carattere 0 (carattere zero) e per scrivere un numero in notazione esadecimale occorre premettere i due caratteri 0x (zero e x). Ad esempio i seguenti letterali sono equivalenti:
Essi denotano lo stesso numero: 75 (settantacinque) espresso rispettivamente come numero in base 10, in base 8 e in base 16.75 // decimale
0113 // ottale
0x4b // esadecimale
Nota: le cifre decimali sono le usuali (0,1,2,3,4,5,6,7,8,9), le cifre ottali sono soltanto (0,1,2,3,4,5,6,7) mentre come cifre esadecimali usiamo (0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f).
Numeri in virgola mobile
Sono numeri con una parte frazionaria e/o un fattore esponenziale. Sono
rappresentati con letterali in cui compare il punto decimale che separa
la parte intera dalla parte decimale (noi usiamo la virgola ma nei paesi
anglosassoni si usa il punto) e/o un carattere e seguito
da un esponente intero (che si legge "per 10 alla X, dove X è l'intero
che segue il carattere e").
sono tutti letterali che rappresentano numeri in virgola mobile.3.14159 // 3.14159
6.02e23 // 6.02 x 1023
1.6e-19 // 1.6 x 10-19
3.0 // 3.0
Caratteri e stringhe
Vi sono anche dei letterali che rappresentano costanti non numeriche:
'z'I primi due rappresentano un singolo carattere mentre gli altri due rappresentano stringhe di diversi caratteri. Osserviamo che i letterali che rappresentano singoli caratteri sono racchiusi tra due caratteri apice (' ) mentre i letterali che rappresentano stringhe sono racchiusi tra due caratteri doppio apice ("). Questo è necessario per poter distinguere valori di tipo stringa da valori di tipo carattere (che sono considerati diversi). Inoltre, l'uso degli apici ( ' ) e ( " ) evita di confondere un letterale carattere o stringa da un identificatore o una parola chiave. Infatti in:
'p'
"Salve gente"
"Come state?"
xx denota la variabile x, mentre 'x' denota la costante di tipo carattere 'x' .
'x'
Per rappresentare con un letterale (o all'interno di un letterale stringa) alcuni caratteri speciale si usano notazioni particolari (i codici di escape). Ecco una lista di tali codici di escape (ognuno di essi inizia con il carattere barra rovesciata (\):
Ad esempio:
\n a capo riga \r ritorno carrello \t tabulazione \v tabulazione verticale \b backspace \f nuova pagina \a allerta (beep) \' apice singolo (' ) \" doppio apice (" ) \? punto interrogativo ( ?) \\ barra rovesciata ( \ )
'\n'Possiamo inoltre rappresentare ogni carattere del codice ASCII usando il suo codice numerico in ottale preceduto da una sbarra rovesciata (\) oppure il suo codice numerico in esadecimale preceduto da una sbarra rovesciata e un carattere x ( \x ). Ad esempio \23 e \37 rappresentano i caratteri ASCII di codice 19 e 31 mentre, usando la notazione esadecimale, i medesimi due caratteri si denotano con \x13 e \x1f .
'\t'
"Sinistra \t Destra"
"uno\ndue\ntre"
#define identificatore_di_costanteOvunque useremo l'identificatore, il preprocessore provvederà a sostituirlo con la costante. Ad esempio
#define PI 3.14159265Questo ci evita di dover riscrivere la stessa costante più volte in posti diversi del programma con la possibilità di commettere errori quali scrivere in qualche posto 3.14159365 invece di 3.14159265. Una volta che abbiamo associato un identificatore ad una costante possiamo usare tale identificatore in ogni punto seguente del programma come se esso fosse una costante. Ad esempio:
#define NEWLINE '\n'
#define WIDTH 100
circonferenza = 2 * PI * r;La direttiva #define non è una istruzione C++ ma una direttiva per il preprocessore. Essa deve quindi essere scritta in una sua propria riga e non deve essere aggiunto il carattere punto e virgola (;) alla fine.
cout << NEWLINE;
const int larghezza = 100;In realtà le costanti dichiarate sono semplicemente delle variabili il cui valore non può più essere modificato (il compilatore controlla che in nessun punto del programma compaia una assegnazione o una qualsiasi altra istruzione che può modificare il valore di una costante e in tal caso segnala un errore). Naturalmente, siccome una volta create non è più possibile cambiarne il valore, esse devono essere sempre inizializzate con un valore al momento della loro creazione.
const char tab = '\t';
const int cap = 12440;
![]() |
![]() 1-1. Struttura di un programma C++. |
![]() indice |
![]() 1-3. Operatori. |