Sunteți pe pagina 1din 12

4.

Structuri de date neomogene


4.1.

Definire i exemple

Am studiat pn acum cteva tipuri de date, dar constatm uneori c nu sunt


suficiente, adic apar situaii n care lucrm destul de greu numai cu aceste tipuri de
date.
S presupunem c ni se cere s ntocmim o situaie pentru coal, care s
conin urmtoarele date primare:
1. numele elevului
2. prenumele elevului
3. media generala
4. clasa
Observm c pentru a memora aceste date cu cunotiinele acumulate pn
n prezent, ar trebui s utilizm 4 tablouri unidimensionale, dou de tip ir de
caractere, unul de tip float i unul de tip ntreg. Cu siguran scrierea programului ar
fi neplcut.
Apare astfel evident necesitatea existenei unui tip de dat cu ajutorul cruia
s putem prelucra date neomogene ca cele din exemplul de mai sus.
C++ ne pune la dispoziie un astfel de tip, numit struct, cu ajutorul cruia
utilizatorul poate s i defineasc structura de date de care are nevoie.
Forma general a tipului struct:
struct [<nume structur>]
{ tip1 <nume cmp> [,<nume cmp>, ];
[tip2 <nume cmp > [,<nume cmp >, ];

[tipn <nume cmp > [,<nume cmp >, ];


}[list variabile];
Unde
<nume structur> - desemneaz numele sub care este cunoscut tipul structurat
respectiv, n program
<tip1><tipn>
- reprezint tipurile de date din care se compune structura
<nume cmp>
- desemneaz identificatorii datelor care compun structura
(membrii structurii)
Pentru exemplul de mai sus definim urmtoarea structur:
struct elev
{char nume[20],prenume[20];
float medie;
int clasa;
};

Observie:
Tipul struct descrie doar modul cum sunt organizate datele, asemenea
tipurilor predefinite, nu rezerv o zon de memorie n care datele se pstrez.
Pentru a memora datele este obligatorie declararea unei variabile de tip
<nume structur>.

Declararea variabilelor de tipul structurii definite se poate realiza n dou moduri:


a.) Dup cum putem observa din forma general, variabilele se pot declara dup
definirea structurii.
n acest caz structura poate fi anonim, adic <nume structur> poate s
lipseasc.
b.) Oriunde n program, n acelai mod cu declararea variabilelor pentru tipurile
predefinite:
<nume structur> <nume var1>[, <nume var2>, ,<nume varn>];
n acest caz <nume structur> este obligatoriu, la definirea structurii.
Definirea unui tip structur poate fi plasat oriund n program, acest tip va fi
cunoscut din momentul definirii lui pn n momentul ncheierii structurii n interiorul
careia a fost definit.
Modul de adresare
Cum ne adresm unui anumit membru al unei structuri, tiind c avem o singur
variabil care cuprinde toate cmpurile structurii?
Pentru a putea accesa un anumit cmp din interiorul unei structuri vom folosi
operatorul de selecie direct . , acest operator are prioritate maxim.
Pentru exemplul dat
struct elev
{char nume[20],prenume[20];
float medie;
int clasa;
};
i declaraia de variabil:
elev articol;
Ne vom adresa unui cmp din variabila articol astfel:
articol.nume
articol.prenume
articol.medie
articol.clasa
2

Exemplu:
#include <iostream.h>
#include <conio.h>

//TIPUL STRUCT

struct elev
{char nume[10],prenume[20];
float medie;
int clasa;
};

//definirea structurii elev

elev a,b;
//definirea variabilelor a si b de tip elev
void main()
{cout<<"nume:";cin>>a.nume; //citirea datelor camp cu camp
cout<<"prenume:";cin>>a.prenume;
cout<<"medie:";cin>>a.medie;
cout<<"clasa:";cin>>a.clasa;
b=a;
//copierea unei structuri in alta structura
cout<< a.nume<<" "<<a.prenume<<" "<<a.medie<<" "<<a.clasa;
//afisarea datelor din a
cout<< b.nume<<" "<<b.prenume<<" "<<b.medie<<" "<<b.clasa;
//afisarea datelor din b
getch();
}

Observai n programul de mai sus, am declarat dou variabile de tip elev, a i


b, am citit datele n a , apoi le-am copiat n b.
O variabil de tip structurat poate fi copiat ntr-o alt variabil de
acelai tip cu ajutorul instruciunii de atribuire.
n C++ o astfel de copiere se numete copiere bit cu bit.
4.2.

nregistrri imbricate

S presupunem c pe lng datele elevului din exemplul precedent trebuie s mai


adugm situaiei noastre i data naterii elevului.
O dat calendaristic se compune din 3 cmpuri: zi, lun, an.
Vom putea defini datele unui elev folosind dou structuri, astfel:
Struct data
{int zi,luna,an;
};
Struct elev
{char nume[20],prenume[20];
data datan;
float medie;
int clasa;
};
elev articol;
3

Observai membrul datan reprezentnd data naterii elevului, este de tip


structurat i se folosete n interiorul altei structuri. Spunem despre tipul data c
este imbricat n tipul elev.
Se pot realiza mai multe nivele de imbricri.
Modul de adresare n cazul structurilor imbricate, pentru exemplul precedent:

articol.nume
articol.prenume
articol.datan.zi
articol.datan.luna
articol.datan.an
articol.medie
articol.clasa

Exemplu:

#include <iostream.h>
#include <conio.h>

//STRUCTURA IMBRICATA

struct data
{int zi,luna,an;
};
struct elev
{char nume[10],prenume[20];
data datan;
//datan dat de tip structurat, in interiorul unui tip structurat
float medie;
int clasa;
};
elev a;
void main()
{cout<<"nume:";cin>>a.nume;
cout<<"prenume:";cin>>a.prenume;
cout<<"zi:";cin>>a.datan.zi;
//modul de adresare al datelor imbricate
cout<<"luna:";cin>>a.datan.luna;
cout<<"an:";cin>>a.datan.an;
cout<<"medie:";cin>>a.medie;
cout<<"clasa:";cin>>a.clasa;
cout<< a.nume<<" "<<a.prenume<<" ";
cout<<a.datan.zi<<"/"<<a.datan.luna<<"/"<<a.datan.an;
cout<<" "<<a.medie<<" "<<a.clasa;
getch();
}

4.3.

nregistrri cu structur variabil

Limbajul C++ pune la dispoziia utilizatorilor nc un tip cu care utilizatorul


poate s-i defineasc structura de date pe care dorete s o foloseasc, acesta
este tipul union.
union elev
{char nume[20],prenume[20];
float medie;
int clasa;
}articol;
Dup cum se poate observa nu este nici o diferen n declararea structurii cu
tipul struct sau cu union.
i totui la ce bun dou tipuri diferite care s realizeze acelai lucru?
n programul TIPUL STRUCT de la paragraful 4.1. nlocuim struct cu union
i vom observa c toate regulile att cele de definire ct i cele de adresare
funcioneaz.
Dei nu se observ nici o diferen, la rularea programului observm c nu
obinem acelai rezultat.
Acest lucru se ntmpl deoarece tipul union memoreaz la un moment dat
doar atia octei ci sunt necesari pentru memorarea cmpului celui mai lung.
Dac adugai programului afiarea funciei sezeof(a), rezultatul funciei va fi
20, adic dimensiunea n octei a cmpului cel mai lung.
Tipul union se folosete n situaia n care dorim s crem articole cu structur
variabil.
Exemplu:
Trebuie reprezentate n plan trei tipuri de figuri geometrice: drepte, triunghiuri
i patrulatere.
Pentru fiecare tip va trebui s memorm coordonatele, astfel pentru dreapt
vom memora coordonatele extremitilor pentru triunghi cele trei coordonate ale
vrfurilor iar pentru patrulatere cele patru coordonate ale colurilor.
Vom memora aceste figuri geometrice ntr-un tablou unidimensional cu
elemente de tip structur variabil.
Definim trei structuri: dreapta, triunghi i patrulater.
Definim uniunea figura, care va conine structurile de mai sus.
Definim structura element care se compune din tipul figurii i un cmp de tip figura.
n acest fel, pentru variabila care le memoreaz se va rezerva spaiu doar
pentru structura cea mai mare (respectiv patrulater), nu se va rezerva spaiu pentru
fiecare tip de figur n parte.

#include <iostream.h>
#include <conio.h>
#define MAX 20;
struct dreapta
{float a,b;};
struct triunghi
{float a,b,c;};
struct patrulater
{float a,b,c,d;};
union figura
{dreapta dr;
triunghi tr;
patrulater pa;
};

//uniunea se compune din cele trei structuri definite mai sus

struct element
{int tip;
figura fig;
};

//conine tipul figurii si figura


//2-dreapta, 3-triunghi, 4-patrulater

element t[20];
int n;
void citire();
void afisare();
void main()
{
citire();
afisare();
getch();
}
void citire()
{int i;
cout<<"n="; cin>>n;
for(i=0;i<n;i++)
{ cout<<"tip figura(2,3,4):";cin>>t[i].tip;
switch (t[i].tip)
{case 2:cout<<"dati doua coordonate:";
cin>>t[i].fig.dr.a>>t[i].fig.dr.b;
break;
case 3:cout<<"dati trei coordonate:";
cin>>t[i].fig.tr.a>>t[i].fig.tr.b>>t[i].fig.tr.c;
break;
case 4:cout<<"dati patru coordonate:";
cin>>t[i].fig.pa.a>>t[i].fig.pa.b>>t[i].fig.pa.c>>t[i].fig.pa.d;
break;
default: cout<<"tip diferit de 2,3,4 "<<endl;
}

}
}

void afisare()
{ int i;
for(i=0;i<n;i++)
{ cout<<"tip figura "<<t[i].tip<<":";
switch (t[i].tip)
{case 2:cout<<"coordonatele dreptei:";
cout<<t[i].fig.dr.a<<" "<<t[i].fig.dr.b<<endl;
break;
case 3:cout<<"coordonatele triunghiului:";
cout<<t[i].fig.tr.a<<" "<<t[i].fig.tr.b<<" "<<t[i].fig.tr.c<<endl;
break;
case 4:cout<<"dati patru coordonate:";
cout<<t[i].fig.pa.a<<" "<<t[i].fig.pa.b<<" "<<t[i].fig.pa.c<<" "<<t[i].fig.pa.d;
cout<<endl;
break;
default: cout<<"tip diferit de 2,3,4 "<<endl;
}
}
}

4.4.

Probleme rezolvate

1. Se citesc de la tastatur dou numere complexe. S se efectueze operaiile


de adunare, scadere, nmulire i mprire cu aceste numere complexe.
Vom defini tipul structurat complex, care conine partea real i partea imaginar a
numrului.

#include <iostream.h>
#include <conio.h>

//OPERATII CU NUMERE COMPLEXE

struct complex
{float x,y;
};

//x-partea reala , y-partea imaginara

complex a,b,c;
void afisare(complex e);
void adunare();
void scadere();
void inmultire();
void impartire();

void main()
{cout<<"primul numar:"; cin>>a.x>>a.y;
cout<<"al doilea numar:"; cin>>b.x>>b.y;
cout<<"a="; afisare(a);
cout<<"b="; afisare(b);
adunare();
cout<<"suma=";
afisare(c);
scadere();
cout<<"diferenta=";
afisare(c);
inmultire();
cout<<"produsul=";
afisare(c);
impartire();
cout<<"impartire=";
afisare(c);
getch();
}
void afisare(complex e)
//afisarea unui numar complex
{if(e.y>=0)
cout<<e.x<<"+"<<e.y<<"i"<<endl;
else

cout<<e.x<<e.y<<"i"<<endl;
}
void adunare()
{c.x=a.x+b.x;
c.y=a.y+b.y;
}
void scadere()
{c.x=a.x-b.x;
c.y=a.y-b.y;
}

