Sunteți pe pagina 1din 10

Lucrare de laborator N9

Tema: Tipuri de date definite de utilizator, re denumirea tipurilor. Scopul lucrrii: Definirea i utilizarea unui tip nou de date: structuri, reuniuni, enumerri, cmpuri de bii; nsuirea modalitii de re denumire a tipurilor. Suport teoretic: Un mod de grupare al datelor este tabloul. Tabloul este un set ordonat de date de acelai tip. Un alt mod de grupare al datelor este structura. Structura reunete date de diferite tipuri, dar care se afl ntr-o legtur logic. Obiectele ce fac parte din structur se numesc cmpuri sau membrii structurii. La definirea i utilizarea structurilor e necesar a cunoate trei lucruri: 1) definirea structurii; 2) declararea variabilei, care corespunde acestui tip; 3) asigurarea accesului la componentele variabilei-structur. O declaraie de structur are forma: struct nume { lista de declaraii } nume1, nume2,, numen; Aici nume definete un tip nou de date, iar nume1, nume2,..., numen sunt structuri, adic variabile de tipul nume; lista de declaraii declar componentele structurii de tip nume. Exemplu de definire: struct { char title[20]; int year; float value; };. Structura dat are 3 cmpuri. In unul se pstreaz denumirea crii, n altul anul ediiei, n al treilea preul. Tipului structur i se poate asocia un nume generic, care poate fi indicat n forma: typedef struct { char title[20]; int year; float value; } book ;. Specificatorul typedef este executat de ctre compilator, nu de ctre preprocesor ca #define. n continuare numele generic book poate fi utilizat la definirea noilor structuri. Exist i alt modalitate de asociere a numelui generic tipului structura: struct book { char title[20]; int year; float value; };. Aceast modalitate este necesar la definirea structurilor recursive deoarece typedef nu este suficient: struct node{ int date; node* next; };. Structura S nu poate conine membri de tipul S, dar poate conine membri ce pointeaz ctre S. Observaie: cnd definii o structur, definii nu o variabil, ci un tip compus de variabile. Nu va exista nici o variabil pn nu vei declara una de acest tip. Declararea variabilelor de tip structur se poate face odat cu definirea ei: struct { char title[20]; int year; float value; } date1, mas[10];. n C++ dac a fost deja declarat o structur, putem declara variabile de acest tip folosind doar numele ei generic, fr a preceda cu cuvntul cheie struct. De exemplu avnd declararea struct book { char title[20]; int year; float value; }; putem declara book date2, date3[10]. Cnd este declarat o variabil de tip structur compilatorul de C/C++ aloc automat suficient memorie pentru toate elementele ei. Lungimea zonei de memorie rezervat pentru variabila de tip struct rezult din nsumarea lungimilor cmpurilor. Aceasta nu poate depi 65520 octei (ca orice variabil de tip structurat). Pentru o structur i dovedete utilitatea operatorul sizeof, care asigur determinarea lungimii zonei de memorie asociate unei variabile sau unui tip de date. Accesul la membrii stucturii se face n dou moduri: global sau pe componente. Referirea global este permis numai n operaia de atribuire, cu condiia ca ambele variabile (surs i destinaie) s aib acelai tip. Referirea pe componente (prin numele lor) este o reflectare a faptului c articolul este o structur cu acces direct. Referirea cmpurilor unei structuri se face prin calificare, folosind operatorul. (punct). De exemplu: dac declarm book libry, identificatorul libry.value indic la membrul value al structurii libry. Identificatorul libry.value este variabil de tipul float i se utilizeaz asemntor variabilelor de acest tip, ca de exemplu: scanf( %f ,&libry.value). Dac sunt declarate dou variabile a i b de acelai tip structur putem efectua atribuirea a=b. Nu se admite atribuirea ntre variabile de tip structur care aparin abloanelor diferite, fie i foarte asemntoare.

