Declaratii
Exemple de declaratii:
char ch;
int count = 1;
char* name = "Bjarne";
struct complex
complex cvar;
extern complex sqrt(com 19219b122t plex);
extern int error_number;
typedef complex point;
float real(complex* p);
const double pi = 3.1415926535897932385;
struct user;
Majoritatea
acestor declaratii sint de asemenea si definitii; adica ele definesc o
entitate pentru numele la care se refera. Pentru ch, count si cvar, aceasta
entitate este o cantitate corespunzatoare de memorie care sa se utilizeze ca o
variabila. Pentru real, entitatea este o functie specifica. Pentru
extern complex sqrt(com 19219b122t plex);
extern int error_number;
struct user;
nu sint si definitii. Adica, entitatile la care se refera ele trebuie sa fie definita altundeva. Codul pentru functia sqrt() trebuie sa fie specificat printr-o anumita alta declaratie, memoria pentru variabila error_number de tip intreg trebuie sa fie alocata printr-o anumita alta declaratie a lui error_number, iar o anumita alta declaratie a tipului user trebuie sa defineasca cum arata acel tip. Trebuie totdeauna sa fie exact o definitie pentru fiecare nume dintr-un program C++, dar pot fi multe declaratii si toate declaratiile trebuie sa fie compatibile cu tipul entitatii referite, asa ca fragmentul de mai jos are doua erori:
int count;
int count; // error : redefinition
extern int error_number;
extern short error_number; // error : type mismatch
Anumite definitii specifica o "valoare" pentru entitatile pe care le definesc ele:
struct complex;
typedef complex point;
float real(complex* p);
const double pi=3.1415926535897932385;
Pentru tipuri, functii si constante "valoarea" este permanenta. Pentru tipuri de date neconstante valoarea initiala poate fi schimbata ulterior:
int count = 1;
char* name = "Bjarne";
//................
count = 2;
name = "Marian";
Numai definitia
char ch;
nu specifica o valoare. Orice declaratie ce specifica o valoare este o definitie.
2.1.1. Domeniu
O declaratie introduce un nume intr-un domeniu; adica un nume poate fi utilizat numai intr-o parte specifica a textului programului. Pentru un nume declarat intr-o functie (adesea numit nume local), domeniul lui se extinde din punctul declaratiei pina la sfirsitul blocului in care apare declaratia lui. Pentru un nume care nu este intr-o functie sau intr-o clasa (adesea numit nume global), domeniul se extinde din punctul declaratiei pina la sfirsitul fisierului in care apare declaratia lui. Un nume poate fi redefinit intr-un bloc pentru a referi o entitate diferita in blocul respectiv. Dupa iesirea din bloc numele isi reia intelesul lui precedent. De exemplu:
int x; //global x
f()
x = 3; //asignarea la primul local x
}
int* p = &x; //ia adresa globalului x
Ascunderea numelor este inevitabila cind se scriu programe mari. Totusi, un cititor poate usor sa nu observe ca un nume a fost ascuns si erorile datorate acestui fapt sint foarte dificil de gasit. In consecinta ar trebui minimizat numarul numelor ascunse. Utilizarea numelor de felul lui i si x pentru variabile globale sau locale in functii mari poate sa ne conduca la erori.
Este posibil sa se utilizeze un nume global ascuns utilizind operatorul de rezolutie a domeniului "::". De exemplu:
int x;
f()
Nu exista un mod de a utiliza un nume local ascuns.
Domeniul unui nume incepe in punctul declaratiei lui; aceasta inseamna ca un nume poate fi utilizat chiar pentru a specifica valoarea lui initiala. De exemplu:
int x;
f()
Aceasta este legal dar este fara sens.
Este posibil sa utilizam un singur nume pentru a ne referi la doua obiecte diferite intr-un bloc fara a utiliza operatorul "::". De exemplu:
int x = 11;
f()
Variabila y este initializata cu 11, valoarea globalului x, iar apoi i se atribuie valoarea 22 a variabilei locale x.
Numele argumentelor unei functii se considera declarate in blocul cel mai exterior functiei, deci
f(int x)
eroare, deoarece x este declarat de doua ori in acelasi domeniu.
2.1.2. Obiecte si Lvalori
Se pot aloca si utiliza "variabile" ce nu au nume si este posibil sa se faca atribuiri la expresii care arata straniu (de exemplu *p[a+10]=7).
In
consecinta, exista nevoia de nume pentru "ceva aflat in memorie".
Iata ghilimelele corespunzatoare pentru a face referire la manualul C++:
"Un obiect este o regiune de memorie; o lvaloare este o expresie care
refera un obiect" (&r.5). Cuvintul lvalue original a fost desemnat
pentru a insemna "ceva ce poate fi in partea stinga a unei
atribuiri". Totusi, nu orice lvalue poate fi utilizata in partea stinga a
unei atribuiri; se poate avea o lvaloare care face referire la o
2.1.3. Durata de viata
Daca programatorul nu specifica altfel, un obiect este creat cind definitia lui este intilnita si distrus cind numele lui iese afara din domeniu. Obiectele cu nume globale se creeaza si se initializeaza numai odata si "traiesc" pina cind se termina programul. Obiectele definite printr-o declaratie cu cuvintul cheie static se comporta la fel. De exemplu, (directiva #include <stream.h> a fost lasata afara din exemplele din acest capitol pentru a face economie de spatiu. Este necesar sa fie prezenta pentru exemplele care produc iesiri):
int a = 1;
void f()
main()
produce iesirea:
a = 1 b = 1 c = 1
a = 2 b = 1 c = 2
a = 3 b = 1 c = 3
O variabila statica care nu este explicit initializata este initializata cu zero (&2.4.5).
Utilizind operatorii new si delete, programatorul poate crea obiecte a caror durata de viata poate fi controlata direct (&3.2.4).
|