Sunteți pe pagina 1din 12

Universitatea Tehnică a Moldovei

FCIM
Catedra Informatica Aplicativă

Raport
la lucrarea de laborator nr. 4,5
la Structuri de Date si Algoritmi

Tema: Analiza prelucrării structurilor de date cu liste

Varianta : 3.3,4.3

A efectuat: st. gr. TI-191 Buraga Vadim


A verificat: Marin Ştefan

Chişinău – 2020
Sarcina şi obiectivele:
1. de studiat şi însuşit materialul teoretic pentru evidenţierea esenţialului proiectarii structuri pentru
reprezentarea etapelor prelucrării structurilor de date cu liste în elaborarea modelelor soluţiei, analizând
exemplele din text;
2. să se selecteze problemele din compartimentul “3 şi Anexe” şi să se elaboreze organigramele
(pentru funcţiile principale) şi programele cu liste (declarări, parcurgeri, etc.), pentru aprofundare şi rularea
programelor în limbajul C să se elaboreze scenariile succinte de soluţionare prin respectiva tehnică de
prelucrare cu calculele de verificare şi explicaţii.
3. să se analizeze tehnica modelării şi programării eficiente pentru diverse compartimente ale
diferitor situaţii cu diverse argumentări şi modele de structuri abstracte, incluzând fişiere cu teste de
verificare şi vizualizări. Prezentarea succinta a utilizarii listelor, stivelor si cozilor, explicand prin organigrame cum
are loc apelul prin referință și parcurgerea nodurilor.

Consideraţii teoretice:
Consideraţiile teoretice generale. Tipuri de date abstracte Tipul de date abstract este o entitate manipulata doar prin
operatiile ce definesc acel tip. Avantajele utilizarii tipurilor de date abstracte sunt:

