cursul nr. 11 -...
TRANSCRIPT
Cursul nr. 11
TIPURI DE DATE DEFINITE DE
UTILIZATOR
Enumerarea
Structuri de date
Câmpuri de biţi
Uniuni
Tipuri de date definite de utilizator
Limbajele C/C++, oferă următoarele posibilităţi de definire de noi
tipuri de date:
declaraţia typedef – permite redenumirea tipurilor de date;
prin aceasta creşte lizibilitatea programului;
enumerarea – permite denumirea unui tip de date asociat cu
tipul int simultan cu definirea unei liste de constante;
structura – defineşte colecţii de date de diferite tipuri referite
printr-un singur nume;
câmpuri de biţi – reprezintă membrii unei structuri care nu
sunt alocaţi la nivel de octet, ci alocaţi la nivel de bit;
uniunea – defineşte colecţii de date de tipuri diferite care
folosesc în comun o zonă de memorie.
Observaţie:
Limbajul C++ oferă în plus faţă de C posibilitatea definirii de clase,
acestea fiind tipuri de date care respectă principiile programării
orientate pe obiecte.
Enumerarea
Tipul enumerare constă dintr-un ansamblu de constante
întregi, fiecare asociată unui identificator.
Sintaxa declaraţiei este:
enum <id_tip_enum> {id_elem<=const>,…} <lista_id_var>;
unde: - id_tip_enum = nume tip enumerare ;
- id_elem = nume element;
- const = constantă de iniţializare a elementului.
id_tip_enum reprezintă un nume de tip de date, putându-se
folosi similar cu orice tip de date predefinit, putându-se
declara variabile, pointeri, tablouri, etc. din acel tip.
Identificatorii elementelor trebuie să fie unici în domeniul lor
(diferiţi de numele oricărei variabile, funcţie sau tip declarat
cu typedef).
Enumerarea
Exemple
enum boolean {false, true}; // valoarea identificatorului false este 0,
// iar a lui true este 1
sau
typedef enum {false, true} boolean; // declaraţia este echivalentă
// declaraţiei anterioare
Enumerarea
Exemple
• enum luna {Ian, Feb, Mar, Apr, Mai, Iun, Iul, Aug, Sep, Oct, Noi, Dec}
luna_an;
luna_an=Mai;
printf("Luna actuală este: %d", luna_an);
• enum luna {Ian=1, Feb, Mar, Apr, Mai, Iun, Iul, Aug, Sep, Oct, Noi, Dec} ;
luna luna_an;
luna_an=Mai;
printf("Luna actuală este: %d", luna_an);
Enumerarea
Exemple
enum t emperatura {frig=-10, cald=22, foarte_cald=35}; temperatura t1, t2 ;
enum colors
{ rosu=650, oranj=590, galben=570, verde=510, albastru=475,
indigo=445, violet=400
} color;
Enumerarea
/* Exemplu de folosire a enumerarilor */
#include <stdio.h>
#include <math.h>
typedef enum {FALSE, TRUE} boolean;
boolean verif_triunghi(int a, int b, int c)
{ if (a<b+c && b<a+c && c<a+b)
return TRUE;
else
return FALSE;
}
double aria (int a, int b, int c)
{ double p=(a+b+c)/2.;
return (sqrt(p*(p-a)*(p-b)*p-c));
}
void main()
{ int m=3, n=4 , p=5;
if (verif_triunghi(m, n, p)==TRUE)
printf ("\n aria triunghiului este: %lf", aria(m ,n, p));
else
printf("\n %d, %d, %d nu pot fi valori ale laturilor unui triunghi", m, n, p);
}
Enumerarea
/* Exemplu de folosire a enumerarilor */
#include <stdio.h>
int main()
{
enum Days{Sunday=1,
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};
Days TheDay;
printf("Please enter the day of the week (1 to 7)\n");
scanf("%d", &TheDay);
if(TheDay == Sunday || TheDay == Saturday)
printf("Hurray it is the weekend\n");
else
printf("Curses still at work\n");
return 0;
}
Structuri de date
Structura este o colecţie de date referite cu un nume comun.
O declaraţie de structură precizează identificatorii şi tipurile
elementelor componente şi constituie o definiţie a unui nou
tip de date.
Sintaxa declaraţiei unui tip structură este:
struct id_tip_struct
{
tip_elem1 id_elem1;
tip_elem2 id_elem2;
…
tip_elemN id_elemN;
} lista_id_var_struct;
unde: - struct = cuvânt cheie pentru declararea tipurilor structură;
- id_tip_struct = numele tipului structură declarat;
- tip_elemK = tipul elementului K, unde K=1…N;
- id_elemK = numele elementului K;
- lista_id_var_struct=lista cu numele variabilelor declarate.
Structuri de date
Exemplu
struct ex_stru
{ int m1;
char m2;
float m3;
};
O variabilă de tip ex_stru se declară :
ex_stru var1;
Byte m1 m2 m3999 1000 1001 1002 1003 1004 1005 1006
... ...Adrese memorie
Adresa variabilei (&var1)
var1
999Byte1007
Structuri de date
Referirea unui membru al unei variabile de tip structură se
face folosind operatorul de selecţie (.) (punct), sub forma:
nume_variabilă . nume_câmp
De exemplu, pentru variabila var1 declarata astfel:
struct ex_stru
{ int m1;
char m2;
float m3;
};
ex_stru var1;
Campurile (membrii) se refera:
var1.m1
var1.m2
var1.m3
Structuri de date
Variabilele de tip structură au aceleaşi atribute ca orice
variabilă, ele fiind determinate de locul şi specificatorii
folosiţi pentru declarare.
Astfel, dacă declaraţia nu se face cu iniţializare, membrii
variabilelor iau valoare 0 dacă declaraţiile sunt globale sau
statice, sau valori reziduale dacă declaraţiile sunt locale.
Adresa de alocare a variabilelor de tip structură poate
determina cu operatorul & (adresă), iar numărul de bytes
ocupaţi în memorie cu operatorul sizeof.
printf(”\n adresa variabilei var1 este : %p ”, &var1);
printf(„\n variabila var1 ocupa %d octeti de memorie”, sizeof(var1));
Structuri de date
Declaraţia unei variabile de tip structură se poate face cu
iniţializare prin enumerarea valorilor membrilor în ordinea în
care apar în declaraţie.
ex_stru var1 = { 25, ‘a’, 1.75 } ;
Se poate folosi operatorul de atribuire ( = ) între variabile de
acelaşi tip. Se face copierea octet cu octet a conţinutului
variabilei p1 în variabila p2, astfel că după atribuire cele două
variabile au conţinut identic.
ex_stru var1 = { 25, ‘a’, 1.75 } ;
ex_stru var2 ;
var2 = var1;
Structuri de date
Membrii unei structuri pot fi folosiţi ca orice variabilă simplă
de acelaşi tip, lor putându-li-se face atribuiri sau pot fi folosiţi
în orice expresie validă pentru acel tip de dată
struct ex_stru
{ int m1;
char m2;
float m3;
};
void main (void)
{
ex_stru var1;
scanf(“%d”, &var1.m1);
scanf(“%c”, &var1.m2);
scanf(“%f”, &var1.m3);
printf(“\nvar1.m1= %d”, var1.m1);
printf(“\nvar1.m1= %c”, var1.m2);
printf(“\nvar1.m1= %f”, var1.m3); }
Structuri de date
Se pot declara pointeri la structuri care pot prelua adresa
oricărei variabile de tipul structurii respective (Exemplul
13.14.). În această situaţie, se poate face referire la membrii
obiectului folosind sintaxa:
(*nume_pointer). nume_câmp (1) sau
nume_pointer -> nume_câmp (2)
Cele două variante sunt echivalente, dar în mod uzual se
foloseşte varianta (2).
Exemplu
ex_stru var1;
ex_stru * ps; // se declară un obiect pointer la ex_stru
ps = &var1 // atribuire de valoare pointerului
ps->m1 = 100;
(*ps).m1 = 100;
Structuri de date
Variabilele pointer la tipuri de date structură sunt utilizate în
mod frecvent pentru alocare dinamică de memorie.
I. ps= (ex_stru*)malloc(sizeof(ex_stru)); // alocarea unui element de
// tip persoana
ps = (ex_stru *)malloc(dim*sizeof(ex_stru)); // alocarea unui tablou cu
// dim elemente de tip
// ex_stru
free(ps); // dealocarea memoriei
II. ps = new ex_stru[dim]; // alocarea unui tablou cu dim
…. // elemente de tip ex_stru
delete [ ] ps; // dealocarea memoriei
Structuri de date
Exemple:
struct carte {
char titlu[50];
char autor[50];
char editura[20];
float pret;
};
struct complex {
float re, im;
};
struct punct {
float x, y, z;
};
struct polinom {
int grad;
int coef[10];
};
Câmpuri de biţi
Câmpul de biţi este un membru al unei structuri sau uniuni
care are alocat un grup de biţi în interiorul unui cuvânt de
memorie.
Declaraţia unei structuri cu membrii câmpuri de biţi se face
sub forma:
struct <id_tip_struct>
{
tip_elem1 id_elem1 : lungime;
tip_elem2 id_elem2 : lungime;
…
tip_elemN id_elemN : lungime;
} <lista_id_var_struct>;
unde lungime reprezintă numărul de biţi utilizaţi pentru
reprezentarea în memorie a câmpului respectiv.
Câmpuri de biţi
Restricţiile care se impun la declararea câmpurilor de
biţi sunt:
tipul câmpului poate fi intreg cu sau fără semn;
lungimea este o constantă întreagă cu valoarea în
domeniul 0-15;
nu se poate evalua adresa câmpului, deci nu se poate
folosi operatorul & pentru acel câmp, deci nu se pot folosi
pointeri pentru aceste câmpuri;
nu se pot folosi tablouri de câmpuri de biţi.
Câmpuri de biţi
Exemplu:
struct ex_bit
{ unsigned m1 : 1;
unsigned m2 : 4;
unsigned m3 : 1;
unsigned m4 : 10;
};
ex_bit variabila_mea;
Byte Byte Byte Byte Byte Byte Byte Byte999 1000 1001 1002 1003 1004 1005 1006
... ...Adrese memorie
variabila_mea
12345678910111213141516
m4 m3 m2 m1
Uniuni
Uniunea permite utilizarea în comun a unei zone de
memorie de către mai multe obiecte de tipuri diferite.
Declararea uniunilor se face folosindu-se cuvântul cheie
union.
Sintaxa de declarare a unei uniuni este similară
declaraţiei unei structuri:
union <id_tip_uniune>
{ tip_elem1 id_elem1;
tip_elem2 id_elem2;
…
tip_elemN id_elemN;
} <lista_id_var_uniune>;
unde: union = cuvânt cheie pentru declararea tipurilor uniune;
id_tip_uniune = numele tipului uniune declarat;
tip_elemK = tipul elementului K, unde K=1…N;
id_elemK = numele elementului K;
lista_id_var_uniune = lista cu numele variabilelor de tipul
declarat, id_tip_uniune.
Uniuni
#include <stdio.h>
struct octet
{ unsigned int b0:1; // se declară o structură care ocupă un octet
unsigned int b1:1; // de memorie, cu acces separat, prin
unsigned int b2:1; // membrii săi, la fiecare bit în parte
unsigned int b3:1;
unsigned int b4:1;
unsigned int b5:1;
unsigned int b6:1;
unsigned int b7:1;
};
union caracter
{ char val; // se declară o uniune ce ocupă un octet de memorie
octet bit; // care poate fi accesat atât ca şi char prin membrul
}; // val, sau ca octet prin membrul bit
void main ()
{ caracter i;
i.val=22;
// se afişează fiecare bit al uniunii separat folosindu-se câmpul i.bit.
printf("\n%d se reprezinta in hexazecimal 0x%x, iar in binar: \
%d%d%d%d%d%d%d%d", i.val, i.bit.b7, i.bit.b6, i.bit.b5,
i.bit.b4, i.bit.b3, i.bit.b2, i.bit.b1, i.bit.b0);
}