Sei sulla pagina 1di 12

Tipi, Variabili, Costanti

Tipi delle variabili


Classificazione delle variabili in tipi Si dice che il C++ (come il C) un linguaggio "tipato", per il fatto che pretende che di ogni variabile venga dichiarato il tipo di appartenenza. Definizione di tipo di una variabile Il tipo un termine di classificazione che raggruppa tutte quelle variabili che sono memorizzate nello stesso modo e a cui si applica lo stesso insieme di operazioni. Controllo forte sui tipi Il C++ esercita un forte controllo sui tipi (strong type checking), nel senso che regola e

limita la conversione da un tipo all'altro (casting) e controlla l'interazione fra variabili di tipo diverso.

Tipi intrinseci del linguaggio


In C++ esistono solo 5 tipi, detti "intrinseci o "nativi" del linguaggio : int char float double bool numero intero di 2 o 4 byte numero intero di 1 byte (interpretabile come codice ascii di un carattere) numero in virgola mobile con 6-7 cifre significative (4 byte ) numero in virgola mobile con 15-16 cifre significative (8 byte ) valore booleano: true o false (1 byte )

In realt il numero di tipi possibili molto pi grande, sia perch ogni tipo nativo pu essere specializzato mediante i qualificatori di tipo, sia perch il programma stesso pu creare propri tipi personalizzati (detti "tipi astratti")

Dichiarazione e definizione degli identificatori


Cos' un identificatore ? Un identificatore un nome simbolico che il programma assegna a un'entit del linguaggio, per modo che il compilatore sia in grado di riconoscere quell'entit ogni volta che incontra il nome che le stato assegnato. Sono pertanto identificatori i nomi delle variabili, delle funzioni, degli array, dei tipi astratti, delle strutture, delle classi ecc... Ogni identificatore consiste di una sequenza di lettere (maiuscole o minuscole) e di cifre numeriche, senza caratteri di altro tipo o spazi bianchi (a parte l'underscore "_", che considerato una lettera). Il primo carattere deve essere una lettera.

Non sono validi gli identificatori che coincidono con le parole-chiave del linguaggio (come da Tabella sotto riportata). Esempi di identificatori validi: hello deep_space9 a123 _7bello Esempi di identificatori non validi: un amico un'amica 7bello for Tabella delle parole-chiave del C++ auto catch const_class do enum float if main operator register signed struct throw typeid using wmain bool char continue double explicit for inline mutable private reinterpret_class sizeof switch true typename virtual while break class default dynamic_cast extern friend int namespace protected return static template try union void case const delete else false goto long new public short static_cast this typedef unsigned volatile
(contiene uno spazio)

(contiene un apostrofo) (il primo carattere non una lettera) ( una parola-chiave del C++)

Dichiarazione obbligatoria degli identificatori In C++ tutti gli identificatori di un programma devono essere dichiarati prima di essere utilizzati (non necessariamente all'inizio del programma), cio deve essere specificato il loro tipo. Per dichiarare un identificatore bisogna scrivere un'istruzione apposita in cui l'identificatore preceduto dal tipo di appartenenza. Es. int Variabile_Intera;

Pi identificatori dello stesso tipo possono essere dichiarati nella stessa istruzione e separati l'uno dall'altro da una virgola. Es. int ore, giorni, mesi;

Definizione obbligatoria degli identificatori Un'istruzione di dichiarazione si limita ad informare il compilatore del C++ che un certo identificatore appartiene a un certo tipo, ma pu non essere considerata in fase di esecuzione del programma. Quando una dichiarazione comporta anche un'operazione eseguibile, allora si dice che anche una definizione. Per esempio, l'istruzione: extern int error_number; soltanto una dichiarazione, in quanto (come vedremo pi avanti) con lo specificatore extern informa il compilatore (o meglio il linker) che la variabile error_number definita in un altro file del programma (e quindi l'istruzione serve solo ad identificare il tipo della variabile e a permetterne l'utilizzo); mentre l'istruzione: int error_number; anche una definizione, in quanto non si limita ad informare il compilatore che la variabile error_number di tipo int, ma crea la variabile stessa, allocando un'apposita area di memoria. Per meglio comprendere la differenza fra dichiarazione e definizione, si considerino le seguenti regole: tutte le definizioni sono anche dichiarazioni (ma non vero il contrario); deve esserci una ed una sola definizione per ogni identificatore che appare nel programma (o meglio, per ogni identificatore che appare in uno stesso ambito, altrimenti si tratta di identificatori diversi, pur avendo lo stesso nome), mentre possono esserci pi dichiarazioni (purch non in contraddizione fra loro); un identificatore deve essere dichiarato prima del suo utilizzo, ma pu essere definito dopo (o altrove, come abbiamo visto nell'esempio precedente); la semplice dichiarazione (cio senza specificatore) di una variabile di tipo nativo sempre anche una definizione, in quanto comporta l'allocazione di un'area di memoria;

Qualificatori e specificatori di tipo

