You are on page 1of 10
14. Programarea modulara in limbajul C. Identificatori si domeniile acestora. > Paradigme de programare: ‘© programarea structurati ~ bazatti pe Teorema de structura ‘ programarea procedurala — bazat pe proiectarea de functii separate ‘+ programarea modulara ~ bazata pe aledtuirea de proiecte din mai multe figiere ‘+ programarea orientata obiect — bazata pe mostenire si polimorfism > Un modul este constituit dintr-un set de functii inrudite impreun cu datele pe care acestea le preluereaza, stocate intr-un fisier care se compileaz separat. Aplicatia se dezvolta sub forma unui proiect prin intermediul caruia se “leaga” (link-editeaz) impreuna diversele module componente, credndu-se un executabil unic. > Programarea modular’ ridica o serie de probleme legate de relatia de interdependent dintre ‘modulele unui proiect precum si de modul de comunicare dintre acestea. > Fiecare modul trebuie s& aibi o interfata (implementata prin intermediul figierului header) care si furnizeze compilatorului informatii necesare despre functiile pe care le contine. > In limbajul C un identificator (nume) desemneazi o functie, un tip de date, o variabil& sau o eticheta. > In general un identificator este introdus printr-o declaratie (exceptie fac in C etichetele) care precizeazit implicit semnificatia/modul de utilizare al acestuia > In privinta locurilor in care poate fi folosit identificatorul respectiv, trebuie Kimurite citeva aspecte : - un identificator poate fi folosit numai intr-o anumita zond a textului surs& al programului, numiti domeniul de valabilitate al numelui. ~ semnificatia unui identificator depinde de locul in care se foloseste numele respectiv, semnificatie precizati de asa numitul domeniu de vizibilitate (scope). ~ un nume folosit in mai multe module ale aceluiasi program poate sau nu si refere acelagi obiect, in functie de tipul de legatura (linkage) specificat in modulul care i utilizeazi. ~ in ceea ce priveste numele ce desemneaz variabile, acestora li se asociazit implicit 0 zon’ de memorie. Zona de memorie in care se face alocarea este definiti de clasa de alocare (memorie). main.epp include “F1.4" include “2.4 inti double x; int main( void) t 10: 20: turn 0; ) fn mh void fi(void)s void 12(void): flepp Rep include“ include “12.4” ‘exter int is extern double x: void f1(void) void 12(void) { t ) i Figura 14.1. Diagrama ce ilustreazai didactic o posibila organizare a unui proiect Obs. Evident, fisierele componente pot confine mai multe functi ! 14.1. Domeniul de valabilitate al unui identificator > Domeniul de valabilitate al unui identificator reprezinti acea zon’ de program in care este cunoscuta (valabila) declaratia sau definitia unui nume si in care, in cazul variabilelor, exist o zoni de memorie alocati acestuia > in limbajul C existi trei tipuri de dome local; - funetie; ~ global (figier). > in limbajul C se numeste bloe o zonii de program ce contine instructiunile cuprinse in interiorul uunei perechi de paranteze acolade, 14.1.1. Domeniul local Un identificator definit in interiorul unui bloc se spune c& are domeniul de valabilitate local (acelui bloc). El este cunoscut si_ se poate folosi doar in interiorul blocului in cauz, mai precis, din punctul imediat ulterior declaratiei sau definitiei sale si pana la paranteza } care se imperecheaza cu cea mai apropiati (textual) parantezii {ce precede textul declaratiei in cauza . 14.1.2. Domeniul functi Domeniul functie se refers in special la cazul etichetelor pentru care domeniul de valabilitate este dat de punctul in care ele sunt folosite si pana la sfarsitul functiei respective. 14.1.3. Domeniul global (fisier) Un identificator definit in afara tuturor blocurilor (practic in afara corpului oricdrei functii) se spune ca are domeniul de valabilitate figier sau global. El se poate folosi in intreg fisierul in care a fost definit, din punctul imediat urmator declaratiei sau definitiei sale. De exemplu pentru o variabila, definitia unei variabile globale coincide cu o declaratie obisnuita, care este insa serisa in afara corpului oricarei functii a programului. De obicei o astfel de definitie se scrie la inceputulfisierului,fiind valabila pan la sfarsitul fisicrului sursa respectiv. 14.2. Domeniul de vizibilitate al unui identificator > Semnificatia unui nume (identificator) depinde de zona de program in care acesta se utilizeaza si de tipul expresiei prin care de face accesul (in C++). > Domeniul de vizibilitate defineste acea zon de program in care un nume isi pistreazi aceeasi semnificatie (aceleasi atribute). Un nume se poate utiliza numai in interiorul domeniului siu de vizibilitate. > In general domeniul de vizibilitate (scope) coincide cu domeniul de valabilitate, cu exceptia situatiilor in care, in blocuri imbricate, apar declaratiile unor omonime. > Semnificatia unui nume intr-un anumit punct al unui program este dati de cea mai apropiati declaratie care precede punetul in cauzai > Domeniul de vizibilitate al unui nume este domeniul de valabilitate din care se exclud blocurile incluse ce contin declaratia unui omonim. 14.3. Utilizarea parametrilor si a variabilelor globale > Atat variabilele globale, cat si parametrii reprezinta interfete intre funetii, implementand 0 posibilitate de comunicare intre acestea, > Asa cum s-a aritat, transferul parametrilor in C este unilateral, de la functia apelanta la functia apelata. Desi ar parea ca avantajoasi utilizarea variabilelor globale ca modalitate de transfer bidirectional a informatiei intre functii, acest mod de lucru nu este in general recomandat, fiind o potential sursi de erori. Exista astfel posibilitatea ca o functie si modifice valoarea unei variabile globale, fapt ce poate avea consecinte nefavorabile pentru restul functiilor ce folosese variabila respectiva. Un astfel de efect se numeste “efect lateral” (in limba englezai “side effect”). Exemplul 14.1 include inti= 15 /* i global */ int main(void) printi("%d\n", i); /* afiseaza 1 */ imti= 2.5 isi locale */ /* definitia globala a lui i e ascunsa */ i,j): afiseaza 2, 3 */ printh("%dinYodl : double i= 0; /* i este redefinit intr-un bloc indentat */ ves /* definitile anterioare ale lui i sunt ascunse */ tas printf("%ogin%din", i,j); / afiseaza 0, 3" oy printh"%din", i); afiseaza 2 */ printi(%od\n", i); * afiseaza 1 */ return 0; Exemplul 14.2 include int xy; void subpr(float x) { A X=1.0; y=1; 1; printf(*Subpr: x=%glty=Yd\tz=%d\n” x,9,2)5 3 int main(void) { x0; printf(“M: ssubpr(x); I: x=%g\ty=%din" x,y); Jain II: x=%ghty=%d\n” x,y); 14.4. Tipul de legatura al unui identificator > In cazul in care un program se compune din mai multe module (mai multe fisiere sursi), 0 variabila global poate fi utilizata intr-un fisier sursi in care nu este definita, doar daca este declarati ca variabila externa in acel fisier, caz.in care se spune ci variabila are legatura externa. > 0 declaratie de variabila extern coincide eu o declaratie de variabila obisnuit de cuvantul rezervat extern. > Restul identificatorilor se spune ci au legitura interna. > Un nume cu domeniul global prefixat de cuvantul rezervat static este local modulului, avand legitura intern’. precedati Exemplul 14.4. In conditile prezentate in Figura 14.1 se modifica fisierul main, ea mai jos main.cpp include “fh” include “£2.h” static int is static double x; int main(void) t #105 120); return 0; : flepp include “Fh extern inti; void fl(void) i) EROARE la link - unresolved externals 14.5. Clase de alocare > Clasele de alocare precizeaz locul si momentul in care se rezervai memorie pentru 0 anumiti variabila. > Exist urmitoarele clase de alocar: ~ automatic; - registru; = static - dinamic. 14.5.1. Clasa de alocare automatic > Clasa de alocare automatic este referita prin intermediul euvantului rezervat automatic, mentiune impliciti pentru variabilele locale (daci nu este specificata nici o alti clasi de alocare, declaratiile din interiorul unei functii creeazi variabilele din clasa automatic) . > Alocarea automatici presupune rezervare de memorie, in momentul executiei, intr-o zon’ special numiti stiva (stack), 0 multime ordonati de celule de memorie la care se poate avea acces in acest caz, conform principiului LIFO (Last In First Out) - ultimul intrat, primul servit. > Ultimul element al stivei se numeste varful stivei. Accesul la stiva se face numai prin varful acesteia. > La addugarea unui element in stivi dimensiunea acesteia creste, iar la extragerea unui clement din stivi, dimensiunea acesteia se miesoreaza. > Variabilele locale si parametrii formali se aloci pe stivi, atunci cind nu se precizeaz’t explicit un alt mod de alocare. > La apelul unei funetii, variabilelor automatice li se rezervii memorie pe stiva, iar cfind se revine din functie, la incheierea executiei functiei, variabilele respective se dezaloca si stiva revine la starea de dinaintea apelului, Aceasta inseamna ci variabilele automatice se “nase” (apar) si “mor” (dispar) odata eu functia, de aceea, la apeluri diferite ale functiei, ele pot fi alocate la adrese diferite. 14.5.2. Clasa de alocare registra v Variabilele se pot aloca in registrele unititii centrale, apartinand in acest caz clasei de alocare registru, specificata prin cuvantul rezervat register. Se pot aloca in acest mod doar variabilele de tip intreg, caracter si pointer. Parametrii formali pot fi declarati din clasa register, aceasta neafectind modul lor de transmitere citre functie (care rimne prin intermediul stivei), ci numai faptul c’, pe durata executiei functiei vor fi plasati in registrele unitaii centrale. vy > Exist urmitoarele restriefii cu privire la clasa de alocare registru: = nu se pot folosi pointeri pentru a refer variabile alocate registru; = nu se poate folosi clasa de alocare registru pentru variabile globale; ~ unei variabile alocate registru nu i se poate aplica operatorul adresi (8). 14.5.3. Clasa de alocare static > Variabilele din clasa static sunt alocate intr-o zona de memorie special destinati acestui scop (nu pe stiva). Ele sunt alocate la compilare, la adrese fixe de memorie, neschimbate pe ‘intreaga durata a executiei programului. Alocarea static este specificaté prin intermediul cuvantului rezervat static. De exemplu tablourile de dimensi incarea stiva. > Variabilele statice se pot declara atat in corpul unei functii, cat si in afara corpului oricdrei i, cu alte cuvinte pot avea domeniul de valabilitate local sau global (fisier). Variabilele globale prefixate de cuvantul rezervat statie (cu semnificatia de legatura intern {n acest context!) nu pot avea legatur’ externa (ele nu pot fi declarate extern). > Modul de alocare are repercusiuni si asupra modului de initializare a valorilor variabilelor si asupra posibilitailor de pistrare a valorilor de la un apel la altul al functiei in care sunt definit Variabilele din clasa automatic si registru nu igi_pistreaza valorile de la un apel la altul, fiind alocate ad-hoc. De aceea, la fiecare apel ele trebuie initializate. v ni mari se recomanda a fi alocate static pentru a nu a V > In cazul variabilelor alocate static, initializarea acestora se va face o singura dati, in momentul alocarii. Ele isi pastreazi ins& valorile de la un apel la altul al functiei. > Pentru a extinde cele de mai sus si pentru cazul functiilor, se poate spune c& functiile sunt analoge variabilelor globale eu legitura extern’. Ele pot fi utilizate (apelate) in orice modul al programului, daci apelul este precedat in modulul respectiv fie de definitia functiei, fie de prototipul ei, in acest caz, prototipul functiei inlocuieste declaratia de extern a variabilei globale, Exemplul 14.3 inti for(i=l; i<4; +4)

You might also like