Se pot declara pointeri ctre structuri. Exist dou ntrebuinri ale pointerilor pentru structuri : generarea unei apelri de funcii prin referin i crearea listelor nlnuite. De exemplu : struct bal { float bilan; char nume[80]; } pers, *pstr;. Atunci pstr=&pers; plaseaz adresa structurii pers n pstr. Pentru a avea acces la membrii structurii folosind acest pstr se utilizeaz operatorul ->: pstr->bilan , pstr->nume[0]. Un alt mod de grupare a datelor este reuniunea. Diferena este doar aceea c se substituie cuvntul struct prin cuvntul union. Declararea tipului reuniune se realizeaz astfel: union nume_tip { tip_cimp1 cimp1; tip_cimp2 cimp2; ...; tip_cimpn cimpn;}; Spre deosebire de o structur lungimea zonei de memorie rezervate pentru o variabil de tip reuniune va fi egal cu maximul dintre lungimile cmpurilor componente. Gestiunea coninutului respectivei zone de memorie va trebui realizat de ctre programator. Referirea la elementele unei reuniuni se face ca i la structuri. Exemplu de declarare de reuniune: union a { int x; long y; double z; char z[5]; } p, r[6], *t; Aici s-au declarat reuniunea p de tipul a, tabloul de reuniuni r ce const din 6 elemente i fiecare element este o reuniune de tipul a, un pointer t ce pointeaz spre acelai tip a. Pentru fiecare reuniune declarat se vor aloca cte 8 octei, deoarece tipul double necesit 8 octei numrul maxim. Un alt tip definit de utilizator este tipul enumerare. Acest tip permite folosirea numelor sugestive pentru valori numerice. O declaraie de tip enumerare are forma: enum nume_generic { nume0, nume1, , numen} list_variabile; Aici nume_generic este numele tipului enumerare nou declarat, nume0, nume1,..., numen sunt numele sugestive care se vor folosi n continuare n locul valorilor numerice 0, 1, ..., n i anume: nume0 substituie valoarea 0, nume1 substituie valoarea 1, ..., numen substituie valoarea n. Iar list_variabile sunt declarate variabile de tipul nume_generic, adic variabile de acest tip enumerare. Aceste variabile sunt similare cu variabilele de tip int. De exemplu definim enum season { win,spr,sum,aut } s; Atunci printf(%d %d, spr,sum) va afia 1 2. La declaraia tipului enumerare se pot impune i alte valori pentru numele sugestive. De exemplu, dac vom folosi construcia numei=si n loc de numei n lista numelor sugestive, atunci aceasta va impune pentru numele sugestiv numei valoarea si. Respectiv numei+1 va avea valoarea si+1. Dac definim n felul urmtor enumerarea de mai sus enum seazon { win=1,spr,sum,aut } s; Atunci printf(%d %d, spr,sum) va afia 2 3. Limbajul de programare C permite accesul la unul sau mai muli bii din octet. Una din metodele de prelucrare pe bii este organizarea unui tip nou tipul cmpuri de bii. Acetia sunt structuri speciale n care se definesc numrul de bii ocupai de fiecare element. O declaraie pentru un tip cmpuri de bii are forma: struct nume { tip nume_cimp1 : lungime_cimp ; tip nume_cimp2 : lungime_cimp ; tip nume_cimpn : lungime_cimp ; } n1, n2,..., nm; Aici tip poate fi unsigned, int, signed, char, unsigned char, iar lungime_cimp este lungimea cmpului n bii i nu poate depi doi octei. Numele cmpului poate lipsi,

atunci el definete o zon de bii ne utilizat din octetul respectiv. Lungimea cmpului poate fi 0, atunci cmpul urmtor se aloc n octetul urmtor. Biii se aloc ncepnd de la biii de ordin inferior ai octetului spre cei de ordin superior. Dac un cmp nu ncape n octetul curent, el se aloc n octetul urmtor. Referirea la cmpurile de bii se face ca i n cazul structurilor obinuite. Exemplu de declarare a tipului cmpuri de bii: struct BITFIELDS { unsigned a : 2; int b : 4; unsigned c : 1; unsigned : 3; int d : 2 ; } x;