//adunarea a doua numere complexe

//scaderea a doua numere complexe

void inmultire()
{c.x=a.x*b.y-a.y*b.x;
c.y=a.x*b.y+a.y*b.x;
}

//inmultirea a doua numere complexe

void impartire()
//impartirea a doua numere complexe
{c.x=(a.x*b.x+a.y*b.y)/(b.x*b.x+b.y*b.y);
c.y=(a.y*b.x-a.x*b.y)/(b.x*b.x+b.y*b.y);
}

2. Pentru n elevi se citesc: numele i dou note la informatic. S se calculeze media


fiecrui elev. S se afieze elevii n ordinea descresctoare a mediilor, iar pentru
medii egale, n ordine alfabetic.
#include<iostream.h>
#include<conio.h>
#define MAX 30
struct elev
//definirea structurii de date elev
{char nume[MAX];
int n1,n2;
float media;
};
elev a[MAX];
//a-tabloul pentru memorarea elevilor
int n;
void citire();
void afisare();
void ordonare();
void main()
{ clrscr();
cout<<"n=";cin>>n;
//n-nr.elevi
citire(); clrscr(); afisare();
//citeste datele elevilor
ordonare();
//ordoneaza elevii
cout<<"Elevii in ordinea descrescatoare a mediilor"<<endl;
afisare();
//afiseaza datele elevilor
getch();
}
void citire()
//citire date
{int i;
clrscr();
for(i=1; i<=n; i++)
{cout<<"numele persoanei:"; cin.get();cin.get(a[i].nume,20,'\n');
cout<<"nota1: "; cin>>a[i].n1;
cout<<"nota2: "; cin>>a[i].n2;
a[i].media=(((float)a[i].n1+a[i].n2)/2);
}
}

//citeste numele
//citeste notele
//calculeaza media

void afisare()
//afiseaza datele elevilor
{int i;
for(i=1; i<=n; i++)
cout<<a[i].nume <<" "<<a[i].n1<<" "<<a[i].n2<<" "<<a[i].media<<endl;
getch();
}
void ordonare()
//ordoneaza elevii descrescator dup medii, iar la medii egale alfabetic
{int i,sw;
elev aux;
do{
sw=1;
for(i=1; i<n; i++)
if((a[i+1].media>a[i].media)||(a[i+1].media==a[i].media && strcmp(a[i+1].nume,a[i].nume)<0))
{aux=a[i+1]; a[i+1]=a[i]; a[i]=aux; sw=0; }
} while(!sw);
}

3. S se afieze reprezentarea intern a unei date de tip caracter folozind


reprezentarea lor pe bii.

10

#include <iostream.h>
#include <conio.h>

//REPREZENTAREA INTERNA A UNUI CARACTER

