Capitolul 6.2. Structuri si functii

Vezi subiectul anterior Vezi subiectul urmator In jos

Capitolul 6.2. Structuri si functii

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

Exista un numar de restrictii relative la structurile in C. Regulile esentiale sint ca nu puteti face asupra unei structuri decit operatia de obtinere a adresei cu &, si de accesare a unuia dintre membrii structurii. Acest lucru presupune ca structurile nu pot fi asignate sau copiate ca un tot unitar, si ca nu pot fi nici pasate sau returnate intre functii. (Aceste restrictii vor fi ridicate in versiunile viitoare.) Pointerii la structuri nu se supun insa acestor restricti, si de aceea structurile si functiile coopereaza confortabil. In fine, structurile automate, ca si tablourile automate, nu pot fi initializate; nu pot aceasta decit stucturile statice.

Sa vedem citeva din aceste probleme rescriind functiile de conversie de data din capitolul precedent, folosind structuri. Deoarece regulile interzic pasarea de structuri direct unei functii, trebuie fie sa pasam componentele separat, fie sa pasam un pointer catre intregul obiect. Prima alternativa se foloseste de day_of_year asa cum am scris in capitolul 5:

d.yearday = day_of_year(d.year, d.month, d.day);

Celalalt mod este de a pasa un pointer. Daca am declarat pe hiredate ca:

struct date hiredate;

si am rescris pe day_of_year, putem apoi spune:

hiredate.yearday = day-of-year(&hiredate);

deci pointerul lui "hiredate" trece la "day-of-year". Acum functia trebuie sa fie modificata deoarece argumentul sau este un pointer si nu o lista de variabile.

day-of-year(pd) /* set day of year from month, day */
struct date *pd;
{
int i, day, leap;
day = pd->day;
leap = pd->year % 4 == 0 && pd->year % 100 != 0 || pd-
>year % 400 == 0;
for (i = 1; i < pd->month; i++)
day += day_tab[leap][i];
return(day);
}

Declaratia "struct date *pd;" spune ca pd este un pointer la o structura de tip data. Notatia "pd->year" este noua. Daca p este pointer la o structura, atunci

p->member-of-structure

refera un membru particular. (Operatorul -> este un minus urmat de >.) Cu ajutorul pointerului pd poate referit si un membru al structurii, de exemplu membrul "year":

(*pd).year

Deoarece pointerii la structuri sint des utilizati este preferabila folosirea operatorului ->, forma mai scurta. In constructia de mai sus parantezele sint necesare deoarece operatorul "." este prioritar fata de "*". Atit "->" cit si "." se asociaza de la stinga la dreapta astfel:

p->q->memb
emp.birthdate.month

sint

(p->q)->memb
(emp.birthdate).month

Pentru completare dam o alta functie "month-day" rescrisa folosind structurile.

month-day(pd) /* set month and day from day of year */
struct date *pd;
{
int i, leap;
leap = pd->year % 4 == && pd->year % 100 != 0 || pd->year % 400 == 0;
pd->day = pd->yearday;
for (i = 1; pd->day > day_tab[leap][i]; i++)
pd->day -= day_tab[leap][i];
pd->month = i;
}

Operatorii de structura "->" si ". " impreuna cu "()" pentru liste si "[]" pentru indici in ierarhia prioritatilor sint cei mai puternici. De exemplu la declaratia:

struct {
int x;
int *y;
} *p;

atunci ++p->x incrementeaza pe x si nu p, deoarece ordinea implicita este ++(p->x). Parantezele pot fi utilizate pentru a modifica prioritatile: (++p)->x incrementeaza p inainte de a accesa x, iar (p++)->x incrementeaza p dupa aceea. (Acest ultim set de paranteze nu este necesar. De ce ?)

In acelasi sens, *p->y aduce ceea ce pointeaza y; *p->y++ incrementeaza y dupa ce se face accesul la ceea ce pointeaza y (la fel cu *s++); (*p->y)++ incrementeaza ceea ce pointeaza y; si *p++->y incrementeaza p dupa accesul la ceea ce pointeaza y.
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