Definizione di "qualificatore" e "specificatore" Un qualificatore di tipo una parola-chiave che, in una istruzione di dichiarazione, si premette a un tipo nativo, per indicare il modo in cui la variabile dichiarata deve essere immagazzinata in memoria. Se il tipo omesso, sottointeso int. Esistono 4 qualificatori: short, long, signed, unsigned. Uno specificatore una parola-chiave che, in una istruzione di dichiarazione, si premette al tipo (che pu essere qualsiasi, anche non nativo) e all'eventuale qualificatore, per definire ulteriori caratteristiche dell'entit dichiarata. Esistono svariati tipi di specificatori, con funzioni diverse: li introdurremo via via durante il corso, quando sar necessario. Qualificatori short e long I qualificatori short e long si applicano al tipo int. Essi definiscono la dimensione della memoria occupata dalle rispettive variabili di appartenenza. Purtroppo lo standard non garantisce che tale dimensione rimanga inalterata trasportando il programma da una piattaforma all'altra, in quanto essa dipende esclusivamente dalla piattaforma utilizzata. Possiamo solo dire cos: a tutt'oggi, nelle implementazioni pi diffuse del C++ , il qualificatore short definisce variabili di 16 bit (2 byte) e il qualificatore long definisce variabili di 32 bit (4 byte), mentre il tipo int "puro" definisce variabili di 32 bit (cio long e int sono equivalenti). Vedremo fra poco che esiste un operatore che permette di conoscere la effettiva occupazione di memoria dei diversi tipi di variabili. Per completezza aggiungiamo che il qualificatore long si pu applicare anche al tipo double (la cosidetta "precisione estesa"), ma, da prove fatte sulle macchine che generalmente usiamo, risultato che conviene non applicarlo ! Qualificatori signed e unsigned I qualificatori signed e unsigned si applicano ai tipi "interi" int e char. Essi determinano se le rispettive variabili di appartenenza possono assumere o meno valori negativi. E' noto che i numeri interi negativi sono rappresentati in memoria mediante l'algoritmo del "complemento a 2" (dato un numero N rappresentato da una sequenza di bit, -N si rappresenta invertendo tutti i bit e aggiungendo 1). E' pure noto che, in un'area di memoria di m bit, esistono 2m diverse possibili configurazioni (cio un numero intero pu assumere 2m valori). Pertanto un numero con segno ha un range (intervallo) di variabilit da -2m-1 a +2m-1-1, mentre un numero assoluto va da 0 a +2m-1. Se il tipo int, i qualificatori signed e unsigned possono essere combinati con short e long, dando luogo, insieme a signed char e unsigned char, a 6 diversi tipi interi possibili. E i tipi int e char "puri" ? Il tipo int sempre con segno (e quindi signed int e int sono equivalenti), mentre, per quello che riguarda il tipo char, ancora una volta dipende dall'implementazione: "in generale" (ma non sempre) coincide con signed char.

L'operatore sizeof
L'operatore sizeof(operando) restituisce la lunghezza in byte di identificatori appartenenti a un dato tipo; operando specifica il tipo in esame o un qualunque identificatore dichiarato di quel tipo. Per esempio, sizeof(int) pu essere usato per sapere se il tipo int di 2 o di 4 byte.

[p04]
Confronto dei risultati fra diverse architetture

Lunghezza della voce di memoria in byte

PC (32 bit) tipo

PC (32 bit) DEC ALPHA (64 bit) con Unix 1 2 4 8 4 8 16 1

con Windows con Linux char short int long float double long double bool 1 2 4 4 4 8 8 1 1 2 4 4 4 8 12 1

Definizione con Inizializzazione


Abbiamo visto finora che ogni dichiarazione o definizione di un identificatore consiste di tre parti: uno o pi specificatori (opzionali); il tipo (eventualmente preceduto da uno o pi qualificatori); l'identificatore. NOTA Per completezza aggiungiamo che a sua volta l'identificatore pu essere preceduto (e/o seguito) da un "operatore di dichiarazione". I pi comuni operatori di dichiarazione sono: * *const & [] () puntatore puntatore costante riferimento array funzione prefisso prefisso prefisso suffisso suffisso

Ne parleremo al momento opportuno. Esiste una quarta parte, opzionale, che si chiama inizializzatore (e che si pu aggiungere

solo nel caso della definizione di una variabile): un inizializzatore un'espressione che definisce il valore iniziale assunto dalla variabile, ed separato dal resto della definizione dall'operatore "=". Quindi, ricapitolando (nel caso che l'identificatore sia il nome di una variabile): la semplice dichiarazione assegna un tipo alla variabile; la definizione crea la variabile in memoria, ma non il suo contenuto, che rimane, per il momento, indefinito (forse resta quello che c'era prima nella stessa locazione fisica di memoria) ; la definizione con inizializzazione attribuisce un valore iniziale alla variabile definita. Es. unsigned peso = 57;

n.b. un'inizializzazione concettualmente diversa da un'assegnazione


In C++ i valori di inizializzazione possono essere dati non solo da costanti, ma anche da espressioni che includono variabili definite precedentemente. Es. int lordo = 45; int tara = 23; int netto = lordo-tara;