struct biti
{unsigned b0:1;
unsigned b1:1;
unsigned b2:1;
unsigned b3:1;
unsigned b4:1;
4.5. Evaluare
unsigned b5:1;
unsigned b6:1;
TESTUL
1
unsigned
b7:1;
};
1. n ce situaii utilizai tipul de date structurat?
union caracter
{biti b;2. Presupunnd c trebuie s memorai temperatura i umiditatea nregistrate
char c; n fiecare zi n decurs de o lun, descriei structura de date de care avei
nevoie.
};
3. Scriei un program n care pentru n elevi se memoreaz: numele,
caracter octet;
void main() prenumele, media la l.romn, media la matematic, media la informatic i
general.
Media general nu se citete ci se calculeaz ca medie
{cout<<"datimedia
un cracter:";
cin>>octet.c;
aritmetic
ntre
celelalte
trei medii.
cout<<"reprezentarea interna:";
S se ordoneze descresctor dup medii lista elevilor i s se afieze.
cout<<octet.b.b7<<octet.b.b6<<octet.b.b5<<octet.b.b4;
cout<<octet.b.b3<<octet.b.b2<<octet.b.b1<<octet.b.b0;
getch();
} TESTUL 2
1. Care este deosebirea ntre tipul struct i union?
2. Presupunnd c trebuie s memorai datele angajailor unei firme, descriei
structura de date tiind c avei nevoie de urmtoarele informaii: nume,
prenume, data nasterii, data angajrii, funcia, telefon, vrst.
3. Trebuie nregistrate datele a n concureni la un concurs de gimnastic.
Pentru fiecare concurent se reine: numele, prenumele, rezultatele la 6
probe (punctaje<=100) i punctajul general.
Realizai clasamentul concurenilor i primele trei premii. n cazul n care
mai muli concureni au punctaje egale, toi vor obine acelai premiu.
Punctajul general se calculeaz.
TESTUL 3
1. Dai un exemplu n care este util folosirea tipului struct.
2. Dai un exemplu n care este util folosirea tipului union.
3. Se citesc datele angajailor unei firme: nume, prenume, data nasterii, data
angajrii, funcia, telefon, salar. La citire efectuai validrile necesare pentru
ca datele s fie corecte.
S se afieze angajaii n ordinea alfabetic a funciei iar n cadrul aceleiai
funcii n ordinea descrescatoare a salariului.

11

4.6.

Probleme propuse

1. Se citesc n denumiri de ri de la tastatur mpreun cu culorile drapelelor lor


din fiierul TARI.IN. Se citete de la tastatur o culoare. S se afieze toate
rile care au n componena drapelului culoarea respectiv.
2. Dnduse dou polinoame s se calculeze suma celor dou polinoame. Pentru
fiecare termen al unui polinom se reine gradul i coeficientul folosind un tip
structurat.
3. Se dau n orae mpreun cu coordonatele lor: latitudine i longitudine(ca
abscis i ordonat). Pentru un ora citit de la tastatur s se afieze cel mai
apropiat ora de acesta. Oraele mpreun cu coordonatele lor se vor citi din
fiierul ORASE.IN.
4. Pe o tabl de ah de dimensiune maxim 10x10, se gsesc obstacole
codificate cu 1 ar csuele libere sunt codificate cu 0. Se citesc coordonatele
de pe tabla de ah ale unui nebun. S se afiseze cte obstacole se gsesc pe
traseele atacate de nebun iar dac nu se gsesc obstacole se va afia
mesajul nu sunt obstacole. Date referitopare la tabla de ah se citesc din
fiierul SAH.IN.
5. Se citesc urmtoarele date pentru angajaii unei firme:
Nume i prenume
Data angajarii
Studii-cu valorile:
f-fara studii
m-studii medii
s-studii superioare
Pentru angajaii fara studii nu se mai nregistreaza nimic
Pentru angajaii cu studii medii se memoreaz: anul absolvirii liceului i
localitatea n care a absolvit liceul
Pentru angajaii cu studii superioare se vor nregistra: facultatea,
localitatea, anul absolvirii
S se afieze angajaii n urmtoarea ordine: cu studii superioare, cu studii
medii, fr studii.
6. Se citesc de la tastatur datele pentru mai multe figuri geometrice. Acestea
sunt codificate prin caracterele: T-pentru triunghi, C-pentru cerc, D-pentru
dreptunghi, P-pentru ptrat, R-pentru romb. Pentru cerc se cunoate raza, iar
pentru celelalte figuri geometrice se cunosc dimensiunile laturilor.
S se afieze acele figuri geometrice care au arii care s difere ntre ele prin
cel mult o unitate.

12