• Programele devin independente de modul de reprezentare a datelor. Modul de reprezentare poate fi modificat, fara
însa a afecta restul programului (de exemplu, o multime poate fi implementata printr-un tablou sau printr-o lista
ordonata, dar partea de program ce foloseste operatorii tipului abstract rămâne neschimbata).
• Se previne violarea accidentala a datelor. Utilizatorul tipului abstract este forţat sa manipuleze datele doar prin
intermediul operatorilor ce compun tipul abstract, astfel reducându-se riscul unei distrugeri a datelor.
Dupa cum este exemplificat în continuare, în C tipurile abstracte sunt realizate folosind fişiere. Acest mod are
desigur propriile sale limitari. Mentionam doar doua din ele: nu se pot defini tablouri de tipuri abstracte si nu se pot
transmite parametri având ca si tip un tip abstract.
Pentru utilizarea eficientă a unui calculator trebuie ca relaţiile structurale existente in mulţimea datelor şi modul de acces la
aceste date să se reflecte în metodele de reprezentare şi manipulare a structurilor de date în cadrul sistemelor de calcul. Vom face
o introducere a celor mai importante noţiuni despre structurile informaţiei: proprietăţi statice şi dinamice ale diferitelor tipuri de
structuri liniare, precum şi algoritmi eficienţi pentru crearea, modificarea, regăsirea şi ştergerea informaţiilor cu o anumită
structură în interiorul sistemelor de calcul. Structurile de date arborescente vor fi introduse in materialul care trateză despre
aplicaţiile arborilor binari (Ll5). În continuare vom denumi anumiţi termeni care vor fi utilizaţi în acest material. Astfel
informaţiile conţinute într-un tabel constant dintr-o mulţime de noduri (numite şi înregistrări, entităţi sau articole). Fiecare nod se
compune din unul sau mai multe cuvinte consecutive din memoria calculatorului, fiind împărţite în părţi componente numite
cîmpuri. De exemplu, un nod poate ocupa un singur cuvînt din memorie avînd un singur cîmp de lungime egală cu lungimea
întregului cuvînt din memorie. Să presupunem acum că elementele tabelului reprezintă nişte cărţi de joc: nodurile sunt formate de
cîte un cuvînt, divizat în patru cîmpuri: MARCA, CULOARE, RANG şi URMĂTOR:
listele generale au asociate patru operatii elementare :
• Inserarea
• Stergerea
• Cautarea
• Traversarea
Inserarea reprezinta o oparatie prin care un nou element este introdus in lista.
Intr-o lista generala, inserarea unui element se face la inceputul, in interiorul sau la sfarsitul ei. Deoarece, intr-o
lista neordonata, nu conteaza pozitia unde se efectueaza inserarea, se obisnuieste ca operatia sa se efectueze la sfarsitul
ei. In acest fel elementele pot fi gasite in ordinea in care au fost ele introduse (inserate). Acesta este si motivul pentru
care Inserarea reprezinta o oparatie prin care un nou element este introdus in lista.
Intr-o lista generala, inserarea unui element se face la inceputul, in interiorul sau la sfarsitul ei. Deoarece, intr-o
lista neordonata, nu conteaza pozitia unde se efectueaza inserarea, se obisnuieste ca operatia sa se efectueze la sfarsitul
ei. In acest fel elementele pot fi gasite in ordinea in care au fost ele introduse (inserate). Acesta este si motivul pentru
care listele neordonate se mai numesc si liste cronologice.
Stergerea reprezinta o operatie care permite eliminarea unui element al listei. Aceasta operatie cuprinde:
• Cautarea elementului care trebuie eliminat
• Stergerea efectiva a elementului respectiv
Daca lista este reprezentata cu ajutorul unui vector, atunci elementele ce succed elementul care trebuie sters vor fi
deplasate spre stanga cu o pozitie. Dupa aceasta operatie elementul fiind inlocuit cu succesorul sau.
Cautarea reprezinta operatia prin care se urmareste gasirea unui element intr-o structura.
In general algoritmul de cautare secventiala (element cu element) poate fi aplicat indiferent de tipul listei sau de
modul ei de reprezentare. Daca avem de-a face cu o lista ordonata, reprezentata ca vector, se poate folosi algoritmul de
cautare binara.
Traversarea accesarea secventiala a tuturor elementelor din structura. Ea poate fi privita ca un caz special de
cautare, deoarece consta in regasirea tuturor elementelor structurii. Traversarea consta in exiistenta in algoritm a unei
bucle. La fiecare iteratie este accesat cate un element. Bucla se incheie cand aceasta operatie a fost efectuata asupra
ultimului element.
Operaţiile pe care trebuie să le efectuăm asupra listelor liniare pot include următoarele:

