Guida al C/C++
autore: BlackLight
xx/xx/xx
Uso delle variabili:
In tutti i linguaggi di programmazione le variabili rivestono un ruolo
molto importante, se non fondamentale, nella scrittura del programma.
Le variabili dell'informatica sono una sorta di "contenitori" che al
loro interno possono contenere numeri interi, numeri a virgola mobile,
caratteri di testo ecc.
Ecco come si dichiara una variabile in C:
tipo nome_variabile;
Possiamo anche assegnarle un valore iniziale, in questo modo:
tipo nome_variabile = valore_iniziale;
Il
tipo di variabile è la caratteristica principale della variabile stessa: ecco i principali tipi ammessi dal C:
Tipo
|
Uso
|
Memoria occupata (bit)
|
char
|
Caratteri di testo ASCII
|
8
|
short int
|
Numeri interi piccoli (da -32768 a 32768)
|
16
|
unsigned short int
|
Numeri positivi interi piccoli (da 0 a 65536)
|
16
|
int
|
Numeri interi (da -2147483648 a 2147483648)
|
32
|
unsigned int
|
Numeri interi positivi (da 0 a 4294967296)
|
32
|
long int
|
Numeri interi grandi
|
32
|
float
|
Numeri a virgola mobile (precisione singola)
|
32
|
double
|
Numeri a virgola mobile (doppia precisione, notazione scientifica)
|
64
|
Esempio:
int a; // Dichiaro una variabile intera chiamata a senza inizializzarla
int b = 3; // Dichiaro una variabile intera b che vale 3
char c = 'q'; // Dichiaro una variabile char che contiene il carattere q
float d = 3.5; // Dichiaro una variabile float d che vale 3.5
a = 2; // Adesso a vale 2
int e = a+b; // e vale la somma di a e b, ossia 5
Come vedete, è possibile fare con le variabili ogni tipo di operazione
matematica: addizione (+), sottrazione (-), moltiplicazione (*),
divisione (/), resto della divisione (%). Diamo però un'occhiata a
questo codice:
int a = 2; // Variabile int
float b = 3.5; // Variabile float
int c = a+b; // ERRORE!
Quello che ho riportato sopra è un errore molto frequente anche fra i
programmatori più esperti, se provo a compilare un codice del genere
otterrò un
warning (un "avvertimento del compilatore, che però non pregiudica la compilazione vera e propria) o, più spesso, un
errore vero e proprio (la compilazione viene arrestata).
Non posso effettuare operazioni fra due tipi di variabili diversi fra
loro (int questo caso, int e float): per farlo devo ricorrere alla
conversione di cast. Esempio corretto:
int a = 2;
float b = 3.5;
int c = (int) a+b; // Converto il risultato in int. c vale 5 in questo caso
Oppure:
int a = 2;
float b = 3.5;
float c = (float) a+b; // Converto il risultato in float. c vale 5.5 in questo caso
A differenza delle variabili "matematiche", in C una scrittura del genere è concessa:
int a = a+2; // Aggiorno il valore di a
Oppure, in modo più sintetico:
int a += 2;
La scrittura
a += 2 sta per
a = a+2 (sono concesse scritture come
+= -= *= /= %=).
La scrittura
a++ è invece un
incremento della variabile
a, ed equivale a
a=a+1 (così come la scrittura
a-- equivale a
a=a-1).
È anche possibile usare le variabili in funzioni come la printf(). Prendete ad esempio il seguente codice:
int x = 3;
printf ("x vale %d",x);
L'output sarà:
x vale 3
La direttiva
%d
dice al compilatore di stampare la variabile intera posta fuori i doppi
apici "". In questo caso stampa il valore di x, che è proprio 3.
Se invece voglio stampare una variabile di tipo
float, farei così:
float x = 3.14;
printf ("x vale %f",x);
dove la scrittura
%f
dice al compilatore di stampare una variabile di tipo float. Ecco le
direttive principali usate per stampare i principali tipi di variabili:
Direttiva
|
Uso
|
%c
|
Variabili char
|
%d %i
|
Variabili int e short int in formato decimale (quello che usiamo comunemente)
|
%x %X
|
Varabili int, short int, long int o char in formato esadecimale
|
%o
|
Variabili in formato ottale
|
%l %ld
|
Variabili long int
|
%u
|
Variabili unsigned
|
%f
|
Variabili float
|
%lf
|
Variabili double
|
%p
|
Indirizzo esadecimale di un puntatore (li vedremo più avanti...)
|
%s
|
Stringhe di testo (le vedremo più avanti...)
|
%n
|
Scrive
i byte scritti finora sullo stack dalla funzione printf() (la vedremo
più avanti, quando parleremo del format string overflow...)
|
Esempio:
/* variabili.c */
#include < stdio.h >
int main() {
int a,b,c; // Dichiaro 3 variabili int
a = 3;
b = 4;
c = a+b; // c vale 7
printf ("c vale %d\n",c);
a += 3; // Ora a vale 6
b++; // Ora b vale 5
c = a-b; // Ora c vale -1
printf ("Ora c vale %d\n",c);
return 0;
}
Abbastanza semplice, no?
Il fatto interessante è che possiamo eseguire opeazioni anche sulle
variabili char! Le variabili char, infatti, vengono considerate dal
programma come codici ASCII, ovvero ogni variabile ha il suo codice
numerico (da 0 a 255) che viene convertito in runtime in un carattere
(attenzione che in linguaggi come Java queste operazioni non sono
concesse, in quanto i caratteri non sono in formato ASCII ma Unicode).
Ecco un esempio:
char c = 65; // Equivale a scrivere char c = 'A', infatti
// 65 è il codice per la lettera A
char c += 4; // Ora a vale E
printf ("a = %c\n",c);
Variabili locali e globali
In C, le variabili vanno dichiarate o all'inizio del
programma o all'inizio della funzione che le usa. Attenzione che è un
errore dichiarare una variabile in altri posti! Esempio:
int main() {
printf ("Ciao ciao a tutti!\n");
int b = 3; // ERRORE!
}
In C++ non si ha questo errore, in quanto la dichiarazione
di una variabile è considerata un'istruzione vera e propria e può
essere messa ovunque, ma in C c'è l'errore.
Le variabili dichiarate all'inizio del programma vengono dette
globali
e possono essere usate da ogni funzione del programma (lo vedremo
meglio quando parleremo delle funzioni), mentre le variabili locali
possono essere viste solo dalla funzione che le dichiara (in C++ è
anche possibile far vedere le variabili ad un solo blocco di codice).
Esempio:
#include < stdio.h >
int var_globale = 3; // Variabile globale
int main() {
int var_locale = 2; // Variabile locale
.......
var_globale += var_locale; // È possibile perchè var_globale è una variabile globale
.......
}
Variabili static e auto
Le variabili globali in genere sono
statiche,
ossia vengono instanziate in memoria quando il programma viene chiamato
e distrutte quando il programma viene chiuso. Le variabili locali
invece in genere sono
automatiche, ossia vengono instanziate
quando la funzione che le dichiara viene invocata e vengono distrutte
quando la funzione chiamante è termnata. È però possibile stabilire se
una variabile deve essere static e automatica attraverso le keyword
static e
auto. Esempio:
.....
auto int x = 7; // Variabile automatica
int main() {
static float pi = 3.14; // Variabile statica
.....
}
Costanti: l'istruzione #define e la keyword const
È possibile dichiarare anche delle costanti in C, o
variabili a sola lettura, delle variabili cioè che possono venire lette ma su cui non è possibile scrivere. I modi sono due:
-
Attraverso l'istruzione #define:
#include < stdio.h >
/* Definisco la costante PI, che vale 3.14 */
#define PI 3.14
int main() {
float area, raggio;
.....
area = raggio*PI*PI;
.....
}
-
Attraverso la keyword const:
.....
const float pi = 3.14;
.....
area = raggio*pi*pi;
.....
L'istruzione
#define è, come la
#include,
un'istruzione al preprocessore. In poche parole, quando il compilatore
incappa in una #define, legge il valore assegnato alla costante (anche
se non è propriamente una costante, in quanto non viene allocata in
memoria), cerca quella costante all'interno del programma e gli
sostituisce il valore specificato in real-time. Con la
const,
invece, creo una vera e propria variabile a sola lettura in modo pulito
e veloce, e per dichiarre una costante è di gran lunga preferito
quest'ultimo metodo. Ovviamente una scrittura come questa darà un
errore (o un warning):
const float pi = 3.14;
pi += 1;
in quanto una costante non si può modificare.
Variabili register e volatile
Le variabili vengono in genere allocate nella memoria RAM
(nello stack se sono statiche, nello heap se sono dinamiche). Ma in C è
anche possibile allocare una variabile in un registro del processore
(in genere l'accumulatore, EAX) attraverso la keyword
register:
register int var_reg = 3;
Ovviamente, in genere è sconsigliato allocare variabili
nei registri, in quanto per i registri ci passa una marea di
informazioni importanti per la sessione, per il programma ecc. e la
variabile può facilmente andar persa.
Dichiarando invece una variabile come
volatile, questa variabile può venir modificata da alti processi o da altre parti del programma in qualsiasi momento:
volatile int vol_var;