Aici este declarat variabila x de tipul cmpuri de bii. Aceast declarare ne asigur urmtoarea amplasare: 15 14 13 12 ne utilizai 11 d 10 9 8 7 ne utilizai 6 c 5 4 b 3 2 1 a 0

Dac cmpul d ar fi avut lungimea mai mare dect 6 ar fi fost amplasat automat n urmtorul octet. Pentru a regla n mod forat acest lucru se folosete, dup cum s-a spus mai sus, lungimea 0 a unui cmp. n structuri pot fi utilizai n comun att componente obinuite ct i cmpuri de bii. De exemplu: struct angajat { char nume[20]; float plata; unsigned active : 1; // activ sau ntrerupt unsigned impozit : 3; } ; definete o nregistrare despre salariat care folosete doar un octet pentru a pstra dou informaii: statutul angajatului i impozitul. Variabilele de tip cmpuri de bii au i restricii: 1) nu putem obine adresa unui cmp de bii; 2) nu pot fi introduse n tablouri. C admite o facilitate numit typedef pentru a crea nume pentru noi tipuri de date. O astfel de declaraie de tip are forma: typedef nume_tip_vechi nume_tip_nou; De exemplu declaraia: typedef int LENGTH;

face numele LENGTH sinonim pentru "int". Tipul LENGTH poate fi utilizat n declaraii exact la fel ca int: LENGTH len, maxlen; LENGTH *lengths[]; Similar, declararea: typedef char* STRING;

face ca STRING sa fie sinonim cu char* sau pointerul unui caracter, care poate fi utilizat n declaraii ca: STRING p, lineptr[LINES] ; Exemple de programe: Exemplul 8.1. Programul simplific o fracie raional. Simplificarea se face prin mprirea numrtorului i numitorului la cel mai mare divizor comun al lor. #include<conio.h> #include<stdio.h> void main()

{ typedef struct { long unsigned n; // cmpul n reprezint numrtorul, m - numitorul long unsigned m; } Rational; Rational s; long unsigned k, cmmdc=1, h; clrscr(); puts(Introducei o fracie raional); scanf (%lu%lu,&s.n,&s.m) ; puts(Ai introdus fracia: ); printf(%lu/%lu\n,s.n,s.m); h=s.n < s.m ? s.n : s.m; // h este minimul dintre numrtor i numitor for(k=1;k<h/2;k++) if(s.m%k==0 && s.n%k==0) cmmdc=k; s.n=s.n/cmmdc; s.m=s.m/cmmdc; puts(Fracia simplificat este:); printf(%lu/%lu,s.n,s.m); getch(); } Exemplul 8.2. Programul declar o structur carte care conine 3 elemente. Primul element conine numele autorului, al doilea denumirea crii, al treilea preul. Sunt prelucrate informaiile despre cteva cri. #include<conio.h> #include<stdio.h> #define maxc 100 struct carte { char nume[20]; char titlu[40]; float prt; } void main() { carte bibl[maxc]; // tablou de cri int i, c=0; puts(Introducei titlul crii. Pentru sfrit acionai [enter] la nceput de linie); while ( c<maxc && gets(bibl[c].titlu) !=NULL && bibl[c].titlu[0] != \0 ) { puts(Autor:); gets(bibl[c].nume); puts(Preul:); scanf(%f, &bibl[c++].pret); fflush(stdin); // golirea intrrii puts(Introducei titlul urmtoarei cri:); } puts(Iat lista crilor); for (i=0;i<c;i++) printf(%s, %s : $%.2f\n,bibl[i].titlu, bibl[i].nume, bibl[i].pret); } Exemplul 8.3. Se d o list de persoane i punctajele obinute de acestea la un concurs. Programul ordoneaz descresctor persoanele n funcie de punctaj i afieaz lista ordonat. #include<conio.h> #include<stdio.h> #define max 20 struct persoana { char nume[max]; int punctaj ; } ; int Citeste ( persoana p[]) { int i,n; printf(Dai numrul de persoane: ); scanf(%d,&n); for (i=0; i<n; i++) {fflush ( stdin ); Printf ( Dai numele persoanei nr. %d: , i+1); gets( p[i].nume ); p[i].nume[max]=\0 ; printf ( Dai punctajul lui %s: , p[i].nume );

scanf ( %d, &p[i].punctaj ) ; fflush ( stdin ) ;

return n; } void Schimba ( persoana *a, persoana *b) { persoana aux; aux=*a; *a=*b; *b=aux; } int Ordoneaza ( persoana p[], int n) { int i, j, ord=1 ; for ( i=0 ;i<n-1 ;i++) if ( p[i].punctaj<p[i+1].punctaj ) ord=0 ; if ( !ord ) { for ( i=0; i<n-1; i++ ) for ( j=i+1; j<n; j++) if ( p[i].punctaj<p[j].punctaj ) Schimba ( &p[i], &p[j] ); } return ( !ord ); } void Afiseaza ( persoana *x, int n ) { int i; for ( i=0; i<n; i++ ) printf ( %d. %20s -> %4d. \n , i+1, x[i].nume, x[i].punctaj ); } void main() { persoana x[max]; // irul persoanelor int n; clrscr(); puts ( Ordonare personae dupa punctaj ); if (( n = Citeste(x))==0 ) puts ( Nu exista persoane. ); else { if ( Ordoneaza (x,n) puts ( Am ordonat persoanele ); else printf ( Persoanele erau deja ordonate\n ); Afiseaza(x,n); } getch(); } Exemplul 8.4. Programul exemplific folosirea reuniunilor pentru citirea i afiarea datelor despre mai multe persoane de ambele sexe. #include<conio.h> #include<stdio.h> #include<stdlib.n> union partener { char sotie[20]; char sot[20]; }; struct persoana { char nume[20]; char sex; int virsta; union partener p; }; void Citeste ( int nr_p, persoana *x ) { int vs; char sx; printf ( Se citesc datele persoanei a %d-a:\n, nr_p ); fflush ( stdin ); puts ( Numele: ); gets ( x->nume ); puts ( Virsta: ); scanf ( %d, &vs ); x->virsta=vs; fflush ( stdin ); puts ( Sexul: ); scanf ( %c, &sx ); x->sex=sx; fflush ( stdin );

} void Scrie ( int nr_p, persoana x ) { if ( wherey ()==20 ) { puts ( Apasati o tasta ); getch(); } printf ( Datele persoanei a %d-a:\n, nr_p ); printf ( Numele: %s Virsta: %d Sexul: %c , x.nume, x.virsta, x.sex ); if ( x.sex==F || x.sex==f ) printf ( Numele sotului: %s\n, x.p.sot ); else printf ( Numele sotiei: %s\n, x.p.sotie ); } void main() { clrscr(); persoana om[20]; int i,n; puts ( Dati numarul de personae: ); scanf ( %d, &n ); for ( i=0; i<n; i++) Citeste ( i+1, &om[i] ); for ( i=0; i<n; i++ ) Scrie ( i+1, om[i] ); getch(); } Exemplul 8.5. Programul afieaz codul binar ASCII al simbolului introdus de la tastatur. #include<stdio.h> #include<conio.h> struct byte { int b1:1; int b2:1; int b3:1; int b4:1; int b5:1; int b6:1; int b7:1; int b8:1; } ; union bits { char ch; byte bit;} b; void decode ( bits b ); void main() { do { b.ch=getche(); printf ( ":" ); decode ( b ); } while ( b.ch!='q' );} void decode ( bits u ) { if ( u.bit.b8 ) printf ( "1" ); else printf ( "0" ); if (u.bit.b7 ) printf ( "1" ); else printf ( "0" ); if ( u.bit.b6 ) printf ( "1" ); else printf ( "0" ); if ( u.bit.b5 ) printf ( "1" ); else printf ( "0" ); if ( u.bit.b4 ) printf ( "1" ); else printf ( "0" ); if ( u.bit.b3 ) printf ( "1" ); else printf ( "0" ); if ( u.bit.b2 ) printf ( "1" ); else printf ( "0" ); if ( u.bit.b1 ) printf ( "1" ); else printf ( "0" ); printf ( "\n" ); }

if ( x->sex==F || x->sex==f ) { puts ( Dati numele sotului: ); gets ( x->p.sot ); } else { puts ( Dati numele sotiei: ); gets ( x->p.sotie ); }

Exemplul 8.6. Programul exemplific folosirea enumerrilor. #include<stdio.h> #include<conio.h> enum spectrum { red, orange, yellow, green, blue, violet } ; void main() { enum spectrum color; puts ( Introduceti culoarea ( pentru ieire tastai q ) ); while ( ( scanf (%d, &color)) == 1 ) { switch ( color ) { case red : puts ( Trandafirii sunt rosii ); break; case orange : puts ( Macii sunt orange ); break; case yellow : puts ( Florile florii soarelui sunt galbene ); break; case green : puts ( Iarba este verde ); break; case blue : puts ( Clopoeii sunt albatri ); break; case violet : puts ( Toporasii sunt violeti ); break; default : printf ( Nu cunosc nimic de culoarea data.\n ); } puts ( Urmatoarea culoare ); } } Exemplul 8.7. Programul declar un tablou de structuri student cu elementele: nume numele studentului, tabloul note[5] pentru a pstra notele, med pentru pstrarea notei medii. Se utilizeaz funciile de introducere a datelor despre fiecare student, de calculare a notei medii fiecrui student i atribuirii ei variabilei med, de afiare a listei studenilor. #include<stdio.h> #include<conio.h> #include<stdlib.h> struct student { char nume[10]; int note[5]; float med; }; void initiere (student * s, int n); void calcul (student * s, int n); void afisare (student * s, int n); void main() { int n; clrscr(); student *m; puts (Dai numrul de studeni:); scanf (%d, &n); m=(student*)malloc(n*sizeof(student)); initiere (m,n); calcul (m,n); afisare (m,n); getch (); } void initiere (student * s, int n) { int i, j, q; for ( i=0; i<n; i++ ){ fflush ( stdin ); printf ( "nume %i: ", i+1 ); gets ((s+i)->nume); for ( j=0; j<5; j++ ) { printf ( "nota %i: ",j+1); scanf ( "%i",&q ); (s+i)->note[j]=q;}} } void calcul ( student* s, int n) { int i,j; float f; for (i=0; i<n; i++ ) { f=0.0; for ( j=0; j<5; j++ ) f+=(s+i)->note[j]; (s+i)->med=f/5.0; } }

void afisare ( student *s, int n) { puts (" NUME | MEDIA "); for ( int i=0; i<n; i++ ) printf ( "%-10s|%7.1f\n",(s+i)->nume, (s+i)->med ); } Probleme propuse spre rezolvare: 1. Programul realizeaz operaii cu fracii raionale ( introducere, extragere, atribuire, inversare, adunare, scdere, nmulire, mprire ). 2. Programul realizeaz admiterea la un liceu i permite: iniializarea vectorului de nregistrri de tip elev; adugarea unui elev n vector; nlocuirea unui elev cu alt elev; inserarea unui elev pe o anumit poziie n vector; eliminarea din vector a unui elev avnd un anumit nume; cutarea unui elev dup nume; calcularea mediilor; listarea alfabetic a elvilor; listarea elevilor n ordinea descresctoare a mediilor. 3. Programul administreaz un parc de automobile. Informaiile relative la un automobil sunt: numrul de locuri, marca, tipul de carburant, numrul de nmatriculare. Programul permite intrarea unei maini, ieirea unei maini, nlocuirea unei maini cu alta de acelai model (avnd alt numr de nmatriculare). 4. Programul invit utilizatorul s introduc ziua, luna (denumirea prescurtat) , anul i afieaz numrul zilelor ce s-au scurs de la nceputul anului pn la ziua introdus. 5. Fiind date dou fracii p i q programul afieaz forma ireductibil a fraciilor p+q, p-q, p/q, p*q, punnd n eviden numrtorul i numitorul acestora. 6. Programul determin de cte ori o persoan nscut n anul A>1900, luna L, ziua z, avnd vrsta v i-a aniversat ziua de natere n aceeai zi a sptmnii cu cea n care s-a nscut. 7. Programul calculeaz valoarea unei expresii raionale. 8. Programul determin denumirea zilei dup o dat calendaristic presupus corect. Folosii tipul union. ntrebri de control: 1. 2. 3. 4. 5. Ce este un tip definit de utilizator ? Care sunt aceste tipuri i necesitatea lor ? Ce este o structur ? Care este deosebirea dintre o structur i un tablou ? Cum se declar o structur ? Cum se face referirea la componentele unei structuri ? Cum se aloc memorie unei structuri ? Definii o structur care s conin denumirea prescurtat a lunii pn la trei simboluri, numrul de zile a lunii i numrul de ordine al lunii. 6. Definii un tablou din 12 structuri ca n punctul 5 i efectuai iniializarea lui pentru un an bisect. 7. Condiia ca dou puncte distincte A i B ( de tip structur) s aparin aceleiai axe de coordonate este: a) A.x==0 && B.x==0 && A.y==0 && B.y==0 b) ( A.x==0 || B.x==0 ) && ( A.y==0 || B.y==0) c) A.x==0 && B.x==0 || A.y==0 && B.y==0 d) A.x==0 || B.x==0 && A.y==0 || B.y==0 8. Dat un fragment de program: struct name { char first[20]; char last[20]; } ; struct bem { int limbs; name title; char type[30]; } ; bem *pb; bem deb = { 6, { Bernazel, Gwolkapwolk }, Arcturan }; A) Ce va afia: printf(%d\n, deb.limbs); printf(%s\n, pb->type);

