Sunteți pe pagina 1din 5

TEMA 10

Domenii de vizibilitate: variabile globale și variabile locale.

După cum știm, în C++ variabilele despre care am învățat până acum trebuie declarate și odată cu
declararea li se alocă în memorie spațiu în conformitate cu tipul lor. Întrebarea este: “Unde putem
declara variabile și prin ce diferă acestea?”.

Sistemul de operare alocă fiecărui program, în memoria RAM, trei zone în care putem memora
variabile:
 zona de date
 zona de stivă
 zona liberă (heap)

O variabilă se caracterizează prin:


 clasa de memorare
 vizibilitate
 durata de viață
 tipul variabilei

Să nu uităm, de asemenea, identificatorul variabilei! Dar nu toate variabilele au un identificator, așa


cum vom vedea cândva! Clasa de memorare reprezintă zona de memorie unde poate fi alocat spațiu
pentru o variabilă. Ea poate fi: zona de date, zona de stivă, heap-ul sau un registru al procesorului – o
memorie specială, de mici dimensiuni, foarte rapidă existentă în procesor (CPU).

Vizibilitatea unei variabile precizează zona din codul sursă (liniile programului C++) unde se poate
folosi respectiva variabilă și poate fi:
 la nivel de bloc – variabila este vizibilă numai într-un bloc al programului
 la nivel de fișier – variabila este vizibilă în tot fișierul sursă cu care lucrăm
 la nivel de clasă – specific programării orientate pe obiecte

Durata de viață reprezintă timpul în care variabilei îi este alocat spațiu în memorie și poate fi:
 durată statică – variabila are alocat spațiu pe tot parcursul execuției programului
 durata locală – variabila are alocat spațiu numai pe parcursul execuției instrucțiunilor dintr-
un bloc
 durata dinamică – variabila se creează (i se alocă spațiu) și se distruge de către programator,
în timpul executării programului

În C++ variabile pot fi: locale, globale și dinamice. Variabile dinamice vor fi prezentate într-un alt
articol, iar cele statice și dinamice în continuare.

VARIABILE LOCALE

Variabilele locale se declară într-un anumit bloc al programului, în corpul unei funcții. Fie programul
de mai jos:

#include <iostream>
using namespace std;
void F(){
int x;
x = 5;
cout << x << endl;
}
int main(){
int y = 10;
F();
cout << y << endl;
return 0;
}

Variabilele x și y declarate în programul de mai sus sunt locale. Variabila x poate fi utilizată numai în
funcție F(), iar variabila y numai în funcția main(). Mai mult, cele două variabile ar fi putut avea
același nume și nu ar fi fost nicio confuzie.

Variabilele locale respectă următoarele reguli:


 li se alocă memorie în zona de stivă
 sunt vizibile numai în blocul în care au fost declarate
 durata de viață a lor este execuția instrucțiunilor din blocul în care au fost declarate
 sunt inițializate cu valori aleatorii. Mai precis, standardul C++ nu garantează inițializarea
lor cu o anumită valoare. Asta nu înseamnă că nu este posibil ca variabilele locale să fie
inițializate de exemplu cu 0 într-o anumită implementare a compilatorului, dar nu ne putem
baza pe acest lucru. Mai mult, compilatorul utilizat pe pbInfo nu inițializează variabilele
locale cu o anumită valoare

Observație:
Parametrii formali ai unei funcții respectă proprietățile unei variabile locale. Nu vom putea
declara în blocul funcției variabile cu același nume ca al parametrilor formali.

VARIABILE GLOBALE

Variabilele globale se declară în afara oricărei funcții. La declarare, ele sunt inițializate cu 0.

#include <iostream>
using namespace std;
int x;
void F(){
cout << x << endl;
x = 10;
}
int y;
int main(){
cout << x << " " << y << endl;
x = 5; y = 15;
F();
cout << x << " " << y << endl;
return 0;
}

În programul de mai sus variabilele x și y sunt globale. Variabila x poate fi utilizată atât în funcția
main() cât și in F(), iar variabila y numai în main().

Variabilele globale respectă următoarele reguli:


 li se alocă memorie în zona de date
 sunt vizibile în toate funcțiile care urmează în codul sursă declarării lor
 durata de viață a lor este execuția întregului program
 sunt inițializate cu valoarea 0.
Observație:
Într-un program putem avea și variabile globale și variabile locale, ba chiar variabile globale
și locale cu același nume. Următorul program exemplifică această situație. Rulați-l și analizați
valorile afișate pentru a deduce modul în care sunt ele vizibile!
#include <iostream>
using namespace std;
int x;
void F(){
cout << x << endl; //5, variabila globala
int x = 10;
cout << x << endl; //10, variabila locala in F()
{
int x = 20;
cout << x << endl; //20, variabila locala în F(), blocul interior
}
cout << x << endl; //10, variabila locala in F()
}
int y;
int main(){
cout << x << endl; //0, variabila globală
x = 5;
cout << x << endl; //5, variabila globala
F();
cout << x << endl; //5, variabila globala
int x = 100;
cout << x << endl; //100, variabila locala in main()
return 0;
}

Observație:
Dacă într-un program avem variabile cu același nume, dar cu domenii de vizibilitate diferite,
are prioritate variabila cu domeniul de vizibilitate cel mai mic. În particular, dacă ave o
variabilă globală și una locală cu același nume are prioritate variabila locală.