• accesul la nodul X[k] din listă pentru a examina sau modifica conţinutul cîmpurilor sale;
• ştergerea nodului X[k] din listă;
• înserarea unui nou nod înainte (după) nodul X[k];
• determinarea numărului de noduri dintr-o listă;
• sortarea nodurilor unei liste în ordine crescătoare (descrescătoare) a conţinuturilor numitor cîmpuri ale nodurilor;
• căutarea în listă a nodului (nodurilor) cu o valoare particulară a unui anumit cîmp;
• copierea unei liste liniare;
• combinarea a două sau mai multor liste într-una singură;
O anumită aplicaţie pe calculator rareori apelează la toate aceste operaţii în întreaga lor generalitate şi există mai
multe căi de a reprezenta liste liniare, în funcţie de clasele de operaţii care se vor efectua cel mai frecvent.
Nu există o metodă unică de reprezentare pentru listele liniare pentru care toate aceste operaţii să fie eficiente,
fiecare metodă avînd anumite avantaje, dar şi dezavantaje, care o deosebesc de celelalte.
ALOCAREA SECVENŢIALĂ
Calea cea mai simplă de a păstra o listă liniară în memoria calculatorului este de a pune elementele listei în locaţii
succesive, nod după nod. În acest fel avem LOC(X[j+1])=LOC(X[j])+c, unde LOC(V) reprezintă locaţia din memorie
a variabilei-pointer V şi c reprezintă numărul de cuvinte alocate unui nod, presupunînd că toate nodurile listei ocupă
acelaşi spaţiu de memorie. Rezultă că LOC(X[j])=L+cj, unde L este o constantă numită adresa de bază.
Ideea alocării înlănţuite a fost deja expusă cînd am prezentat un mod de reprezentare în calculator a cărţilor de joc:
fiecare nod are un cîmp suplimentar în care se păstrează adresa nodului următor sau Λ pentru ultimul nod al listei.
Cîteva comparaţii între alocarea secvenţială şi alocarea înlănţuită se impun de la sine:
●Alocarea înlănţuită necesită spaţiu suplimentar de memorie pentru pointeri (referinţe).
●Este uşor de extras un nod din cadrul unei liste înlănţuite. De exemplu, pentru a şterge al II-lea nod din lista
referită de primul este suficient să copiem referinţa din al II-lea nod peste referinţa din primul nod. Pentru alocarea
secvenţială o asemenea ştetrgere implică în general deplasarea unei părţi din listă în locaţii diferite. O concluzie
similară se obţine pentru înserarea unui nuo nod în interiorul unei liste liniare.
●Accesul la diferite părţi din listă este mult mai rapid în cazul alocării secvenţiale. Aşa cum am văzut, locaţia
nodului k din listă în cazul alocării secvenţiale este o funcţie liniară de k, deci pentru a obţine accesul la acest nod se
consumă un timp constant. În cazul alocării înlănţuite acest acces necesită k iteraţii urmărind referinţele a k-1 noduri.
Astfel utilizarea memoriei înlănţuite este mai eficientă cînd parcurgerea listei se face secvenţial şi nu aleatoriu.
●Alocarea înlănţuită permite o mai mare flexibilitate în ceea ce priveşte reunirea a două sau mai multor liste
într-o singură listă sau desfacerea unei liste în mai multe părţi.
Folosirea alocării înlănţuite implică existenţa unei liste a spaţiului disponibil numită în continuare lista DISP (sau
stiva DISP, deoarece ea funcţionează ca o stivă).
Mulţimea tuturor nodurilor care sunt utilizate la un moment dat se înlănţuie într-o listă liniară iar variabila-
referinţă DISP va păstra adresa nodului din vîrful stivei DISP sau va fi egală cu Λ dacă stiva este vidă.
Operaţia notată X←DISP extrage nodul din vîrful stivei DISP şi stabileşte ca variabila-referinţă X să se refere la
acest nod extras, care este astfel rezervat pentru utilizarea ulterioară. Ea constă din următoarele operaţii elementare:
dacă DISP=Λ, atunci depăşire; astfel X←DISP, DISP←LEG(DISP).
Operaţia inversă DISP←X transferă nodul adresat de X înapoi în vîrful stivei nodurilor disponibile: LEG(X)←DISP,
DISP←X.
INSERŢIE: P←DISP; INFO(P)←Y, LEG(P)←T, T←P.
EXTRAGERE: Dacă T=Λ atunci subdepăşire; altfel P←T, T←LEG(P), Y←INFO(P); DISP←P.
Structura de date lista

Lista este o structura dinamica, situata in memoria centrala, in care toate elementele sunt de acelasi tip; numarul de elemente
este variabil, chiar nul. De remarcat diferentele fata de definitia tabloului: tabloul este o structura statica, situata in memoria
centrala, in care toate elementele sunt de acelasi tip; numarul de elemente este constant.
O alta definire a listei este:
O lista L este o secventa de zero sau mai multe elemente, numite noduri, toate fiind de acelasi tip de baza T.
L=a1,a2,...,an (n>=0)
Daca n>=1, a1 se spune ca este primul nod al listei, iar an, ultimul nod. Daca n=0, lista este vida. Numarul de noduri se
numeste lungimea listei.
Un nod al listei liniare care apare ca o structura recursiva, avand o componenta de tip pointer la structura, reprezentand
legatura ( inlantuirea ) spre nodul urmator. Lista in care fiecare nod are o sinfura inlantuire se numeste lista simplu
inlantuita.
    struct nod{
        TipCheie cheie;
        TipInfo info;
        struct nod* urmator;
  };
  struct nod* inceput;

  //pentru o scriere mai compacta se pot defini tipurile:


  typedef struct nod Nod, *pNod;
  pNod inceput;
