Sunteți pe pagina 1din 4

Tipuri definite de utilizator

Generaliti
Un tip definete o mulime de valori i operaiile posibile cu acestea. Adeseori e nevoie de
alte tipuri (mai complexe) dect cele de baz.
n C se pot defini tipuri enumerare, structur i uniune cu sintaxa:
cuvnt_cheie opt_nume_tip specificatie_tip opt_lista_declaratori ;
unde cuvnt cheie ::= enum | struct | union
opt_nume_tip: pt. referire ulterioar (prefixat cu enum, struct, union) opt_lista_declaratori :
pot fi declarate obiecte de tipul respectiv
Opt_nume_tip e ntr-un spaiu de nume diferit de cel comun pentru variabile, tipuri i
funcii. E mai clar s folosim totui nume diferite.

Tipuri enumerare
Folosite pentru a da nume simbolice unui ir de valori numerice.
Sintaxa: enum opt_nume_tip { lista_constante } opt_lista_declaratori ;
constantele pot avea specificate valori (i o valoare se poate repeta)
enum luni curs {ian=1, feb, mar, apr, mai, iun, oct=10, nov, dec};
implicit, irul valorilor e cresctor cu pasul 1, iar prima valoare e 0
acelai nume de constant nu poate fi folosit n dou enumerri diferite
tipurile enumerare sunt tipuri ntregi
=> variabilele enumerare se pot folosi la fel cu variabilele ntregi
cod mai lizibil dect prin declararea separat de constante
int ore_lucru[7];
enum zile_sapt {D, L, Ma, Mc, J, V, S} zi;
for (zi = L; zi <= V; zi++) ore_lucru[zi] = 8;

Structuri
Folosite pentru gruparea mai multor elemente de tipuri de date diferite
exemplu clasic: nregistrare din baz de date cu date despre persoane
struct student {
char *nume, *prenume; /* mai flexibil; nu tablou de dim. fix */
char *adresa;
char nr_tel[10];
/* sau long, suficient pentru 9 cifre */
float medie_an[5];
/* mediile pe ani de studiu */
float nota_dipl;
/* nota la examenul de diplom */
};
struct opt_nume_tip { lista cmpuri } opt_lista_declaratori ;
oricare poate lipsi, dar nu amndou (tipul n-ar putea fi folosit)
elementele unei structuri se numesc cmpuri (engl. fields)
pot fi de orice tip, dar nu de acelai tip structur (nu recursiv)
structuri de tip diferit pot avea fr conflict nume de cmpuri identice
structuri, tablouri, uniuni = tipuri agregate (= complexe, nu simple)

Definirea tipurilor: observaii practice


definirea unor nume de tip (typedef) faciliteaz nelegerea codului
tablouri: constante simbolice (nu direct numere) pentru dimensiune (modificrile
ulterioare sunt necesare ntr-un singur punct n program)
concepei structuri de date uor de modificat i de extins
anticipai limitrile care pot deveni rapid problematice
adresarea segmentat pe 16 bii n procesoarele Intel (depit)
utilizarea a doar dou cifre pentru an (problema anului 2000)
mai comun: limite fixe (i mici) pentru lungimi de nume, adrese, linii de text,
dimensiuni de fiiere, durate de timp, etc.
Pagina 1 din 4

Utilizarea structurilor
Accesul la cmpuri: se face cu sintaxa nume variabila.nume cmp
(operaia de selecie)
struct student s;
s.nume = "Stefanovici";
strcpy(s.telefon, "256123456");
s.medie_an[2] = 9.35;
Iniializarea structurilor: cmp cu cmp, ntre acolade, ca i pentru alte agregate:
struct coord { float x, y; } punct1 = { 2.5, 1.5 };
Structurile pot fi atribuite i transmise ctre / returnate de funcii.
Pt. dimensiuni mari, se prefer transmiterea / returnarea de pointeri.
NU se compar structuri cu operatori logici (doar pt. cmpuri), sau:
int memcmp(void *p1, void *p2, size t n); /* in stdlib.h */
struct { ... } x, y;
if (memcmp(&x, &y, sizeof(x))) ...

Pointeri la structuri
Accesul la cmpuri se face frecvent printr-un pointer la structur:
struct student s, *p; p = &s; (*p).nota dipl = 9.50;
Operatorul -> e echivalent cu indirectarea urmat de selecie:
pointer -> nume cmp e echivalent cu (*pointer).nume cmp
Operatorii . i -> au precedena cea mai ridicat, ca i () i []
Atenie la ordinea de evaluare !
p -> x++ nseamn (p -> x)++
++p -> x nseamn ++(p -> x)
*p -> x nseamn *(p -> x)
*p -> s++ nseamn *((p -> s)++)

Structuri i tablouri
n C, tipurile agregat pot fi combinate arbitrar (tablouri de structuri, structuri cu cmpuri de
tip tablou, etc.)
Tipurile trebuie definite n aa fel nct s grupeze logic datele.
Ex.: dac dou tablouri au acelai domeniu pt. indici i datele de la acelai indice sunt
folosite mpreun, e preferabil gruparea n structur:
char* nume_luna[12] = { "ianuarie", ... , "decembrie" };
char zile_luna[12] = { 31, 28, 31, 30, ... , 30, 31 };
/* e preferabil varianta urmtoare */
typedef struct {
char *nume;
int zile;
} tip_luna;
tip_luna luni[12] = { {"ianuarie", 31}, ..., {"decembrie", 31} };

Structuri de date recursive


Un cmp al unei structuri nu poate fi o structur de acelai tip (s-ar obine o structur de
dimensiune infinit/nedefinit!).
Poate fi ns adresa unei structuri de acelai tip (un pointer)!
=> structuri de date recursive, nlnuite (liste, arbori, etc.)
struct wl {
/* o list de cuvinte */
char *word; /* informaia propriu-zis */
struct wl *next; /* pointer la acelai tip de structur */
};
Pagina 2 din 4

Un arbore binar, avnd n noduri numere ntregi:


typedef struct t tree; /* declaraie incomplet */
struct t {
int val;
tree *left, *right; /* folosete numele din typedef */
};

Cmpuri pe bii
Se pot declara cmpuri ntregi cu un numr specificat de bii =>Testarea/setarea unor bii se
face folosind direct numele cmpului fr a fi nevoie de definirea de mti i utilizarea unor
operatori pe bii
cmp ::= nume : int const ; | : int const ;
struct packet {
int : 2;
/* primii doi bii nu intereseaz */
int error: 1; /* un bit, semnalizeaz eroare */
int status: 3; /* un cmp pe 3 bii */
int : 0;
/* foreaz alinierea la octetul urmtor */
int seq_no: 4; /* numr de secven pe 4 bii */
} pkt;
if (pkt.error) { ... }
else if (pkt.status == 5) { ... }
else pkt.seq_no++;

Uniuni
Agregate a cror valoare poate avea date de tipuri diferite, dup caz.
Sintaxa: similar cu cea pentru structuri
union opt_nume_tip { lista_cmpuri } opt_lista_declaratori ;
Lista de cmpuri este ns o list de variante:
o variabil structur conine toate cmpurile declarate
o variabil uniune conine exact una din variantele date (dimensiunea tipului e dat de
cel mai mare cmp)
o variabil uniune nu conine informaii despre varianta reprezentat
acest lucru trebuie memorat explicit n program (n alt variabil)

Utilizarea uniunilor
Exemplu: un analizor lexical (prima faz a compilatorului) returneaz:
un cod ntreg pt. fiecare atom lexical (cuvnt cheie, operator, etc.)
date suplimentare pentru identificatori (nume) i constante (valoare)
enum tok { IDENT, INUM, FNUM, DO, IF, ..., PLUS, ..., COMMA, ... };
typedef union {
char *id;
/*ir de caractere pentru identificator */
int ival;
/* valoare pentru constant ntreag */
float fval;
/* valoare pentru constant real */
} lexvalue;
enum tok token;
lexvalue lv;
switch (token) {
case IDENT: printf("%s", lv.id); break;
case INUM: printf("%d", lv.ival); break;
case FNUM: printf("%f", lv.fval); break;
}
Pagina 3 din 4

Probleme:
1. S se scrie un program care s afieze pe ecran zilele sptmnii corespunztoare unui
numr, folosind tipul enumerare (de ex: pentru numrul 20, ziua este smbt, 1 este
lunea).
2. Afiai decada
Explicaie

creia i aparine o anumit


- 1 .. 10 -> decada I
- 11 .. 20 -> decada II
- 21 .. 30 -> decada III
- 31
-> decada IV

zi

dintr-o

lun

oarecare.

3. tiindu-se numele i media unor elevi s se afieze elevii n ordinea cresctoare a


mediei. (folosii tipul predefinit)
4. Pentru a scrie catalogul, dirigintele are nevoie de numele i prenumele elevilor. Se
citete n (numrul elevilor) apoi n perechi de date. S se ordoneze aceste date
alfabetic, dup nume, iar pentru elevii cu acelai nume s se ordoneze alfabetic dup
prenume. (folosii tipul predefinit)
5. Scriei un program pentru evidena studenilor unei faculti, care s permit alegerea
repetat a uneia din opiunile de mai jos, ct timp utilizatorul dorete aceasta:
- adugarea unui student n grup;
- listarea tututor studenilor din grup;
- afiarea informaiilor despre un anumit student, cutat dup nume.
Despre fiecare student al unei grupe se cunosc numele studentului, media la sfritul
unei sesiuni, i valoarea bursei. (folosii tipul predefinit)

Pagina 4 din 4

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