Il tipo "booleano"
Il tipo bool non faceva parte inizialmente dei tipi nativi del C e solo recentemente stato introdotto nello standard del C++. Una variabile "booleana" (cio dichiarata bool) pu assumere solo due valori: true e false. Tuttavia, dal punto di vista dell'occupazione di memoria, il tipo bool identico al tipo char, cio occupa un intero byte (anche se in pratica utilizza un solo bit). Nelle espressioni aritmetiche e logiche valori booleani e interi possono essere mescolati insieme: se un booleano convertito in un intero, per definizione true corrisponde al valore 1 e false corrisponde al valore 0; viceversa, se un intero convertito in un booleano, tutti i valori diversi da zero diventano true e zero diventa false. Esempi: bool b = 7; int i int i = true; = 7 < 2; ( b inizializzata con true ) ( i inizializzata con 1 ) ( espressione falsa: i inizializzata con 0 )

Le Costanti in C++
Costanti intere Una costante intera un numero decimale (base 10), ottale (base 8) o esadecimale (base 16) che rappresenta un valore intero positivo o negativo. Un numero senza prefissi o suffissi interpretato in base decimale e di tipo int (o unsigned int se la costante specificata maggiore del massimo numero positivo signed int). La prima cifra del numero non deve essere 0. Un numero con prefisso 0 interpretato in base ottale e di tipo int (o unsigned int). Es. a = 0100; (in a memorizzato il numero 64) Un numero con prefisso 0x o 0X interpretato in base esadecimale e di tipo tipo int (o unsigned int). Le "cifre" a,b,c,d,e,f possono essere scritte sia in maiuscolo che in minuscolo. Es. a = 0x1B; (in a memorizzato il numero 27) In qualunque caso, la presenza del suffisso L indica che il numero deve essere di tipo long int, mentre la presenza del suffisso U indica che il numero deve essere di tipo unsigned int. Es. a = 0x1BL; a = 0x1BU; Costanti in virgola mobile Una costante in virgola mobile un numero decimale (base 10), che rappresenta un valore reale positivo o negativo. Pu essere specificato in 2 modi: parte_intera.parte_decimale (il punto obbligatorio) notazione esponenziale (il punto non obbligatorio) Esempi: 15.75 -1.5e2 25E-4 10.

In qualunque notazione, se il numero scritto senza suffissi, assunto di tipo double. Per forzare il tipo float bisogna apporre il suffisso f (o F) Es. 10.3 di tipo double 1.4e-5f di tipo float Costanti carattere Una costante carattere rappresentata inserendo fra singoli apici un carattere stampabile oppure una sequenza di escape. Esempi: 'A' carattere A '\n' '\003' carattere newline carattere cuoricino

In memoria un carattere rappresentato da un numero intero di 1 byte (il suo codice ascii). Le conversioni fra tipo char e tipo int sono automatiche (purch il valore intero da convertire sia compreso nel range del tipo char) e quindi i due tipi possono essere mescolati insieme nelle espressioni aritmetiche. Per esempio, l'operazione: MiaVar = 'A' + 1; ammessa, se la variabile MiaVar stata dichiarata int oppure char. Il carattere NULL ha codice ascii 0 e si rappresenta con '\0' (da non confondere con il carattere 0 decimale che ha codice ascii 48). Costanti stringa Una costante stringa rappresentata inserendo un insieme di caratteri (fra cui anche sequenze di escape) fra doppi apici (virgolette). Es. "Ciao Universo\n" In C++ (come in C) non esistono le stringhe come tipo intrinseco. Infatti esse sono definite come sequenze (array) di caratteri, con una differenza rispetto ai normali array: il compilatore, nel creare una costante stringa, aggiunge automaticamente un NULL dopo l'ultimo carattere (si dice che le stringhe sono "array di caratteri null term inated"). E quindi, per esempio, 'A' e "A" sono due costanti diverse : 'A' "A" un carattere e occupa 1 byte (con il numero 65) una stringa e occupa 2 byte (con i numeri 65 e 0)

Per inizializzare una stringa bisogna definirla di tipo char e aggiungere al nome della variabile l'operatore di dichiarazione []. Es. char MiaStr[] = "Sono una stringa";

[p05]

Specificatore const
Se nella definizione di una variabile, si premette al tipo (e ai suoi eventuali qualificatori), lo specificatore const, il contenuto della variabile non pu pi essere modificato. Ovviamente una variabile definita const deve sempre essere inizializzata. Es. const double pigreco = 3.14159265385;

L'uso di const fortemente consigliato rispetto all'alternativa di scrivere pi volte la stessa costante nelle istruzioni del programma; infatti se il programmatore decide di cambiarne il valore, e ha usato const, sufficiente che modifichi la sola istruzione di definizione. D'ora in poi, quando parleremo di "costanti", intenderemo riferirci a "variabili definite const" (distinguendole dalle costanti "dirette" che saranno invece chiamate "costanti letterali" o "literals").