printf(%s\n, pb->type + 2) ? B) Cum poate fi accesat Gwolkapwolk ( n dou moduri ) 9. Ce este o reuniune ? Care este deosebirea dintre o structur i o reuniune ? 10. Cum se aloc memoria pentru o reuniune ? 11. Ce reprezint tipul cmpuri de bii ? 12. Cum se face referirea la cmpuri de bii ? 13. Ce tip poate avea un cmp de bii ? 14. Care este lungimea maxim a unui cmp de bii ? 15. Ce semnific lipsa numelui unui cmp de bii n declaraia tipului cmp de bii ? 16. Fie urmtoarea declarare : struct cimp { unsigned a : 3; int b : 2; unsigned c : 4; unsigned d : 1; int e : 2 ; } x; Ce amplasare ne asigur aceast declarare ? 17.Ce reprezint tipul enumerare ? Cum se declar tipul enumerare ? 18. Cum se aloc memoria pentru datele de tip enumerare ? 19.Care valori implicite substituie numele sugestive din declaraia unui tip enumerare ? 20.Cum se pot impune alte valori dect cele implicite pentru numele sugestive din declaraia unui tip enumerare ? 21.Ce tip au valorile numelor sugestive din declaraia unui tip enumerare ? 22.Ce operaii pot fi efectuate cu datele de tip enumerare ? 23.Ce reprezint specificatorul typedef ? 24.Care-i deosebirea dintre typedef i #define ?

10

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