cursul nr. 11 -...

23
Cursul nr. 11 TIPURI DE DATE DEFINITE DE UTILIZATOR Enumerarea Structuri de date Câmpuri de biţi Uniuni

Upload: others

Post on 04-Sep-2019

15 views

Category:

Documents


0 download

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

Exemplu:

union exemplu

{

char c;

int i;

float f;

};

exemplu var1;

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);

}