CATEGORII DOCUMENTE |
DOCUMENTE SIMILARE |
|
TERMENI importanti pentru acest document |
|
Uniuni
O uniune este o varaibila care poate pastra (la momente
diferite) obiecte de diferite tipuri si dimensiuni, iar
compilatorul tine seama de cerintele de dimensiune si
aliniament. Uniunile permit sa se manipuleze diferite feluri de
date intr-o singura zona de memorie, fara sa se includa in
program nici un fel de informatii dependente de masina.
Ca de exemplu, sa consideram din nou o tabela de simboluri a
unui compilator. Sa presupunem ca constantekle pot fi 'int',
'float' sau pointeri de caractere. Valoarea unei constante
particulare trebuie memorata intr-o variabila de tipul
corespunzator, dar este cel mai convenabil pentru organizarea
tabelei daca valoarea ocupa aceasi dimensiune de memorie si
acelasi loc in memorie in functie de tipul ei. Aceasta este
scopul unei uniuni -sa permita ca o singura variabila care poate
sa contina oricare din mai multe tipuri. La fel ca la cimpuri,
sintaxa se bazeaza pe structuri.
union u-tag uval;
O variabila 'uval' va fi suficient de mare ca sa pastreze oricare
din cele trei tipuri, iar privitor la masina, codul generat de
compilator este indiferent de caracteristicile hard. Oricare din
aceste tipuri poate fi asignat la 'uval' si apoi utilizat in
expresii, atita vreme cit uzajul este considerat, adica tipul
utilizat trebuie sa fie cel mai recent memorat. Este
responsabilitatea programatorului sa tina seama de tipul de
data curent memorat intr-o uniune; rezultatele sint dependente de
masina daca ceva este memorat ca un tip si este extras ca altul.
Sintactic, membri unei uniuni sint accesati ca
union-name.member
sau
union-pointer->member
la fel cu structurile. Daca variabila 'utype' este folosita pentru
a tine seama
de tipul curent al marimii memorate in 'uval', poate scrie un cod,
astfel:
if (utype == INT)
printf('%dn', uval.ival);
else if (utype == FLOAT)
printf('%fn', uval.fval);
else if (utype == STRING)
printf('%sn', uval.pval);
else
printf('bad type %d in utypen', utype);
Uniunile pot sa se gaseasca in structuri si tablouri si
viceversa. Notatia pentru a accesa un membru a unei uniuni
dintr-o structura(sau viceversa) este identica cu aceea pentru
structurile in cuiburi. De exemplu in structura definita prin
struct uval;
} symtab[NSYM];
variabila 'ival' este referita astfel
symtab[i].uval.ival
iar primul caracter al sirului 'pval' prin
*symtab[i].uval.pval
In fond, o uniune este o structura in care toti membri au
deplasamentul zero, structura este suficient de mare ca sa
cuprinda cel mai mare membru, iar aliniamentul este potrivit
pentru toate tipurile din uniune Ca si la structuri singurele
operatii admise cu uniunile sint de a accesa un membru si
obtinerea adresei lui;uniunile nu pot fi asignate, nu se pot
aplica functii asupra lor, Pointeri la uniuni pot fi
utilizati de o maniera identica pinterilor la structuri.
In capitolul 8 se arata cum alocatorul de memorie prin
intermediul unei uniuni de memorie prin intermediul unei uniuni
forteaza o variabila sa se alinieze la orice fel de
particularitati de memorare.
6.9. Typedef
C admite o facilitate numita typedef pentru a crea nume pentru
noi tipuri de date. De exemplu declaratia:
typedef int LENGTH;
face numele LENGTH sinonim pentru 'int'. Tipul LENGTH poate
fi utilizat in declaratii exact la fel ca int:
LENGTH len, maxlen;
LENGTH *lengths[];
Similar, declaratia:
typedef char*STRING;
face ca STRING sa fie sinonim cu char* sau pointerul unui
caracter, care poate fi utilizat in declaratii ca:
STRING p, lineptr[LINES], alloc();
Observati ca tipul fiind declarat printr-un typedef apare in
pozitia unui nume de variabila. Sintactic, typedef este ca o
clasa de memorie, extern, static, etc. In cazul de mai sus am
utilizat litere pentru a accentua numele.
Ca de exemplu mai complicat putem folosi typedef pentru
nodurile copacului prezentat mai inainte in acest capitol:
typedef struct tnode TREENODE, *TREEPTR;
Aceasta creeaza doua noi tipuri de cuvinte cheie numite TREENODE
(o structura) si TREEPTR (un pointer la structura), dupa care
rutina 'talloc' poate deveni:
TREEPTR talloc()
{
char *alloc();
return((TREEPTR) alloc(sizeofTREENODE)));
Trebuie sa specificam ca un typedef nu creaza noi tipuri; mai
degraba renumeste tipurile existente. Variabilele astfel
declarate au exact aceleasi proprietati ca si variabilele a
caror declaratii sint explicite. In fond, typedef este ca un
#define, exceptind ca, de cind este interpretat de copilator el
face fata cu substitutiile in text care sint dincolo de
capacitatile C macro procesorului. De exemplu:
typedef int (*PFI) ();
creaza tipul PFI, care poate fi utilizat intr-un context ca
PFI strcmpp, numcmp, swap;
din programul de sort din capitolul 5.
Exista doua motive mai importante pentru a utiliza declaratiile
t9pedef. Primul este de a parametrizaun program alaturi de
problemele de portabilitate. Daca pse utilizeza typedef pentru
diferite tipuri de date care pot fi dependente de masina, numai
typedef necesita modificari daca programul este mutat pe alta
masina. O situatie obisnuita este de a folosi typedef pentru
cantitati intregi variate, cind se alcatuieste un set adecvat de
'short', 'int' si 'long' pentru fiecare masina.
Un al doilea scop a lui typedef este de a da mai mare claritate
unui program numit TREEPTR este mai usor de inteles decit unul
declarat ca un simplu pointer la o structura complicata.
In final, exista deja posibilitatea ca in viitor, compilatorul
sau * un alt program ca 'lint' sa faca uz de informatia
continuta in typedef ca sa execute niste controale in plus asupra
programului.
Politica de confidentialitate | Termeni si conditii de utilizare |
Vizualizari: 976
Importanta:
Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved