Documente Academic
Documente Profesional
Documente Cultură
Lab 7 TipuriDefiniteDeUtilizator
Lab 7 TipuriDefiniteDeUtilizator
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)
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} };
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
zi
dintr-o
lun
oarecare.
Pagina 4 din 4