Capitolul 1.10. Domenii; variabile externe

Vezi subiectul anterior Vezi subiectul urmator In jos

Capitolul 1.10. Domenii; variabile externe

Mesaj  zooky la data de Mier Mar 18, 2009 12:49 am

Variabile din main (line, save, etc) sint private sau locale lui main; deoarece ele sint declarate in main, nici o alta functie nu poate avea acces direct la ele. La fel se intimpla si cu variabilele din alte functii de exemplu variabila i din getline nu are nici o legatura cu varibila i din copy. Fiecare variabila locala dintr-o rutina se naste numai atunci cind functia este apelata si"dispare" cind functia isi termina activitatea. Aceasta este ratiunea pentru care astfel de variabile sint cunoscute uzual sint numele de variabile automate, urmind terminologia din alte limbaje. Vom folosi termenul de "automat" de aici inainte pentru a ne referi la aceste variabile dinamice locale. (Capitolul 4 discuta clasa de memorie "statica" in care variabilele locale isi pastreaza valoarea intre apelurile la functii).
Deoarece variabilele automate vin si pleaca odata cu apelurile de functii, ele nu-si pastreaza valoarea de la un apel la altul si trebuie initializate explicit inainte de fiecare intrare. Daca nu sint setate, rezultatele vor fi imprevizibile.
Ca o alternativa la variabilele automate, este posibil sa definim variabile care sa fie "externe" tuturor functiilor, adica, variabilele globale care sa fie accesate prin nume de orice functie care doreste sa o faca. (Acest mecanism este foarte asemanator cu COMMON din FORTRAN sau EXTERNAL din PL/1). Deoarece variabilele externe sint accesibile global, ele pot fi folosite in locul listelor de argumente pentru a comunica date intre functii.
Mai mult, deoarece variabilele externe exista permanent, si nu apar si dispar dupa cum functia este apelata sau s-a terminat, ele isi pastreaza valorile chiar si dupa ce s-a terminat functia care le-a setat.

O variabila externa trebuie sa fie definita in afara oricarei functii; acest lucru face sa se aloce memorie reala pentru ea. Variabila trebuie deasemenea sa fie declarata in fiecare functie care vrea sa o foloseasca; aceasta se poate face fie printr-o declaratie explicita "extern", fie implicit prin context. Pentru a face discutia corecta, vom rescrie programul precedent, in care line, save, max vor fi declarate variabile externe. Aceasta va cere modificari in apeluri, in declaratii si in corpurile celor trei functii.

#define MAXLINE 1000 /* marimea maxima a liniei de intrare */
char line[MAXLINE]; /* linia de intrare */
char save[MAXLINE]; /* cea mai lunga linie este salvata aici*/
int max; /* lungimea liniei celei mai mari */
main() /* gaseste linia cea mai lunga ;versiune specializata*/
{
int len;
extern int, max;
extern char save[];
max = 0;
while ((len = getline() > 0)
if (len > max) {
max = len;
copy();
}
if (max > 0) /* a fost cel putin o linie */
printf("%s", save);
}

getline() /* versiune specializata */
{
int c, i;
extern char line[];
for (i = 0; i < MAXLINE-1 && (c = getchar()) != EOF && c != '\n'; ++i)
line[i] = c;
if (c == '\n') {
line[i] = c;
++i;
}
line[i] = '\0';
return(i);
}

copy() /* versiune specializata */
{
int i;
extern char line[], save[];
i = 0;
while ((save[i] = line[i]) != '\0')
++i;
}

Variabilele externe din main, getline si copy sint definite de primele linii din exemplul de mai sus care declara tipul lor si provoaca o alocare de memorie pentru ele. Din punct de vedere sintactic, definitiile externe sint asemanatoare cu declaratiile pe care le-am folosit anterior dar deoarece ele apar in afara functiilor, variabilele sint externe. Inainte ca o functie sa poata folosi o variabila externa, numele variabilei trebuie sa fie facut cunoscut functiei O modalitate pentru a face aceasta este scriind o declaratie "extern"; declaratia este identica cu cea de dinainte, avind insa in plus cuvintul cheie extern.
In anumite circumstante, declaratia "extern" poate fi omisa:daca definitia externa a variabilei apare in fisierul sursa inainte de folosirea ei intr-o functie particulara, atunci nu este necesara o declaratie "extern" in functie. Deci, declaratiile "extern" din main, getline si cpoy sint redundante. De fapt practica uzuala consta in plasarea definitiilor tuturor variabilelor externe la inceputul fisierului sursa si apoi omiterea tuturor declaratiilor "extern".
Daca programul consta din mai multe fisiere sursa si o variabila este definita in fisierul 1 si folosita in fisierul 2 atunci e nevoie de o declaratie "extern" in fisierul 2 pentru a conecta cele 2 aparitii ale variabilei. Acest subiect este discutat pe larg in capitolul 4.

Puteti nota ca am folosit cu grija cuvintele "declaratie" si "definitie" cind ne-am referit la variabile externe in aceasta sectiune. "Definitiile" se refera la locul in care variabila este efectiv creata si i se asigneaza memorie; "declaratie" se refera la locul unde natura variabilei este declarata dar nu i se aloca memorie.

Fiindca veni vorba, exista o tendinta de a face totul cu ajutorul variabilelor externe deoarece ele par a simplifica toate comunicatiile - listele de argumente sint scurte si variabilele sint intodeauna acolo cind aveti nevoie de ele. Dar variabilele externe sint intodeauna acolo chiar si cind nu aveti nevoie de ele. Acest stil de a codifica este plin de pericole deoarece el conduce la programe ale caror conexiuni de date nu sint evidente clar - variabilele pot fi modificate in moduri neasteptate si chiar inadvertente iar programul devine greu de modificat daca acest lucru este necesar. A doua versiune a programului care cauta linia cea mai luunga este inferioara primei, partial din aceste motive, si partial deoarece ea distruge generalitatea a doua functii atit de utile introducind in ele numele unor variabile pe care le vor folosi.

Exercitiul 1.18. Testul din instructiunea for din functia getline de mai sus este aproape de neinteles. Rescrieti programul pentru a-l face mai clar dar pastrati acelasi comportament la sfirsitul fisierului sau la depasire de buffer. Este acest comportament cel mai adecvat ?
avatar
zooky
Moderator
Moderator

Numarul mesajelor : 147
Data de inscriere : 15/03/2009
Varsta : 24
Localizare : Cernatesti City

Vezi profilul utilizatorului http://e-learning.forumhit.ro

Sus In jos

Vezi subiectul anterior Vezi subiectul urmator Sus


 
Permisiunile acestui forum:
Nu puteti raspunde la subiectele acestui forum