11.3.1. Crearea unei liste circulare simplu inlantuite (LCSI)
2020/03/03 in Programare in C
La crearea unei LCSI, ca si la crearea unei LSI, se utilizeaza functiile incnod si elibnod.
Prima se foloseste pentru a incarca datele curente intr-un nod al listei, iar cea de-a doua pentru a elibera zonele de memorie alocate pentru un nod.
Amintim ca functia incnod returneaza:
0 | la eroare; |
1 | la incarcare normala; |
-1 | nu mai sunt date de incarcat in nod. |
Functia ccrelist de creare a listei returneaza:
0 | la eroare; |
-1 | la crearea normala a listei. |
int ccrelist {
/* - creaza o lista circulara;
- returneaza:
- 0 - la eroare;
- -1 - creare normala. */
extern TNOD *ptrnod;
int i, n;
TNOD *p;
n = sizeof(TNOD);
ptrnod = 0; /* initial lista este vida */
while (((p = TNOD *)malloc(n)) != 0) && ((i = incnod(p)) == 1)) {
/* s-a rezervat zona pentru nod si s-au incarcat date in zona respectiva */
if (ptrnod == 0) { /* lista este vida */
ptrnod = p;
ptrnod -> urm = p;
}
else { /* nodul curent se insereaza dupa cel spre care pointeaza ptrnod */
p -> urm = ptrnod -> urm;
ptrnod -> urm = p;
ptrnod = p; /* ptrnod pointeaza spre ultimul nod inserat in lista */
}
/* sfarsit while: p=0 sau incnod nu a returnat valoarea 1 */
if (p == 0) { /* nu s-a rezervat zona pentru nod*/
printf("memorie insuficienta la crearea listei\n");
exit(1);
}
/* - s-a rezervat zona pentru nod, dar incnod nu a reusit sa incarce date
in zona respectiva, returnand o valoare diferita de 1, deci 0 sau -1;
- valoarea returnata de incnod va fi returnata si de ccrelist. */
elibnod(p); /* elibereaza zona de memorie pentru nod si care
nu a mai fost incarcata cu date */
return i; /* i are ca valoare valoarea returnata de incnod */
}
Observatie:
Functia ccrelist a fost scrisa mai compact decat functia ccrelist utilizand expresia:
((p = TNOD *)malloc(n)) != 0) && ((i = incnod(p)) == 1)
,
care se evalueaza astfel:
- se apeleaza functia malloc pentru a rezerva o zona de n octeti in memoria heap;
- in cazul in care nu se poate rezerva o zona de n octeti, lui p i se atribuie o valoare diferita de 0 si deci primul operand al operatorului && are valoarea adevarat. In acest caz se evalueaza operandul al doilea al operatorului &&, care apeleaza functia incnod pentru a incarca datele curente in zona a carei adresa de inceput este valoarea lui p;
- in cazul in care nu se pot rezerva n octeti in memoria heap, lui p i se atribuie valoarea 0 si deci primul operand al operatorului && este fals;
- in acest caz, intreaga expresie este falsa si deci nu se mai evalueaza cel de-al doilea al operatorului &&.
- de asemenea, expresia este falsa si in cazul in care lui p i s-a atribuit o valoare diferita de 0, dar incnod a returnat o valoare diferita de 1.