Capitolul 5.2. Pointeri si argumente de functii

Vezi subiectul anterior Vezi subiectul urmator In jos

Capitolul 5.2. Pointeri si argumente de functii

Mesaj  zooky la data de Mier Mar 18, 2009 1:45 pm

Datorita faptului ca in C este posibila transmiterea de argumente unei functii prin "apel prin valoare" nu exista modalitate directa pentru functia apelata de a altera o variabila in functia apelanta. Ce este de facut atunci cind de fapt, se intentioneaza schimbarea unui argument obisnuit ? De exemplu, o rutina de sortare trebuie sa inverseze doua elemente neordonate cu o functie swap. Nu este suficient sa se scrie

swap(a, b);

unde functia swap este definita ca

swap(x, y) /* GRESIT */
int x, y;
{
int temp;
temp = x;
x = y;
y = temp;
}

Din cauza apelului prin valoare, swap nu poate afecta argumentele a si b in rutina care o apeleaza.
Din fericire, exista o modalitate de a obtine efectul dorit. Programul apelant trasmite pointeri pe valorile care trebuie schimbate.

swap(&a, &b);

Din moment ce operatorul & da adresa unei variabile, &a este un pointer pe a. In swap insasi, argumentele sint declarate ca fiind pointeri iar adevaratii operanzi sint accesati prin ei ( prin pointeri).

swap(px, py) /* interscimba *px si *py */
int *px, *py;
{
int temp;
temp = *px;
*px = *py;
*py = temp;
}

O utilizare comuna a argumentelor de tip poiter se intilneste in cadrul functiilor care trebuie sa returneze mai mult decit o singura valoare. (Veti putea obiecta ca swap returneaza doua valori, noile valori ale argumentelor sale.) Ca un exemplu sa luam o functie getint care realizeaza inversia la intrare prin transsformarea unui sir de caractere in valori intregi, un intreg la fiecare apel, getint trebuie sa returneze valoarea gasita sau semnul de sfirsit de fisier atunci cind s-a terminat sirul de caractere de la intrare. Aceste valori trebuie sa fie returnate ca obiecte separate, pentru indiferent ce valoare este utilizata pentru EOF aceasta putind fi deasemenea valoarea unui intreg-input.
O solutie, care este bazata pe functia input scanf, functie care o vom descrie in cap7, este de a folosi getint care sa returneze ca valoare o functie EOF, atunci cind se intilneste sfirsitul de fisier; orice alta valoare returnata inseamna ca a fost prelucrat un intreg obisnuit Valoarea numerica a intregului gasit este returnata printr-un argument care trebuie sa fie pointer pe un intreg. Aceasta organizare separa starea de sfirsit de fisier de valorile numerice.
Urmatoarea bucla completeaza un tablou cu intergi prin apeluri la get int.

int n, v, array[SIZE]
for (n = 0; n < SIZE && getint(&v) != EOF; n++)
array[n] = v;

Fiecare apel pune pe y pe urmatorul intreg gasit la intrare. De notat faptul ca este esential a scrie &y in loc de y, ca arg al lui getint. A scrie doar y constituie eroare de adresare, getint sustinind ca are de a face cu un pointer propriu zis.
Insasi getint este o modificare evidenta a lui atoi tratata mai inainte.

getint(pn) /* ia numarul interg -input */
int *pn;
{
int c, sign;
while ((c = getch() == ' ' || c == '\n' || c == '\t');
/*sare blancuri*/
sign = 1;
if (c == 't' || c == '-') { /* semnul */
sign = (c == '+' ? 1 : -1;
c = getch();
}
for (*pn = 0; c >= '0' && c <= '9'; c = getch())
*pn = 10 * *pn + c - '0';
*pn *= sign;
if (c != EOF)
ungetch(c);
return(c);
}

Peste tot in getint, *pn este utilizat ca o variabila int ordinara. Deasemenea, am utilizat getch si ungetch ( descrise in cap 4) in asa fel incit caracterul special ( semnalul EOF) care trebuie citit sa poata fi restocata la intrare.

Exercitiul 5.1. Scrieti getfloat pentru virgula flotanta analoaga lui getint. Ce tip de valoare returneaza functia getfloat.
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