Caracteristica unei astfel de structuri consta in prezenta unei singure inlantuiri. Campul cheieserveste la identificarea nodului,
campul urmatore pointer de inlantuire la nodul urmator, iar cel infocontine informatia utila.
Variabilainceputindica spre primul nod al listei. In unele situatii in locul lui inceputse utilizeaza un nod fictiv, adica o variabila
de tip struct Nod cu campurile cheie si info neprecizate, dar campul urmatorindicand spre primul nod al listei.
De asemenea uneori este util a se pastra pointerul spre ultimul nod al listei.
O varianta este a listelor circulare la care dispare notiunea de prim, ultim nod, lista fiind un pointer ce se plimba pe lista

 Liste ordonate si reorganizarea listelor


a)Cautarea intr-o lista neordonata; tehnica fanionului
Se considera o lista simplu inlantuita, cu nodurile de tip Nod. Daca inceput indica spre primul nod al listei, iar ordinea
cheilor in lista este aleatoare, cautarea unei chei implica traversarea listei. Functia booleana gasit returneaza valoarea
pointerului spre nodul cu cheia egala cu cea cautata, daca un astfel de nod exista si valoarea NULL in caz contrar:  
pNod gasit(TipCheie val){
          pNod poz;
          poz=inceput;
          while (poz!=NULL)
               if (poz->cheie==val)
                   return poz;
               else 
                   poz=poz->urmator;
          return poz; // cu valoarea NULL 

Cautarea se poate perfectiona prin utilizarea metodei fanionului, lista prelungindu-se cu un nod fictiv numit fanion, la creare lista
continand acest unic nod. In functia gasit, inainte de baleierea listei, informatia cautata se introduce in cheia nodului fanion, astfel
incat va exista cel putin un nod cu cheia cautata:  
pNod fanion;
pNod gasit(TipCheie val){
          pNod poz;
          for(poz=inceput,fanion->cheie=val;poz->cheie!=val;
              poz=poz->urmator);
          if(poz==fanion)
                return NULL;
          return poz;

b)Crearea unei liste ordonate; tehnica celor doi pointeri


In continuare se prezinta o metoda foarte simpla pentru crearea unei liste ordonate, tipurile pNod si Nod fiind cele definite
anterior. Lista se initializeaza cu doua noduri fictive pointate de doua variabile pointer, inceput sifanion:  
pNod inceput, fanion;
 

void init(void);
     inceput=(pNod)malloc(sizeof(Nod));
     fanion=(pNod)malloc(sizeof(Nod));
     inceput->urmator=fanion;
}
Pentru introducerea unei noi chei in lista, pastrand ordonarea, se va scrie o functie gasit, care daca gaseste cheia in lista returneaza
valoarea 1 si pointerii p1 spre nodul gasit si p2 spre cel anterior, respectiv in cazul negasirii cheii, valoarea 0 si pointerii p1 si p2
spre nodurile intre care trebuie facuta insertia:  
int gasit(TipCheie val, pNod* p1, pNod* p2){
          for(*p2=inceput,*p1=(*p2)->urmator,fanion->cheie=val;
              (*p1)->cheie<=val;p2=p1,*p1=(*p1)->urmator);
          return *p1!=fanion && (*p1)->cheie==val;

Fragmentul de program care insereaza o noua cheie este:  


    pNod p1,p2,p3;
    TipCheie val;
          ...
    if (!gasit(val,&p1,&p2)){
            p3=(pNod)malloc(sizeof(Nod)); //creare nod nou
            p2->urmator=p3; //legatura de la nodul anterior la cel nou
            p3->cheie=val;
                                 //completare p3->info
            p3->urmator=p1; //legatura de la noul nod la cel urmator
    }

Pentru tiparirea cheilor dintr-o lista ordonata astfel creata, pointerul care parcurge nodurile trebuie sa fie initializat cu valoarea
pointerului spre primul nod efectiv al listei, urmator celui inceput, iar parcurgerea listei se face pana la intilnirea nodului fanion:  
    pNod p;
    for(p=inceput->urmator;p!=fanion;p=p->urmator)
      //prelucrarea nodului indicat de p

Deci Lista este o mulţime finită şi ordonată de elemente de acelaşi tip. Elementele listei se numesc noduri.
Listele pot fi organizate sub formă statică, de tablou, caz în care ordinea este implicit dată de tipul tablou
unidimensional, sau cel mai des, sub formă de liste dinamice, în care ordinea nodurilor este stabilită prin pointeri.
Nodurile listelor dinamice sunt alocate în memoria heap. Listele dinamice se numesc liste înlănţuite, putând fi simplu
sau dublu înlănţuite.
Prin definitie, o multime dinamica de structuri recursive de acelasi tip, pentru care sunt definite una sau mai multe
relatii de ordine cu ajutorul unor pointeri din compunerea structurilor respective, se numeste lista inlantuita.
Elementele unei liste se numesc noduri.
Daca intre nodurile unei liste exista o singura relatie de ordine, atunci lista se numeste simplu inlantuita. In mod
analog, lista este dublu inlantuita daca intre nodurile ei sunt definite doua relatii de ordine.
O lista este n-inlantuita daca intre nodurile ei sunt defi-nite n relatii de ordine.
Aspecte ale implementarii listelor liniare simplu înlantuite. O solutie de implementare a listelor liniare este sub
forma unei înlantuiri de elemente cu aceeasi structura, aflate în memorie la diverse adrese si legate între ele prin
intermediul pointerilor. Scopul utilizarii listelor este de a economisi spatiu de memorie, motiv pentru care se foloseste
alocarea dinamica în locul celei statice (utilizata în cazul tablourilor). Accesul la un element al listei se poate face doar
secvential, parcurgând elementele aflate înaintea sa în înlantuire.
Pentru a exploata avantajul listelor în ceea ce priveste economia de spatiu de memorie, trebuie acordata o atentie deosebita
operatiilor asupra listei. În general, asupra unei liste se pot face operatii de insertie/adaugare de noduri, stergere de noduri si
parcurgerea nodurilor.
Pentru a putea folosi o lista, este necesar sa fie retinuta adresa de început a listei (adresa primului nod). Ne vom referi în
continuare la aceasta adresa prin pointerul prim.
În cazul parcurgerii listei, operatia este relativ simpla. Cu ajutorul unui pointer auxiliar se pleaca de la prim si se urmareste
legatura spre nodul urmator, pointerul auxiliar primind pe rând adresa nodului urmator.

Sarcina Lucrarii :
3.3 Să se scrie funcţia pentru inserarea unui nod la începutul unei liste simplu înlănţuite. Funcţia are ca parametri
capul listei în care se inserează şi numărul care se inserează. Prin numele funcţiei se întoarce noul cap al listei.

1. #include <stdio.h>  
2. #include <conio.h>  
3. typedef  struct NOD {       //facem o structura pentru definirea tipului lui NOD  
4. int a ;     //introducem o variabila a de tip int  
5. struct NOD *next;   //inlantuirea spre urmatorul NOD  
6. } NOD;  
7.   
8. NOD *inceput(NOD *NEW, NOD *prim , int a) { // Cream funcţia ce are ca parametri capul listei în c
are se                    inserează şi numărul care se inserează.   
9. NOD *p; //se introduce pointerul p de tip NOD  
10. p=NEW;  // se creează noul nod  
11. p->next=prim;        //în adresa se introduce adresa capătului  
12. prim = p;   //atribuim primului element adresa lui p      
13. return p; }     // se returnează noul nod ca fiind capătul listei  
14.    
15. void main () {  
16. NOD *prim = NULL;       //atribui primului element al listei NULL  
17. int a;      //introducem variabila a de tip int  
18. NOD *NEW = (NOD*) malloc (sizeof(NOD));     //se aloca dinamic memorie pentru NEW  
19. printf("Nr. de introdus la inceput este = ");  
20. scanf("%i",&a);     //se citeste numarul care trebuie de introdus la inceputul listei  
21. prim = inceput(NEW,prim,a); //facem apelul la functia inceput     
22. printf("%i",a);     //se afiseaza numarul introdus la inceputul listei  
23. getch();}   //sfarsitul programului  
4.3 Sa se realizeze un program C ce citesste o matrice rare de ordin n in forma de lista. Se cere sa se tipareasca
matricea si determinantul asociat.

1. #include<stdio.h>  
2. #include<stdlib.h>  
3.   
4.   
5. struct Node  
6. {  
7.     int value;  
8.     int row_position;  
9.     int column_postion;  
10.     struct Node *next;  
11. };  
12.   
13. void create_new_node(struct Node** start, int non_zero_element,  
14.                      int row_index, int column_index )  
15. {  
16.     struct Node *temp, *r;  
17.     temp = *start;  
18.     if (temp == NULL)  
19.     {  
20.         temp = (struct Node *) malloc (sizeof(struct Node));  
21.         temp->value = non_zero_element;  
22.         temp->row_position = row_index;  
23.         temp->column_postion = column_index;  
24.         temp->next = NULL;  
25.         *start = temp;  
26.   
27.     }  
28.     else  
29.     {  
30.         while (temp->next != NULL)  
31.             temp = temp->next;  
32.   
33.           
34.         r = (struct Node *) malloc (sizeof(struct Node));  
35.         r->value = non_zero_element;  
36.         r->row_position = row_index;  
37.         r->column_postion = column_index;  
38.         r->next = NULL;  
39.         temp->next = r;  
40.   
41.     }  
42. }  
43.   
44.   
45. void PrintList(struct Node* start)  
46. {  
47.     struct Node *temp, *r, *s;  
48.     temp = r = s = start;  
49.   
50.     printf("Pozitia din rind: ");  
51.     while(temp != NULL)  
52.     {  
53.   
54.         printf("%d ", temp->row_position);  
55.         temp = temp->next;  
56.     }  
57.     printf("\n");  
58.   
59.     printf("Pozitia din coloana: ");  
60.     while(r != NULL)  
61.     {  
62.         printf("%d ", r->column_postion);  
63.         r = r->next;  
64.     }  
65.     printf("\n");  
66.     printf("Value: ");  
67.     while(s != NULL)  
68.     {  
69.         printf("%d ", s->value);  
70.         s = s->next;  
71.     }  
72.     printf("\n");  
73. }  
74. int det(int sparseMatric[100][100], int n)  
75. {  
76.     int Minor[100][100];  
77.     int i,j,k,c1,c2;  
78.     int determinant;  
79.     int c[100];  
80.     int O=1;  
81.   
82.     if(n == 2)  
83.     {  
84.         determinant = 0;  
85.         determinant = sparseMatric[0][0]*sparseMatric[1][1]-sparseMatric[0][1]*sparseMatric[1][0]; 
 
86.         return determinant;  
87.     }  
88.     else  
89.     {  
90.         for(i = 0 ; i < n ; i++)  
91.         {  
92.             c1 = 0, c2 = 0;  
93.             for(j = 0 ; j < n ; j++)  
94.             {  
95.                 for(k = 0 ; k < n ; k++)  
96.                 {  
97.                     if(j != 0 && k != i)  
98.                     {  
99.                         Minor[c1][c2] = sparseMatric[j][k];  
100.                         c2++;  
101.                         if(c2>n-2)  
102.                         {  
103.                             c1++;  
104.                             c2=0;  
105.                         }  
106.                     }  
107.                 }  
108.             }  
109.             determinant = determinant + O*(sparseMatric[0][i]*det(Minor,n-1));  
110.             O=-1*O;  
111.         }  
112.     }  
113.     return determinant;  
114. }  
115.   
116.   
117. int main()  
118. {  
119.      int i,k,res,j,n=0;  
120.     int sparseMatric[100][100];  
121.     printf("Introducem nr de coloane si rinduri:\n");  
122.     scanf("%d",&n);  
123.     printf("Introducem prima matrice rara:\n");  
124.      for (i = 0; i < n; i++)  
125.     for (j = 0; j < n; j++)  
126.       scanf("%d", &sparseMatric[i][j]);  
127.   
128.   
129.     struct Node* start = NULL;  
130.   
131.     for (int i = 0; i < n; i++)  
132.         for (int j = 0; j < n; j++)  
133.   
134.   
135.             if (sparseMatric[i][j] != 0)  
136.                 create_new_node(&start, sparseMatric[i][j], i, j);  
137.   
138.     PrintList(start);  
139.     res = det(sparseMatric,n);  
140.     printf("determinantul este: %d",res);  
141.   
142.     return 0;  
143. }  

Întrebări de autocontrol:
1. Definiți noțiunea – tip abstract de date.
Tipul de date abstract este o entitate manipulată doar prin operațiile ce definesc
acel tip. Avantajele tipurilor de date abstracte sunt:
a) programele devin independente de modul de reprezentare a datelor adică
modul de reprezentare poate fi modificat, fără însă a afecta restul
programului.
b) se previne violarea accidentală a datelor, utilizatorul fiind forțat să
manipuleze datele doar prin intermediul operatorilor ce compun tipul
abstract.
2. Cum se definește o structură?
Pentru a defini o structură trebuie să utilizăm expresia struct ce definește un nou
tip de date cu minimum doi membri. Formatul structurii este prezentat mai jos:
1. struct [tag_structura] {  
2.    definire membru;  
3.    definire membru;  
4.    ...  
5.    definire membru;  
6. } [variabilele structurii];    
tag_structura este opțional iar membrii structurii sunt variabile simple, ca
exemple int i, float b sau oricare altă definire de variabilă validă. La sfârșitul
structurii se specifică variabilele structurii (opțional). Un exemplu de declarare
a unei structuri este următorul:
1. struct Carti {  
2.    char  titlu[50];  
3.    char  autor[50];  
4.    char  editura[100];  
5.    int   id_carte;  
6. } carte;    