Notă:
Dacă declarăm o variabilă în expresia de inițializare a unei instrucțiuni for, ea va fi vizibilă
numai în expresiile de control ale instrucțiunii for și în blocul subordonat acesteia. De
exemplu:

for(int i =1 ; i <= 10 ; i ++)


cout << i << " " ;

CORESPONDENȚA DINTRE PARAMETRII FORMALI ȘI CEI EFECTIVI

Să ne amintim că parametri din antetul unei funcții se numesc parametri formali, iar cei din apelul
funcției se numesc parametri efectivi.

Fie următorul program, în care funcția cmmdc returnează cel mai mare divizor comun al
parametrilor:

#include <iostream>
using namespace std;
int cmmdc(int a , int b){
while(b != 0)
{
int r = a % b;
a = b;
b = r;
}
return a;
}
int main(){
int x = 24, y = 18;
cout << cmmdc(x , y) << endl; // 6
cout << cmmdc(x, y + 2) << endl; // 4
cout << cmmdc(x , 36) << endl; // 12
cout << cmmdc(26 , 39) << endl; // 13
cout << cmmdc(8.5 , 12.56) << endl; // 4
return 0;
}

Să observăm că între parametri formali și cei actuali trebuie să existe o anumită corespondență,
astfel:

1. numărul parametrilor formali și cel al parametrilor actuali trebuie să fie același (există și o
excepție care depășește cadrul acestui articol)
2. tipul parametrilor formali trebuie să fie același cu cel al parametrilor actuali, sau să se poată
face o conversie implicită:
 cmmdc(x , y) – parametri actuali sunt variabile de tip int
 cmmdc(x, y + 2) – un parametru actual este variabilă de tip int, celălalt este o expresie al
cărei rezultat este de tip int
 cmmdc(26 , 39) – parametri actuali sunt constante de tip int
 cmmdc(8.5 , 12.56) – parametri actuali sunt constante de tip double. Înainte de apel
valorile parametrilor actuali vor fi convertite la tipul int, apelul fiind similar cu cmmdc(8 ,
12).
3. numele parametrilor formali nu trebuie să fie aceiași cu numele parametrilor actuali
corespunzători

Parametrii formali ai unei funcții se comportă la fel ca niște variabile locale:


 li se alocă memorie pe stivă, ca variabilelor locale.
 devin variabile locale pentru funcție, iar numele acestor variabile este identic cu numele
parametrilor din antetul funcției
 la revenirea din apelul funcției, conținutul parametrilor, la fel ca al variabilelor locale, se
pierde

Există două modalități de transmitere a parametrilor:


 transmiterea prin valoare
 transmiterea prin referință

În cazul transmiterii parametrilor prin valoare, parametrii formali ai unei funcții sunt copii ale
valorilor parametrilor actuali. Acest lucru înseamnă că:
 parametri actuali pot fi expresii ale căror valori corespund ca tip cu parametri formali (sau
pot fi convertite implicit la tipul parametrilor formali).
 pe stivă se memorează valoare expresiei (sau variabilei) date ca parametru actual.
 la ieșirea din apelul funcției modificările realizate în funcție asupra parametrilor formali nu au
efect asupra parametrilor actuali. Parametrii actuali sunt nemodificați!
 acesta este modul implicit de transmitere a parametrilor.

Exemplu:

#include <iostream>
using namespace std;
int cmmdc(int a , int b){
cout << "La inceputul functiei cmmdc, a = " << a << " si b = " << b << endl;
while(b != 0)
{
int r = a % b;
a = b;
b = r;
}
cout << "La finalul functiei cmmdc, a = " << a << " si b = " << b << endl;
return a;
}
int main(){
int x = 24, y = 18;
cout << cmmdc(x , y) << endl;
cout << "După apelul functiei cmmdc, x = " << x << " si y = " << y << endl;
return 0;
}

Constatăm că deși în funcția cmmdc parametrii formali a și b se modifică, în main(), după apelul
funcției cmmdc(), parametrii actuali x și y au valorile anterioare.

Este mecanismul specific C++ prin care putem modifica într-o funcție variabile din afara funcției. În
cazul transmiterii parametrilor prin referință, parametrii formali ai unei funcții sunt referințe ale
parametrilor actuali. Acest lucru înseamnă că:
 parametri actuali pot fi doar variabile, sau expresii ale căror rezultate sunt similare
variabilelor: elemente de tablou, câmp al unei structuri, pointer dereferențiat, etc.
 pe stivă se memorează adresa variabilei date ca parametru actual.
 toate modificările realizate în apelul funcției asupra parametrilor formali se fac de fapt asupra
parametrilor actuali. Parametrii actuali sunt modificați la ieșirea din apel!
 pentru a preciza că un parametru este transmis prin referință va fi precedat de caracterul & în
antetul funcției.

Trebuie amintit că în limbajul C nu este posibilă transmiterea parametrilor prin referință. Dacă dorim
să modificăm într-o funcție o variabilă din afara ei trebuie să folosim pointeri.

Exemplu:
#include <iostream>
using namespace std;
void dublare(int & n)
{
n = 2 * n;
}
int main(){
int x = 24;
cout << "x = " << x << endl;
dublare(x);
cout << "x = " << x << endl;
return 0;
}

Constatăm că, la ieșirea din apel, valoarea variabilei x este modificată. Mai mult, un apel de forma
dublare(10); reprezintă o eroare de sintaxă, deoarece parametrul actual trebuie să fie variabilă.

S-ar putea să vă placă și