Variabile locale și globale
Când scriem funcții, o întrebare importantă este: unde există o variabilă? Poate fi accesată din orice funcție sau doar din cea în care a fost declarată?
Variabile locale
O variabilă declarată în interiorul unei funcții este locală. Ea există doar cât timp funcția se execută și nu poate fi accesată din altă parte.
#include <iostream>
using namespace std;
void functie() {
int x = 10;
cout << x << endl;
}
int main()
{
functie();
// cout << x; // EROARE! x nu există aici
return 0;
}x este locală funcției functie().
În main nu știm de ea.
Fiecare funcție are propriile variabile
void f1() {
int a = 5;
cout << a << endl;
}
void f2() {
int a = 100;
cout << a << endl;
}
int main()
{
f1();
f2();
return 0;
}Output:
5
100Variabila a din f1 și
a din f2 sunt complet
diferite - au doar același nume. Fiecare funcție are
propriul spațiu.
Variabile globale
O variabilă declarată în afara tuturor funcțiilor este globală. Ea poate fi accesată din orice funcție.
#include <iostream>
using namespace std;
int contor = 0; // globală
void incrementeaza() {
contor++;
}
int main()
{
incrementeaza();
incrementeaza();
incrementeaza();
cout << contor << endl;
return 0;
}Output:
3contor este globală - ambele funcții
(incrementeaza și main) o văd și o pot
modifica.
Diferențe cheie
| Locale | Globale | |
|---|---|---|
| Unde se declară | În interiorul unei funcții | În afara tuturor funcțiilor |
| Cine le vede | Doar funcția respectivă | Toate funcțiile |
| Durata de viață | Cât se execută funcția | Tot programul |
| Valoare inițială | Nedefinită (gunoi) | Automat 0 |
| Bune pentru | Calcule temporare | Vectori, fin/fout, date
partajate |
Foarte important: variabilele locale
nu sunt inițializate automat. Dacă nu le dai o
valoare, conțin “gunoi”. Variabilele globale sunt automat
0.
Suprapunerea numelor
Dacă o variabilă locală are același nume cu una globală, cea locală o “ascunde” pe cea globală.
#include <iostream>
using namespace std;
int x = 100; // globală
void functie() {
int x = 5; // locală - ascunde globala
cout << "In functie: " << x << endl;
}
int main()
{
cout << "Inainte: " << x << endl;
functie();
cout << "Dupa: " << x << endl;
return 0;
}Output:
Inainte: 100
In functie: 5
Dupa: 100În functie(), x se referă la
variabila locală (5). Globala (100) nu
e afectată.
De ce se întâmplă asta?
Compilatorul caută mai întâi o variabilă locală cu acel nume. Dacă o găsește, o folosește pe ea. Doar dacă nu există local, caută global.
De aceea, este o practică bună să nu folosim același nume pentru variabile locale și globale - evităm confuzii.
Când folosim variabile globale?
La concursuri, declarăm global:
- Vectorii (sunt mari și nu încap pe stivă)
finșifout(accesibile din orice funcție)n(dimensiunea vectorului - folosit peste tot)
#include <fstream>
using namespace std;
ifstream fin("date.in");
ofstream fout("date.out");
int v[100001]; // global - vector mare
int n; // global - dimensiune
void citeste() {
fin >> n;
for (int i = 1; i <= n; i++)
fin >> v[i];
}
void afiseaza() {
for (int i = 1; i <= n; i++)
fout << v[i] << " ";
}
int main()
{
citeste();
afiseaza();
return 0;
}Variabile locale în bucle
Variabilele declarate într-o buclă for sunt
locale buclei:
for (int i = 1; i <= 5; i++) {
cout << i;
}
// cout << i; // EROARE! i nu mai există aiciLa fel în if sau while:
if (n > 0) {
int temp = n * 2;
cout << temp;
}
// cout << temp; // EROARE! temp nu mai existăParametrii sunt variabile locale
Parametrii unei funcții se comportă ca variabile locale:
int dublu(int x) {
x = x * 2; // modificăm variabila locală x (copia)
return x;
}
int main()
{
int a = 5;
cout << dublu(a); // 10
cout << a; // 5 - neschimbat
return 0;
}x este locală funcției dublu - este
o copie a lui a.
Exemplu: de ce contează
#include <iostream>
using namespace std;
int suma = 0; // globală
void adauga(int x) {
int suma = 0; // locală! Ascunde globala!
suma = suma + x;
cout << "Local: " << suma << endl;
}
int main()
{
adauga(5);
adauga(3);
cout << "Global: " << suma << endl;
return 0;
}Output:
Local: 5
Local: 3
Global: 0adauga modifică variabila
locală suma, nu pe cea globală.
Globala rămâne 0. Dacă ștergem int din
fața lui suma din funcție, ar folosi globala.
Greșeli frecvente
1. Variabila locală neinițializată
void f() {
int x;
cout << x; // valoare aleatorie (gunoi)!
}Variabilele locale trebuie inițializate explicit.
2. Aceeași denumire - confuzie
int n = 10; // globală
void f() {
int n = 5; // locală - ascunde globala
// credem că modificăm globala, dar nu
}Evită să dai același nume variabilelor locale și globale.
3. Vector declarat local
void f() {
int v[100000]; // PERICOL! Poate depăși stiva
}Vectorii mari trebuie declarați global.
Ce să reții
- Locale - declarate în funcție, vizibile doar acolo, neinițializate automat.
- Globale - declarate în afara funcțiilor, vizibile peste tot, inițializate cu 0.
- O variabilă locală cu același nume ascunde globala.
- Parametrii funcțiilor sunt variabile locale (copii).
- La concursuri: vectori,
fin/foutșinse declară global. - Variabilele locale declarate în bucle sau blocuri
ifexistă doar în acel bloc.