3. Prin ce se deosebește structura de alte tipuri de date?


În limbajul C structura se referă la o colecție ce combină diferite tipuri de date.

4. Cum se definește o variabilă de tip structură?


Considerăm că avem o structură de următorul format:
1. struct Carti {  
2.    char  titlu[50];  
3.    char  autor[50];  
4.    char  editura[100];  
5.    int   id_carte;  
6. } ;    
declararea variabilelor este prezentată în secvența de mai jos (rînd 3, 4):
1. int main( ) {  
2.     .........  
3.     struct Carti carte1;        /* Declară carte 1 de tip Carti */  
4.     struct Carti carte2;        /* Declară carte 2 de tip Carti */  
5.     ..........  
6. }  

5. Când se utilizează punctul, când săgeata în selectarea câmpurilor structurii?


1. Punctul se utilizează pentru accesarea directă a membrilor structurii în modul
următor:
1. int main( ) {  
2.     .........  
3.     struct Carti carte1;   /* Declară carte 1 de tip Carti */ 
4.     printf( "Titlu carte 1 : %s\n", carte1.titlu);  
5.     .........  
6. }  
2. Săgeata se utilizează la accesarea membrilor structurii prin intermediul pointerilor în
modul următor:
1. int main( ) {  
2.     .........  
3.     struct Carti carte1;    /* Declară carte 1 de tip Carti */
4.     struct Carti *struct_pointer;  
5.     struct_pointer = &carte1;  
6.     struct_pointer->titlu;  
7.     .........  
8. }  

