Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




Structuri si uniuni

c


Structuri si uniuni

Structuri. Declaratie.

Structurile sunt tipuri de date agregate care grupeaza mai multe date, in general de tipuri diferite - desi nu obligatoriu! - care au o caracteristica comuna: descriu diverse atribute ale aceleiasi entitati.



Ex. Datele unui angajat dintr-o intreprindere, datele care definesc o adresa (domiciliu) coordonatele unui punct din spatiul bi, tri, n-dimensional, etc. Structurile sunt echivalente cu tipuri de date similare din alte limbaje, precum tipul record din Pascal.

Intrucat fiecare tip de "obiect" care se modeleaza printr-o structura are atribute distincte, structurile nu sunt de fapt tipuri concrete ci permit definirea (de catre programator) a caracteristicilor tipului respectiv. Caracteristicile respective alcatuiesc un "sablon", o matrita care specifica atributele tuturor obiectelor de acelasi tip.

Structurile (ca tip de date specifice) se declara in felul urmator:

struct eticheta_tip

Cuvantul cheie struct p 333h72d recizeaza ca declaratia care urmeaza este pentru un nou tip de date ale carui atribute sunt precizate de membrii structurii. Un anumit tip de structura poate fi precizat, de exemplu pentru a declara instante ale acelei structuri (variabile), cu ajutorul etichetei care precizeaza ce tip de structura se declara

Operatii cu structuri. Accesul la membri

O structura poate fi initializata cu Ajutorul unei liste de initializatori, cate unul pentru fiecare membru. Exemplu

struct s ;

struct s v=; /*declaratia si initializarea variabilei v de tipul struct s*/

O structura poater fi asignata altei structuri, ca o entitate;

struct s u;

u=v; /*membrii variabilei u au aceleasi valori ca si cei ai variabilei v */

Variabilele de tip structura pot fi transmise ca argumente la functii si pot fi returnate ca valori ale unei functii.

struct s funct(struct s x); /*declaratie de functie care are un argument de tip struct s */

/* si returneaza o valoare de tip struct s */

u=funct(v); /*apelul functiei si asignarea valorii returnate la o variabila de tip struct s*/

Variabilele de tip structura nu sunt utile daca nu pot fi acesati, individual, membrii lor. Accesul la membrii unei variabile de tip structura se face cu ajutorul operatorului . (punct).

Generic:

nume_variabila.nume_membru /* valoarea membrului nume_membru al variabilei

/* cu numele nume_variabila */

Ex. v.c /* membrul c al variabilei v */

u.c /* membrul c al variabilei u */

Structuri imbricate

Membrii unei structuri pot fi structuri (de un tip diferit!).

Ex.

struct point ;

struct rectangle ;

struct s; /* eroare: membrii unei structuri nu pot fi structuri de acelasi tip*/

OBS. Interdictia/imposibilitatea declararii de structuri avand ca membri structuri de acelasi tip rezida din caracterul recursiv al unei astfel de declaratii, ceea ce determina imposibilitatea rezolvarii uneia din sarcinile legate de declararea variabilelor de tipul respectiv: rezervarea de spatiu! (La declararea oricarei variabile se rezerva si spatiu pentru acea variabila!)

Pointeri la structuri. Tablouri de structuri. Tablouri de pointeri la structuri

Variabilele de tip structura fiind. variabile, ele ocupa o anumita zona de memorie si ca atare au o adresa - adresa de inceput a zonei de memorie unde este stocata variabila respectiva. Adresa unei variabile structura se poate memora intr-o variabila de tipul pointer la o structura de acel tip.

Ex.

struct s v, *pv=&v;

Cu declaratia de mai sus, v este o variabila de tipul struct s, pv este un pointer la o structura de tipul struct s, iar *pv este tot una cu v (daca pv are ca valoare adresa lui v) adica o structura de tip struct s.

Accesul la membrii unei structuri, prin intermediul unui pointer care contine adresa variabilei respective se face in felul urmator:

(*pv).nume_membru

din cauza precedentei mai mari a operatorului de acces la membrii unei structuri (.) decat a operatorului de dereferentiere (*).

Exista o alternativa pentru accesul la membrii unei structuri prin intermediul unui pointer si anume prin utilizarea operatorului ->

Ex.

pv->nume_membru

Deasemenea, structurile (de acelasi tip) se pot agrega in tablouri.

Ex.

struct s t[DIM];

In exemplul de mai sus, t este adresa tabloului de structuri, t[i] este elementul de indice i al tabloului, adica o variabila de tip struct s, iar accesul la membrii unui element al tabloului se face prin expresii de tipul

t[i].nume_membru

Intrucat pointerii se folosesc cu precadere pentru a indica/accesa elemente de tablou, in exemplul urmator se prezinta modalitatea de a accesa membrii unui element al unui tablou de structuri prin intermadiul unui pointer.

Ex.

struct s t[DIM], *p=t;

(p+i)->nume_membru /*acces la un membru al elementului de indice i*/

p->nume_membru /*acces la un membru al elemnetului "curent"*/

Structuri cu autoreferire. Liste, arbori, tabele de cautare (hashing)

