Il linguaggio C definisce una regola fondamentale sulla visibilita' delle
entita': nel caso che due o piu' entita' differenti abbiano
nomi uguali, l'entita' dichiarata nel blocco interno prevale su
quella piu' esterna avente lo stesso nome.
Il linguaggio C prevede 4 classi di memoria da preporre alle
variabili ed alle funzioni. Nessuna di esse e' obbligatoria, ed in loro
assenza e' previsto un comportamento di default dipendente dal
contesto.
Le classi di memoria sono:
Auto | |
Static | |
Extern | |
Register |
Classe di memoria AUTO
La classe di memoria auto e' il default (e partanto puo' essere
omessa) per le variabili locali, cioe' quelle variabili che sono definite
entro un blocco o
all'interno della definizione di una
funzione.
Tali variabili, dette automatiche, vengono create all'entrata del
blocco e non vengono inizializzate automaticamente, salvo che sia
esplicitato diversamente dal programmatore. All'uscita del blocco vengono
distrutte e perdono ogni valore assegnatogli. Non e' cosi' possibile che
una variabile possa conservare un valore fra 2 esecuzioni dello stesso
blocco o della stessa funzione.
Pertanto:
Il tempo di vita di una variabile
automatica e' pari al tempo di vita del blocco in cui e'
definita. L'allocazione e la deallocazione della variabile automatica viene effettuata impiegando una struttura LIFO (Last In - First Out) come per es. lo STACK. | |
La visibilita' (scope) di una variabile automatica e' limitata al blocco in cui e' definita. |
N.B. - Non ha senso parlare di funzioni automatiche, poiche' una
funzione non puo' essere locale ad un altro oggetto, ovvero non possono
essere definite funzioni all'interno di
blocchi. Inoltre una funzione ha un
tempo di vita pari all'intera durata del
programma.
N.B. - Ha senso parlare di variabili locali ad una funzione, poiche' la funzione viene definita da un blocco entro il quale possono venire definite a loro volta delle variabili automatiche.
Un tempo di vita pari all'intero
programma. L'allocazione e l'inizializzazione avviene una volta per tutte all'inizio del programma e le aree di memoria impiegate fanno parte dei dati globali del programma. Per default le variabili statiche sono sempre inizializzate a zero. Nel caso di inizializzazione esplicita, l'inizializzatore deve essere un'espressione costante. | |
Una visibilita' (scope) limitata al blocco in cui e' definita se si tratta di una variabile locale; nel caso, invece, di una variabile esterna (nel senso, che e' definita all'esterno di ogni funzione), la visibilita' e' limitata al file in cui essa e' definita; in altri termini, l'utilizzo di una variabile static e' consentito solamente da parte delle funzioni definite nello stesso file sorgente. |
Una funzione static ha:
Un tempo di vita pari all'intero
programma. | |
Una visibilita' (scope) limitata al sorgente in cui e' definita; in altri termini, una funzione static puo' essere invocata solamente da altre funzioni che siano definite nello stesso file sorgente, oppure (ovviamente) da se' stessa (caso della ricorsione). |
Un tempo di vita pari all'intero
programma. L'allocazione e l'inizializzazione avviene una volta per tutte all'inizio del programma e le aree di memoria impiegate fanno parte dei dati globali del programma. Per default le variabili extern sono sempre inizializzate a zero. Nel caso di inizializzazione esplicita, l'inizializzatore deve essere un'espressione costante. | |
Una visibilita' (scope) globale, cioe' una variabile esterna e' visibile da tutti i sorgenti che compongono il programma, a condizione che venga dichiarata almeno sui sorgenti dove se ne faccia uso. |
Una funzione extern ha:
Un tempo di vita pari all'intero programma. | |
Una visibilita' (scope) globale, cioe' una funzione esterna e' visibile da tutti i sorgenti che compongono il programma, a condizione che venga dichiarata almeno sui sorgenti dove se ne faccia uso. |
Per la definizione di una variabile o di una funzione esterna, il
termine extern non deve essere
impiegato.
Per dichiarare una variabile o una funzione definita all'esterno del
sorgente attuale, occorre precedere la dichiarazione stessa con la parola
chiave extern.
extern deve essere impiegata anche' nel caso,
sebbene molto piu' raro, della dichiarazione di una variabile la cui
definizione avvenga in un punto seguente del sorgente.
Classe di memoria REGISTER
La classe di memoria register definisce una varibile con
caratteristiche della classe di memoria automatica,
tranne il fatto di indicare al compilatore che la
variabile venga inserita, se possibile, direttamente nei registri di
memoria della CPU, piuttosto che allocarla sullo STACK. Poiche'
l'accesso ai registri di CPU risulta essere molto piu' veloce dell'accesso
in memoria, ne consegue che l'uso di variabili register puo' notevolmente
migliorare le prestazioni di alcune funziolni critiche e con esse
dell'intero programma.
E' quindi evidente, che la convenienza di definire variabili register
aumenta con l'aumentare del numero di accessi che si prevede di effettuare
su tali variabili. In quest'ottica risulta conveniente chiedere
al compilatore di definire queste variabili nei registri macchina della
CPU.
L'effettivo utilizzo dei registri di CPU per una variabile register
dipende dalla implementazione del compilatore.
Le limitazioni tipiche sono in funzione della tipologia della variabile (es.:
int, long, float, ...) e sul numero di registri di CPU disponibili per
l'allocazione di variabili.
Come e' evidente, i limiti sono per lo piu' di natura hardware (riguardano
direttamente l'architettura della CPU).
La classe register e' anche applicabile ai parametri formali di una
funzione.
Esempio:
int funzione1(int arg1, register int arg2, long arg3) { ... }
N.B. - Ad una variabile register non e' consentito di applicare l'operatore indirizzo &
auto | static | extern | register | |
---|---|---|---|---|
Variabili locali | Si (default) | Si | Si (dichiarazione) | Si |
Variabili esterne | No! | Si | Default (definizione) Si (dichiarazione) |
No! |
Funzioni | No! | Si | Default (definizione) Si (dichiarazione) |
No! |
Nella tabella soprastante, si e' evidenziata la possibilita' di utilizzare
esplicitamente le 4 classi di memoria in funzione delle entita'.
Con variabili locali si intendono le variabili dichiarate o definite
all'interno di un blocco.
Con variabili esterne si sono indicate quelle variabili dichiarate o
definite all'esterno di ciascuna funzione.
Per quanto riguarda la classe di memoria extern, e' stato indicato, oltre alla compatibilita' con le varie entita', che la sua presenza implica una dichiarazione, mentre la sua assenza nei casi di default implica una definizione.
Link ad ulteriori approffondimenti sui termini di
dichiarazione e di
definizione di entita'.