6. Care sunt deosebirile între structura în limbajul C și C++?


• Structura de date în limbajul C nu poate conține funcții doar membri, în
C++ structurile pot conține atât funcții cât și membri.
• În limbajul C este necesar de indicat cuvântul cheie struct pentru crearea
unei variabile de tip structură, în C++ nu este necesar.
• Mărimea unei structuri vide în C este nedefinită, în limbajul C++ mereu
este 1.
• Structurile în limbajul C nu pot conține membri statici, în C++ structurile
conțin membri statici.
• Membrii structurii în C nu pot fi inițializați în interiorul structurii, în C++
acest lucru se permite.
• Structurile în limbajul de programare C++ pot conține constructori,
destructori, etc pe când structurile în limbajul C nu suportă acest lucru.

7. O structură poate să conțină oare altă structură?


Da. Structurile în limbajul C pot conține orice tip de date definit în C, la fel pot
include tablouri și alte structuri. Un exemplu de structură ce conține altă
structură este prezentat în secvența de program de mai jos.
1. struct coordonate{  
2.      int x;  
3.      int y;  
4. };  
5.   
6. struct dreptunghi{  
7.       struct coordonate stinga_sus;  
8.       struct coordonate dreapta_jos;  
9. } cutie;  
10.   
11. int main(){  
12.     /* Citire coordonate */  
13.     printf("\nX stinga - sus: ");  
14.     scanf("%d", &cutie.stinga_sus.x);  
15.     printf("\nY stinga - sus: ");  
16.     scanf("%d", &cutie.stinga_sus.y);  
17.     printf("\nX dreapta - jos: ");  
18.     scanf("%d", &cutie.dreapta_jos.x);  
19.     printf("\nY dreapta - jos: ");  
20.     scanf("%d", &cutie.dreapta_jos.y);  
21.     .........  
22.     return 0;  
23. }  
8. O structură poate să conțină oare pointer spre ea însăși ?
Limbajul de programare C nu permite ca o structură să conțină un câmp de
același tip ca structura, însă se pot utiliza pointeri ce fac referință la ea. Spre
exemplu:
1. typedef struct Node Node;  
2. struct Node{  
3.   int value;  
4.   Node *next;  
5.   Node *prev;  
6. };  

