5.2. Variabile locale
2019/02/23 in Programare in C
Variabilele locale, spre deosebire de cele globale, nu sunt valabile in tot programul. Ele au o valabilitate locala, in unitatea in care sunt declarate.
Variabilele locale pot fi alocate pe stiva. In acest caz ele se numesc automatice. Acestea se declara in mod obisnuit, in corpul unei functii sau la inceputul unei instructiuni compuse. O astfel de variabila se aloca la executie (nu la compilare).
La apelul unei functii, variabilele automatice (declarate in mod obisnuit inaintea primei instructiuni din corpul functiei respective) se aloca pe stiva. In momentul in care se revine din functie, variabilele automatice alocate la apel se dezaloca (se elimina) si stiva revine la starea dinaintea apelului (operatia de curatire a stivei). Aceasta inseamna ca variabilele automatice isi pierd existenta la revenirea din functia in care sunt declarate. De aceea, o variabila automatica este valabila (vizibila) numai in corpul functiei in care a fost declarata.
In acelasi mod se comporta variabilele automatice declarate la inceputul unei instructiuni compuse. O astfel de variabila se aloca pe stiva in momentul in care controlul programului ajunge la instructiunea compusa in care este declarata variabila respectiva si se elimina de pe stiva in momentul in care controlul programului trece la instructiunea urmatoare celei compuse.
Variabilele locale pot si sa nu fie alocate pe stiva. In acest scop ele se declara ca fiind statice. O declaratie de variabila statica este o declaratie obisnuita precedata de cuvantul cheie static.
Variabilele statice pot fi declarate atat in corpul unei functii cat si in afara corpului oricarei functii.
O variabila statica declarata in corpul unei functii este definita numai in corpul functiei respective.
Spre deosebire de variabilele automatice, o variabila statica nu se aloca pe stiva la executie, ci la compilare, intr-o zona de memorie destinata acestora.
O variabila statica declarata in afara corpurilor functiilor este definita (vizibila) din punctul in care este declarata si pana la sfarsitul fisierului sursa care contine declaratia respectiva. Spre deosebire de variabilele globale, o astfel de variabila nu poate fi declarata ca externa. Deci ea nu poate fi utilizata in alte fisiere daca acestea se compileaza separat sau se includ inaintea declaratiei respective.
Putem spune ca o variabila statica declarata in afara corpurilor functiilor este locala fisierului in care este declarata.
Ea se aloca la compilare intr-o zona speciala rezervata variabilelor statice corespunzatoare fisierelor sursa in care au fost declarate.
Daca prin modul intelegem un text sursa compilat separat fata de restul textului sursa al unui program, atunci putem afirma ca o variabila statica declarata in afara corpurilor functiilor este locala modulului in care a fost declarata. Utilizarile unei variabile statice trebuie precedate de declaratia ei.
In cazul variabilelor globale, acestea pot fi utilizate in orice modul, daca sunt precedate, in modulul respectiv, fie de definitia lor, fie de declaratia de extern.
Functiile sunt analoge cu variabilele globale. Ele, ca si variabilele globale, pot fi utilizate (apelate) in orice modul al programului daca apelul lor este precedat, in modulul respectiv, fie de definitie, fie de prototipul lor. In acest caz, prototipul functiei inlocuieste declaratia de extern a variabilei globale.
Limbajele C si C++ permit declarari de functii statice. Aceasta se face precedand antetul functiei de cuvantul cheie static. In acest caz, functia respectiva este locala modulului in care este definita.
Impartirea pe module a unui program nu se face prin reguli definite riguros.
Se obisnuieste sa se spuna ca un modul este format din functii "inrudite" si contine date pe care acestea le prelucreaza in comun.
Exemplu:
Un program se compune din 2 fisiere sursa1.cpp si sursa2.cpp care formeaza fiecare cate un modul (se compileaza separat, utilizand, de exemplu, un fisier de tip project).
Fisierul sursa1.cpp contine:
int i, j, k;
/*
Definitie de variabile globale;
Se pot utliza in tot modulul;
Se pot declara ca externe in celalalt modul pentru a putea fi utilizate si acolo.
*/
static double x, y;
/*
Declaratie de variabile statice;
Se pot utiliza in tot modulul de fata si numai in acesta.
*/
...
main()
{
int p, q;
/*
Declaratie de variabile automatice;
Se pot utiliza numai in corpul functiei main.
*/
static int u, v, r;
/*
Declaratie de variabile statice;
Se pot utiliza numai in corpul functiei main.
*/
...
/* se pot utiliza variabilele i, j, k, x, y, p, q, u, v si r*/
...
}
tip f(...)
{
float a, b;
/*
Declaratie de variabile automatice;
Se pot utiliza numai in corpul functiei f.
*/
static char c, temp;
/*
Declaratie de variabile statice;
Se pot utiliza numai in corpul functiei f.
*/
...
/* se pot utiliza variabilele i, j, k, x, y, a, b, c si temp*/
}
Fisierul sursa2.cpp contine:
static float s, t;
/*
Declaratie de variabile statice;
Se pot utiliza in fisierul sursa2.cpp.
*/
tip f(...)
{
extern int i, j, k;
/*
Declaratie de extern pentru variabilele i, j, k;
Se pot utiliza in corpul functiei f.
*/
char d, e;
/*
Declaratie de variabile automatice;
Se pot utiliza in corpul functiei g.
*/
static double d1, d2, d3;
/*
Declaratie de variabile statice;
Se pot utiliza in corpul functiei g.
*/
...
/* se pot utiliza variabilele i, j, k, s, t, d, e, d1, d2 si d3*/
...
}
tip h(...)
{
extern int k;
/*
Declaratie de extern pentru variabila k;
Se poate utiliza in corpul functiei h.
*/
...
/* se pot utiliza variabilele k, s si t*/
...
}
Variabilele pot fi redeclarate indiferent de modul lor de alocare (global, static sau automatic).
Exemplu:
int i, c; /* variabile globale */
static float a; /* variabila statica */
...
main()
{
double c; /* variabila automatica diferita de variabila globala c */
char a; /* variabila automatica diferita de variabila statica a */
...
c = 123; /* se atribuie variabilei automatice c valoarea 123
dupa conversia ei in flotanta dubla precizie */
...
i = 123; /* se atribuie variabilei globale i valoarea 123 */
...
a = '1'; /* se atribuie variabilei automatice a
codul ASCII al caracterului 1 */
/*
- in aceasta functie nu se pot utiliza variabila globala c si
variabila statica a deoarece acestea au fost redeclarate;
- cu toate acestea, in limbajul C++ este posibila utilizarea
lor folosind operatorul :: pentru globale
*/
}
tip f(...)
{
...
/* nu sunt redeclarari pentru i, c si a; */
c = 123; /* se atribuie variabilei globale c valoarea 123 */
a = 123; /* se atribuie variabilei statice a valoarea 123,
dupa ce a fost convertita spre flotant simpla precizie */
...
}
Uneori, tablourile de dimensiuni mari se aloca globale sau statice deoarece alocarea lor pe stiva poate conduce la depasirea stivei.