Structurile reprezinta metoda preferata pentru implementarea listelor, arborilor, tablourilor de cautare (vezi si discutia referitoare la Probleme care implica utilizarea tablourilor sau a listelor



Structurile nu pot contine, ca membri, structuri de acelasi tip! Explicatia consta in imposibilitatea rezervarii de spatiu pentru o variabila de acest tip, dupa cum rezulta din exemplul urmator:

struct s     v;

Oridecate ori compilatorul intalneste o declaratie (de definire) a unei variabile, una din actiunile intreprinse o reprezinta generarea de cod pentru rezervarea de spatiu ("crearea variabilei") pt variabila respectiva. In cazul unei variabile structura, aceasta implica rezervarea de spatiu pentru fiecare membru in parte.

v.c    - 1 byte

v.n    - variabila structura

v.n.c - 1 byte

v.n.n - variabila structura

v.n.n.c - 1 byte

v.n.n.n - variabila structura.

.si procesul nu poate fi terminat!

In schimb, o structura poate contine ca membru un pointer la o structura de acelasi tip

struct s     v;

v.c    - 1 byte

v.next    - 2 (4) bytes

si procesul de rezervare de spatiu s-a incheiat!

Structurile care contin ca membri pointeri spre structuri de acelasi tip se numesc structuri cu autoreferire. Structurile cu autoreferire reprezinta mijlocul de implementare a listelor, arborilor, tabelelor de cautare sau hashing.

Operatorul typedef

Limbajul C permite definirea de noi nume de tipuri pentru tipuri de date existente. Aceasta facilitate este accesibila prin operatorul typedef. Sintaxa operatorului este:

typedef nume_tip_existent nume_nou_de_tip;

OBS. Noul nume de tip, creat cu typedef poate fi folosit in acelasi mod ca si vechiul nume, cu care este sinonim!

Ex.

typedef int Coord; /* Coord este un intreg */

typedef struct tnode * Treeptr; /*Treeptr este un pointer la struct tnode */

typedef char * String; /* String este un pointer la char */

OBS. In ultimul exemplu, desi String este sinonim cu un pointer la char si deci poate fi folosit (legal) in :

char c;

String p=&c;

Dar o astfel de utilizare ar fi improprie, intrucat, string inseamna "sir" (de caractere, in context!), ceea ce nu e .cazul in exemplul anterior! Exemplul urmator indica o utilizare pertinenta pentru String:

char t[ ] = "Timisoara";

String p = s, q;

Q = (String)malloc( strlen(p)+1);

intrucat, valoarea lui p este intradevar adresa unui sir (de caractere)!

Numele "create" cu typedef au aceeasi semnificatie ca si sinonimele lor si pot fi utilizate oriunde se poate utiliza un nume de tip predefinit!

Uniuni. Declaratie

Uniunile sunt tipuri de date care permit partajarea aceluiasi spatiu de memorie de catre mai multe variabile (de tipuri diferite) care nu trebuie sa coexiste (simultan). Sintaxa declaratiei unei uniuni:

union eticheta ;

Ca si in cazul structurilor, declaratia unei uniuni precizeaza un "model"/"sablon" si ca atare nu este insotita de rezervare de spatiu. Spatiu se rezerva doar in momentul declararii unei variabile de tip uniune.

Spatiul necesar unei variabile uniune trebuie sa fie (este) suficient pentru a pastra cel mai mare (care are nevoie de cel mai mult spatiu) membru.

Initializarea (pe linia de declaratie a) unei variabile uniuni se poate face doar cu o valoare corespunzatoare primului membru.

Operatii cu uniuni

Ca si in cazul structurilor, variabilele uniune pot fi asignate/copiate (inclusiv transmise ca argumente actuale la apelul unei functii, respectiv returnate de o functie), li se poate prelua adresa si membri sai pot fi accesati individual. Operatorul de acces la membri este acelasi ca la structuri, adica .

Cade in sarcina programatorului sa urmareasca care dintre membri variabilei uniune este memorat in aceasta. Exista o modalitate standard pentru a realiza aceasta urmarire.

Ex.

#define INT    0

#define FLOAT 1

#define STRING 2

union u {

int ival;

float fval;

char *sval;

; v;

int v_type;

Oridecate ori se memoreaza un membru in variabila uniune v, actiuneaeste insotita de actualizarea valorii variabilei v_type:

v.ival=val_intreaga;

v_type=INT;

.

v.fval=val_flotanta;

v_type=FLOAT;

.

v.sval=adresa_sir_caractere;

v_type=STRING;

Oridecate ori trebuie "exploatata" valoarea variabilei uniune, se verifica tipul valorii memorate curent in v prin "interogarea" variabilei v_type:

if(v_type == INT)

printf(" %d ", v.ival; /* "exploateaza" pe v.ival */

else if (v-type == FLOAT)

printf(" %f ", v.fval); /* "exploateaza" pe v.fval */

else if(v_type == STRING)

printf(" %s ", v.sval; /* "exploateaza" pe v.sval */

else

printf("bad union member! ");





Document Info


Accesari: 2979
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2025 )