9. Poate oare să fie creată dinamic o variabilă de tip structură?


Alocarea dinamică de memorie este foarte importantă în limbajul C. Ea permite
construirea structurilor de date complexe precum sunt listele. Alocarea dinamică
a memoriei ne ajută să păstrăm date la care nu cunoaștem mărimea inițială. Un
exemplu de alocare dinamică a memoriei este prezentat mai jos:

1. typedef struct {  
2.     char * nume;  
3.     int virsta;  
4. } persoana;  
5.   
6. int main(){  
7.     ..........  
8.    /* Alocarea memoriei */  
9.    persoana * nume = malloc(sizeof(persoana));  
10.    /* Accesarea membrilor */  
11.    nume->nume = "John";  
12.    nume->virsta = 20;  
13.    /* Eliberare memorie */  
14.    free(me);  
15.     .........  
16.     return 0;  

Concluzie :
In aceasta lucrare am analizat prelucrarea structurilor de date cu liste. Lista este o mulţime finită şi ordonată
de elemente de acelaşi tip. Elementele listei se numesc noduri. Sructura este un obiect compus , in care se
includ elemente de orice tip , in afara de functii. In structura este obligator sa fie indicat cel putin un element.
Structurile recursive pot fi implementate in C numai in forma unor structuri dinamice, deoarece o structura nu
poate avea un camp de acelasi tip structura, ci doar pointer la structura. O lista este o secventa de zero sau mai
multe elemente, numite noduri, toate fiind de acelasi tip de baza. Daca intre nodurile unei liste exista o singura
relatie de ordine, atunci lista se numeste simplu inlantuita. In mod analog, lista este dublu inlantuita daca intre
nodurile ei sunt definite doua relatii de ordine.O lista este inlantuita daca intre nodurile ei sunt definite n relatii
de ordine.

S-ar putea să vă placă și