Documente Academic
Documente Profesional
Documente Cultură
htm
Capitolul III
Programarea orientata pe obiecte in C++:clase, obiecte, functii membru,
structuri si uniuni in analogie cu clasele, functii speciale
III. 1. Notiuni introductive
Programarea orientat pe obiecte este o tehnologie modern in domeniul programrii
calculatoarelor, care a rezultat din necesitatea realizrii de aplicaii din ce n ce mai
complexe. Programarea clasica si structurata avea urmatoarele dezavantaje: control greoi al
programelor de dimensiuni mari, dificultati cu privire la reutilizarea codurilor de programe si
inflexibiliatea adaptarii si extinderii unor module de program deja realizate. Programarea
clasica structurata are la baza celebra ecuatie a lui Nikolaus Wirth:
Program = Structuri de date + Algoritmi
Programarea Orientata pe Obiecte, POO, se fundamenteaza pe conceptul de obiect,
care este definit printr-o multime de date, numite proprietati, si o multime
de proceduri sau functii de prelucrare ale acestor date, numite metode. In consecinta,
ecuatia POO este:
Obiect = Date + Functii
sau
Obiect = Date + Functii
Obiect = Proprietati + Metode
Diferenta dintre cele doua cai de abordare ale programarii calculatoarelor consta in maniera
de abordare a programarii. In timp ce programarea clasica structurata se concentreaza pe
prelucrarea datelor, adica pe programe, proceduri si functii, POO se bazeaza pe definirea
obiectelor, adica, pe proprietatile acestora, numite date, si pe functiile acestor obiecte,
numite metode.
III.2. Clase si obiecte
La baza POO stau conceptele de clasa si de obiect.
Definitia 1
Clasa, intr-un anumit limbaj de programare, reprezinta definirea unui tip de obiecte
abstracte sau concrete, adica descrierea proprietatilor, a datelor si a metodelor, a prelucrarilor,
posibile asupra datelor. Clasa este, de fapt, o notiune abstracta, care defineste un anumit tip
de obiecte, sau, altfel spus, o clasa reprezinta multimea posibila a mai multor obiecte de
acelasi tip.
Definitia 2
Obiect, reprezinta o multime de date care descrie un anumit obiect concret sau
abstract, numite si proprietati, impreuna cu procedurile, functiile, de prelucrare a cestora,
numite metode.
Crearea unui obiect presupune specificarea clasei din care face parte, astfel
identificandu-se proprietatile obiectului si modul in care acestea pot fi folosite si prelucrate
Observatie:
Crearea sau declararea unui obiect este similara cu crearea sau declararea unor
variabile. Declararea unei variabile se face, dupa cum se stie, prin specificarea
identificatorului acesteia, precedat de tipul variabilei iar declararea unui obiect presupune
precizarea identificatorului acestuia, precedat de clasa din care face parte, clasa care in mod
implicit determina proprietatile si metodele obiectului definit.
O clasa in limbajul C++ poate fi reprezentata ca o extindere a conceptului de
structura, care, ca si o structura, descrie un sablon pentru viitoarele declarari de variabile
obiect.
#include<string.h>
#include<stdio.h>
class carte
{
public:
char nume[40];
char autor1[40];
char autor2[40];
int nrpag;
double pret;
void citeste_carte(char *numecarte,char *autorcarte1,char *autorcarte2,int *np,double *p);
void afiseaza_carte();
};
// descrirea functiei de citire carte
void carte::citeste_carte(char *numecarte,char *numeautor1,
char *numeautor2,int *np,double *p)
{
strcpy(nume,numecarte);
strcpy(autor1,numeautor1);
strcpy(autor2,numeautor2);
nrpag=*np;
pret=*p;
}
void carte::afiseaza_carte()
{
cout<<"\n cartea nr."<<i<<":"<<nume<<endl;
cout<<"\n primul autor:"<<autor1<<endl;
cout<<"\n al doilea autor:"<<autor2<<endl;
cout<<"\n nr pagini:"<<nrpag<<endl;
cout<<"\n pretul:"<<pret<<endl;
}
int i=0;
void main()
{
carte carteacitita;
char wnume[40],wautor1[40],wautor2[40];
int wnrpag;
double wpret;
char r='d';
while(r=='d')
{
printf("\n denumirea cartii:");
gets(wnume);
printf("\n primul autor:");
gets(wautor1);
printf("\n al doilea autor:");
gets(wautor2);
cout<<"\n nr. pagini:";
cin>>wnrpag;
cout<<"\n pret:";
cin>>wpret;
carteacitita.citeste_carte(wnume,wautor1,wautor2,&wnrpag,&wpret);
carteacitita.afiseaza_carte();
cout<<"\n continuati?(d/n):";
cin>>r;
}
}
In urma executarii programului anterior s-au obtinut urmatoarele rezultate, care arata
cum se declara o clasa, un obiect al acestei clase si modul in care se apeleaza membrii acestei
clase, prin intermediul unei instante a acestei clase.
denumirea cartii:Trecea o moara pe Siret
primul autor:Mihail Sadoveanu
al doilea autor: -nr. pagini:200
pret:30
cartea nr.0:Trecea o moara pe Siret
primul autor:Mihail Sadoveanu
al doilea autor: -nr pagini:200
pretul:30
continuati?(d/n):d
denumirea cartii:O noapte furtunoasa
primul autor:Ion Luca Caragiale
al doilea autor: -nr. pagini:50
pret:25
continuati?(d/n):n
Problema 18
Daca, in programul de mai sus, textul definirii clasei carte impreuna cu textele
functiilor precizate in clasa, citeste_carte si afiseaza_carte se salveaza ca un fisier header in
directorul include, fie el carti.h, atunci programul de mai sus va arata astfel:
int i;
#include<iostream.h>
#include<string.h>
#include<carti.h>
void main()
{
carte carteacitita;
char wnume[40],wautor1[40],wautor2[40];
int wnrpag;
double wpret;
char r='d';
while(r=='d')
{
printf("\n denumirea cartii:");
gets(wnume);
clsir.scrie(stdout);
do
{
// reafisarea meniului de comenzi
printf("\n ==============================");
printf("\n 1. conversie sir in majuscule");
printf("\n 2. conversie sir in minuscule");
printf("\n 3. adaugare subsir la sirul dat");
printf("\n t. terminare program");
printf("\n ==============================");
printf("\n alegeti o optiune:");
alegere=getchar();getchar();
}
while((alegere!='1')&&(alegere!='2')&&
(alegere!='3')&&(alegere!='t'));
}
printf("\n continuati?(d/n):");
r=getche();
}
printf("\n terminat \n");
}
In urma executarii programului de mai sus, s-au obtinut rezultatele din lista de mai
jos, care pun in evidenta declararea si folosirea membrilor publici si privati, prin intermediul
unei instante a clasei declarate.
dati un sir (max=80 caractere):ana are mere
==============================
1. conversie sir in majuscule
2. conversie sir in minuscule
3. adaugare subsir la sirul dat
t. terminare program
==============================
alegeti o optiune:1
sirul modificat este:ANA ARE MERE
==============================
1. conversie sir in majuscule
2. conversie sir in minuscule
3. adaugare subsir la sirul dat
t. terminare program
==============================
alegeti o optiune:2
sirul modificat este:ana are mere
==============================
1. conversie sir in majuscule
2. conversie sir in minuscule
3. adaugare subsir la sirul dat
t. terminare program
==============================
alegeti o optiune:3
introduceti un sir (max 80): frumoase
terminat
continuati?(d/n):n
In programul de mai sus s-a declarat o clasa numita clasasir, utilizata pentru
declararea obiectelor specifice acesteia (exemplu clasasir tempsir) si are ca membri date si
functii. Se constata ca unii membri sunt publici, marcati cu eticheta public:
functiile copy, scrie, citeste, operator si conversie iar altii sunt privati, nemarcati cu nici o
eticheta sau marcati cu eticheta private: variabila (data) sir de exemplu. Se observa, de
asemenea, ca unele functii sunt descrise in corpul clasei clasasir: copy si operator iar altele
sunt descrise in afara clasei: citeste, scrie si conversie. Membri publici ai unei clase, date sau
functii publice, pot fi accesati din interiorul si exteriorul clasei. De exemplu,
functiile citeste si scrie au fost accesate direct din functia main prin intermediul
obiectului clsir al clasei clasasir : clsir.citestesi respectiv clsir.scrie. Membri privati ai unei
clase nu pot fi accesati decat din interiorul clasei. Membrul privat sir a fost accesat numai din
interiorul clasei de catre functiile membre: copy, citeste si scrieindiferent daca sunt descrise
in interiorul sau in exteriorul clasei.
III. 3. Functii membru ale unei clase
Functiile membru ale unei clase sunt functiile descrise sau declarate in
interiorul unei clase. Deci, descrierea efectiva a functiilor membru ale unei clase se
poate face, fie in interiorul clasei, fie in afara clasei, daca in interiorul clasei s-au
declarat ca prototipuri. Ele pot fi accesate din interiorul clasei si din afara clasei,
prin intermediul obiectelor declarate, daca au fost declarate publice, sau numai
direct din interiorul clasei de catre alte functii membru ale aceleiasi clase, daca au
fost declarate private.
III. 3. 1. Apelarea unei functii membru al unei clase
Apelarea unei functii membru, din interiorul unei clase, se face precizanduse numele acesteia si parametrii efectivi:
nume_functie_membru(parametri_efectivi_de_apel)
ca in problema de mai sus: clasasir(char *s=" ") {copy(s);}
Apelarea unei functii membru, din exteriorul unei clase, se face precizanduse obiectul declarat, numele acesteia si parametri efectivi:
nume_obiect.nume_functie_membru(parametri_efectivi_de_apel)
asa cum s-a precizat mai sus: clsir.citeste, clsir.scrie.
III. 3. 2. Functii friend
Functiile friend sunt functii obisnuite declarate intr-o clasa, precedate de calificativul friend.
friend nume_functie_membru(parametri_formali)
Acest calificativ le permite sa acceseze membrii privati ai unei clase, din exteriorul
acesteia, asa cum este cazul functiei conversie din problema precedenta:
friend void conversie(clasasir &s,char optiune);
Apelarea unei functii friend se face asemanator cu apelarea oricarei functii din C+
+,
ca
de
exemplu,
in
functia main() a
programului
de
mai
sus: conversie(clsir,alegere);
Variabile de tip referinta
O variabila de tip referinta, in definirea unei functii, este precedata de
operatorul adresa &, iar in corpul functiei variabila este referita normal, ca o
variabila de tip structura. De fapt, o variabila de tip referinta este un alias, un
pseudonim, pentru alta variabila, in esenta, un pointer cu urmatoarele precizari:
{
return(sqrt((x-x0)*(x-x0)+(y-y0)*
(y-y0)+(z-z0)*(z-z0)));
}
int poz_x_fata_m0(void)
{
return(x-x0);
}
int poz_y_fata_m0(void)
{
return(y-y0);
}
int poz_z_fata_m0(void)
{
return(z-z0);
}
double poz_m_fata_sfera(void)
{
return(distanta()-raza);
}
};
// initializare datelor statice inainte de
// declararea obiectelor clasei
int clspunct::x0=10;
int clspunct::y0=10;
int clspunct::z0=10;
int clspunct::raza=10;
void main(void)
{
// declararea obiectelor ob1 si ob2
clspunct a;
char r='d';
while(r=='d')
{
cout<<"\n sfera are la inceput raza "
<<a.raza<<" si centrul in M0("
<<a.x0<<','<<a.y0<<','<<a.z0<<")";
cout<<"\n coordonatele unui pct (int x,y,z):";
cin>>a.x>>a.y>>a.z;
cout<<"\n distanta(M0("<<a.x0<<','<<a.y0<<','
<<a.z0<<"),M1("<<a.x<<','<<a.y<<','
<<a.z<<"))="<<a.distanta();
cout<<"\n coordonatel lui M fata de centru("
<<a.poz_x_fata_m0()<<','<<a.poz_y_fata_m0()
<<','<<a.poz_z_fata_m0()<<")";
if(a.poz_m_fata_sfera()>0)
cout<<"\n punctul M("<<a.x<<','<<a.y<<','
<<a.z<<") este exterior sferei";
if(a.poz_m_fata_sfera()<0)
cout<<"\n punctul M("<<a.x<<','<<a.y<<','
<<a.z<<") este interior sferei";
if(a.poz_m_fata_sfera()==0)
cout<<"\n punctul M("<<a.x<<','<<a.y<<','
<<a.z<<") este pe sfera";
// se modifica datele statice
a.x0=1;a.y0=1;a.z0=1;a.raza=10;
cout<<"\n sfera modificata are raza "<<a.raza
<<" si centrul in M0("<<a.x0<<','<<a.y0
<<','<<a.z0<<")";
cout<<"\n distanta(M0("<<a.x0<<','<<a.y0<<','
<<a.z0<<"),M1("<<a.x<<','<<a.y<<','
<<a.z<<"))="<<a.distanta();
cout<<"\n coordonatel lui M fata de centru("
<<a.poz_x_fata_m0()<<','<<a.poz_y_fata_m0()
<<','<<a.poz_z_fata_m0()<<")";
if(a.poz_m_fata_sfera()>0)
cout<<"\n punctul M("<<a.x<<','<<a.y<<','
<<a.z<<") este exterior sferei";
if(a.poz_m_fata_sfera()<0)
cout<<"\n punctul M("<<a.x<<','<<a.y<<','
<<a.z<<") este interior sferei";
if(a.poz_m_fata_sfera()==0)
cout<<"\n punctul M("<<a.x<<','<<a.y<<','
<<a.z<<") este pe sfera";
cout<<"\n continuati?(d/n):";
cin>>r;
}
}
In urma executarii programului de mai sus, s-au obtinut rezultatele din lista
de mai jos, evidentiindu-se declararea si modul de utilizare a membrilor statici
precizati in clasa definita.
sfera are la inceput raza 10 si centrul in M0(10,10,10)
coordonatele unui pct (int x,y,z):20 30 40
distanta(M0(10,10,10),M1(20,30,40))=37.4166
coordonatel lui M fata de centru(10,20,30)
punctul M(20,30,40) este exterior sferei
sfera modificata are raza 10 si centrul in M0(1,1,1)
distanta(M0(1,1,1),M1(20,30,40))=52.1824
coordonatel lui M fata de centru(19,29,39)
punctul M(20,30,40) este exterior sferei
continuati?(d/n):d
sfera are la inceput raza 10 si centrul in M0(1,1,1)
coordonatele unui pct (int x,y,z):1 2 3
distanta(M0(1,1,1),M1(1,2,3))=2.23607
coordonatel lui M fata de centru(0,1,2)
punctul M(1,2,3) este interior sferei
sfera modificata are raza 10 si centrul in M0(1,1,1)
distanta(M0(1,1,1),M1(1,2,3))=2.23607
coordonatel lui M fata de centru(0,1,2)
punctul M(1,2,3) este interior sferei
continuati?(d/n):d
sfera are la inceput raza 10 si centrul in M0(1,1,1)
coordonatele unui pct (int x,y,z):-10 -20 20
distanta(M0(1,1,1),M1(-10,-20,20))=30.3809
coordonatel lui M fata de centru(-11,-21,19)
punctul M(-10,-20,20) este exterior sferei
sfera modificata are raza 10 si centrul in M0(1,1,1)
distanta(M0(1,1,1),M1(-10,-20,20))=30.3809
coordonatel lui M fata de centru(-11,-21,19)
punctul M(-10,-20,20) este exterior sferei
continuati?(d/n):n
Functiile statice nu sunt aplicate unui obiect anume si din acest motiv ele
nu accepta ca parametru implicit pointerul this. Si ca atare, din corpul unei functii
statice nu se pot accesa membrii obiectelor decat prin calificare explicita, utilizand
sageata dreapta (->) sau punctul (.). Pentru declaratia din exemplul de mai sus
descrierea functiei statice se face astfel:
Exemplu:
void clsx::functie(int i,clsx *ptr)
{
..
ptr->b=i; // se atribuie datei b din obiectul ptr al ckasei clsx
b=i; // atribuire incorecta
}
Observatie:
Utilizarea principala a membrilor statici este determinata de necesitatea
memorarii datelor comune tuturor obiectelor create, de aceeasi clasa, cum ar fi:
- pastrarea unor informatii comune tuturor obiectelor unei clase: semafoare,
comutatori.
- inregistrarea numarului obiectelor create asociate aceleiasi clase
- reducerea numarului declaratiilor globale
- validarea accesului la denumirea campurilor de date
III. 5. Pointerul this din C++
Apelarea unei functii membru pozitioneaza un pointer la obiectul de tipul
clasei asociate. In momentul apelului, acest pointer apare ca un argument
suplimentar nevizibil. El poate fi referit, totusi, cu ajutorul cuvantului
cheie this (aici). Utilizarea de baza a cuvantului cheie this este legata de descrierea
functiilor membru care manipuleaza pointeri. Deoarece this este un cuvant cheie
in C++, el nu poate fi declarat explicit iar, in orice functie membru nestatica a unei
clase, pointerul this este declarat implicit ca nume_clasa *this si initializat sa
adreseze spre obiectul pentru care este apelata functia membru.Utilizarea
pointerului this poate fi pusa in evidenta in functia care insereaza o componenta
intr-o lista dublu inlantuita.
Exemplu:
.
class clsinsert
{
clsinsert *anterior;
clsinsert *urmator;
public:
void finsert(clsinsert *);
.
};
void clsinsert::finsert(clsinsert *ptr)
{
scanf("%d",&wcm);
}
while((wcm<1)||(wcm>999));
printf("\n nume student:");
cin.getline(wnume,20,'\n');
do
{
printf("\n nr note(1..15):");
scanf("%d",&wnrn);
}
while((wnrn<1)||(wnrn>15));
for(k=0;k<wnrn;k++)
{
do
{
printf("\n nota(%d)=",k);
scanf("%lf",&wnota[k]);
}
while((wnota[k]<1)||(wnota[k]>10));
}
student[i].citeste_student(wcm,wnume,wnrn,wnota,0);
i++;
printf("\n continuati?(d/n):");
r=getche();
}
printf("\n
mediile studentilor ");
printf("\n =====================================");
printf("\n cod nume si prenume
media ");
printf("\n =====================================");
for(k=0;k<i;k++) student[k].afisaza_student();
printf("\n =====================================\n");
}
Rezultatele executiei programului, de mai sus, sunt prezentate in
continuare, putandu-se urmari cum se declara si se utilizeaza o structura care, pe
langa campurile componente, contine si doua functii membre, cu care se
prelucreaza datele unei structuri date
cod student (1..999):100
nume student:popescu ilie
nr note(1..15):3
nota(0)=2.55
nota(1)=8.45
nota(2)=9.50
continuati?(d/n):d
Problema 22
Aceeasi problema ca cea de mai sus, cu deosebirea ca citire efectiva a
campurilor unei componente a tabloului student se face in functia citeste_student(),
membru al structurii tip_student.
#include<stdio.h>
#include<iostream.h>
#include<iomanip.h>
#include<conio.h>
#include<string.h>
#define nmax 20
struct tip_student
{
int cm;
char nume[20];
int nrn;
double nota[15];
double media;
void citeste_student()
{
int k;
int wcm,wnrn;char wnume[20];
double wnota[15],wmedia;
do
{
printf("\n cod student (1..999):");
scanf("%d",&wcm);
}
while((wcm<1)||(wcm>999));
printf("\n nume student:");
cin.getline(wnume,20,'\n');
do
{
printf("\n nr note(1..15):");
scanf("%d",&wnrn);
}
while((wnrn<1)||(wnrn>15));
for(k=0;k<wnrn;k++)
{
do
{
printf("\n nota(%d)=",k);
scanf("%lf",&wnota[k]);
}
while((wnota[k]<1)||(wnota[k]>10));
}
this->cm=wcm;
strcpy(this->nume,wnume);
this->nrn=wnrn;
this->media=0;
for(k=0;k<wnrn;k++)
{
this->media=this->media+wnota[k];
}
this->media=this->media/this->nrn;
wmedia=this->media;
}
void afisaza_student()
{
printf("\n %5d %-22s %6.2lf",this->cm,this->nume,this->media);
}
}; // sfarsitul definirii structurii tip_student
void main(void)
{
tip_student student[nmax]; char r='d';
int i=0,k;
while((r=='d')&&(i<nmax))
{
student[i].citeste_student();
i++;
printf("\n continuati?(d/n):");
r=getche();
}
printf("\n
mediile studentilor ");
printf("\n =====================================");
printf("\n cod nume si prenume
media ");
printf("\n =====================================");
for(k=0;k<i;k++) student[k].afisaza_student();
printf("\n =====================================\n");
}
III. 6. 2. Uniuni in limbajul C++
In limbajul C++, tipul uniune de date, precizat prin cuvantul cheie union,
se defineste in mod similar cu definirea unei structuri, adica, tot ca si o clasa ai
carei membri sunt considerati in mod implicit public, pana la prima
declaratie private explicita. Ca si la declararea variabilelor de tip structura, in C++,
la declararea unei variabile de tip union nu mai este obligatorie precizarea
cuvantului cheie union. Dupa cum se stie, fata de o structura, tipul union declara
date de acelasi tip sau de tipuri diferite care utilizeaza in comun aceeasi zona de
memorie, dar la momente diferite de timp. Partajarea aceleasi zone de memorie de
catre doua sau mai multe variabile nu se poate realiza cu o structura sau o clasa
obisnuita. Tipul union de date are si cateva restrictii importante cum ar fi:
- nu poate include obiecte care sa contina functii constructor si destructor,
fara
a
se
intelege
ca
tipul union nu
poate
avea
definite
functii constructor si destructor proprii.
- nu poate include membri statici: date si functii statice
- nu poate fi mostenirea altei clase si nu poate servi, ca baza, pentru
definirea, derivarea, altei clase.
Problema 23
Se introduc, pe rand, de la tastatura oricare n (1<=n<=nmax) numere reale
(float) si 2*n numere intregi (int) si care vor folosi in comun aceasi zona de
memorie. Sa se afiseze, pe rand, numerele introduse, cele reale si cele integi,
impreuna cu mediile lor aritmetice, utilzandu-se un tip union adecvat care sa
contina datele care utilizeaza in comun aceeasi zona de memorie precum si
functiile membru de citire, calcul medii si de afisare a datelor si rezultatelor.
#include <stdio.h>
#include <conio.h>
#include<malloc.h>
const int nmax=20;
union tipnumere
{
long int x[nmax];
double y[nmax/2];
void citeste_intregi(long int n)
{
int k;
printf("\n introduceti cele %d de nr. intregi in uniunea u:",n);
for (k=0;k<n;k++)
{
printf("\n x(%d)=",k);
scanf("%d",&this->x[k]);
}
}
void citeste_reale(long int n)
{
int k;
printf("\n introduceti cele %d de numere reale din uniunea u:",n/2);
for (k=0;k<(n/2);k++)
{
printf("\n y(%d)=",k);
scanf("%lf",&this->y[k]);
}
}
void calcul_medie_intregi(int n)
{
int k;
double mint=0;
printf("\n nr intregi si calculul medie in uniune:\n");
/* insumarea numerelor intregi */
for(k=0;k<n;k++)
{
printf("%ld ",this->x[k]);
mint=mint+this->x[k];
}
printf("\n media arit. a celor %d nr. intregi=%1.2lf",n,mint/n);
}
void calcul_medie_reale(int n)
{
int k;
double mfloat=0;
printf("\n nr reale si calculul medie in uniune:\n");
/* insumarea numerelor intregi */
for(k=0;k<(n/2);k++)
{
printf("%1.2lf ",this->y[k]);
mfloat=mfloat+this->y[k];
}
10 20 30 40 50 60
media celor 6 nr. intregi=35.00
nr reale si calculul medie in uniune:
23.45 67.97 -34.56
media arit. a celor 3 nr.reale=18.95
nr reale si media calculate in main:
23.45 67.97 -34.56
media celor 3 nr. reale=18.95
continuati?(d/n):n
Observatie:
Limbajul C++ accepta uniunile anonime, fara specificarea numelui uniunii, ca in
programul de mai jos:
Problema 24
Se considera o uniune anonima, fara nume, de trei date: intreaga, reala si caracter. Sa
se afiseze pe rand toate datele intregi, reale si caracter tastate.
#include<iostream.h>void main(void)
{
union
{
int x;
double y;
char z;
};
char r='d';
while(r=='d')
{
cout<<"\n dati un nr intreg, x=";
cin>>x;
cout<<"\n ati tastat nr intreg "<<x;
cout<<"\n dati un nr real, y=";
cin>>y;
cout<<"\n ati tastat nr real "<<y;
cout<<"\n dati un caracter, z=";
cin>>z;
cout<<"\n ati tastat caracterul "<<z;
cout<<"\n continuati?(d/n):";
cin>>r;
}
}
Problema 25
Se considera trei siruri: primul de numere intregi, al doilea de caractere si al treilea de
numere reale, care utilizeaza in comun aceeasi zona de memorie. Cu ajutorul unei uniuni a
celor trei tipuri de data, sa se citeasca, pe rand, elementele sirurilor, cu ajutorul unei functii
membru (citeste_sir), sa se ordoneze crescator fiecare sir cu o alta functie membru
(ordoneaza_sir) si apoi sa se afiseze sirurile astfel ordonate cu alta functie membru
(afisaza_sir)
#include<iostream.h>
#define nmax1 20
#define nmax2 15
#define nmax3 10
int i;
union tip_siruri
{
int sint[nmax1];
char scar[nmax2];
double sreal[nmax3];
void citeste_sir(int n,char tsir) //functia membru de citire
{
for(i=0;i<n;i++)
{
if(tsir=='i')
{
cout<<"\n sint("<<i<<")=";
cin>>sint[i];
}
if(tsir=='c')
{
cout<<"\n scar("<<i<<")=";
cin>>scar[i];
}
if(tsir=='r')
{
cout<<"\n sreal("<<i<<")=";
cin>>sreal[i];
}
}
}
void afisaza_sir(int n,char tsir) //functia membru de afisare
{
for(i=0;i<n;i++)
{
if(tsir=='i') cout<<sint[i]<<' ';
if(tsir=='c') cout<<scar[i]<<' ';
if(tsir=='r') cout<<sreal[i]<<' ';
}
}
void ordonare_sir(int n,char tsir) //functia membru de ordonare
{
int ok,i,auxi; char auxc;double auxr;
ok=1;
while(ok)
{
ok=0;
for(i=0;i<n-1;i++)
{
if(tsir=='i')
{
if(sint[i]>sint[i+1])
{
auxi=sint[i];sint[i]=sint[i+1];
sint[i+1]=auxi;ok=1;
}
}
if(tsir=='c')
{
if(scar[i]>scar[i+1])
{
auxc=scar[i];scar[i]=scar[i+1];
scar[i+1]=auxc;ok=1;
}
}
if(tsir=='r')
{
if(sreal[i]>sreal[i+1])
{
auxr=sreal[i];sreal[i]=sreal[i+1];
sreal[i+1]=auxr;ok=1;
}
}
}
}
}
};
void main(void)
{
tip_siruri u;
int n;char r='d';
while(r=='d')
{
do
{
cout<<"\n dati nr de intregi de citit(n<"<<nmax1<<")=";
cin>>n;
}
while((n<1)||(n>nmax1));
cout<<"\n se citesc "<<n<<" intregi:\n";
cout<<"===============================";
u.citeste_sir(n,'i');
u.ordonare_sir(n,'i');
cout<<"\n=============================";
cout<<"\n sirul de intregi ordonat:";
u.afisaza_sir(n,'i');
cout<<"\n=============================";
do
{
cout<<"\n dati nr de caractere de citit(n<"<<nmax2<<")=";
cin>>n;
}
while((n<1)||(n>nmax2));
Rezultatele executiei programului, sunt prezentate in continuare, putanduse urmari cum se declara si se utilizeaza o uniune de siruri de date care, pe langa
aceste siruri, contine si functii membre (citeste_sir(), afisaza_sir() si
ordonare_sir()), cu care se prelucreaza datele uniunii, de tip siruri de date, ce
folosesc aceeasi zona de memorie in comun
dati nr de intregi de citit(n<20)=4
se citesc 4 intregi:
===============================
sint(0)=45
sint(1)=-34
sint(2)=78
sint(3)=-90
=============================
sirul de intregi ordonat:-90 -34 45 78
=============================
dati nr de caractere de citit(n<15)=5
se citesc 5 caractere:
=============================
scar(0)=i
scar(1)=y
scar(2)=3
scar(3)=a
scar(4)=f
=============================
sirul de caractere ordonat:3 a f i y
=============================
dati nr de reali de citit(n<10)=4
se citesc 4 reali:
=============================
sreal(0)=32.45
sreal(1)=89.45
sreal(2)=-67.99
sreal(3)=-23.33
=============================
sirul de reali ordonat:-67.99 -23.33 32.45 89.45
=============================
continuati?(d/n):d
dati nr de intregi de citit(n<20)=3
se citesc 3 intregi:
===============================
sint(0)=45
sint(1)=-34
sint(2)=18
=============================
sirul de intregi ordonat:-34 18 45
=============================
dati nr de caractere de citit(n<15)=4
se citesc 4 caractere:
=============================
scar(0)=k
scar(1)=a
scar(2)=w
scar(3)=h
=============================
sirul de caractere ordonat:a h k w
=============================
dati nr de reali de citit(n<10)=3
se citesc 3 reali:
=============================
sreal(0)=-34.78
sreal(1)=67.33
sreal(2)=-97.5
=============================
sirul de reali ordonat:-97.5 -34.78 67.33
=============================
continuati?(d/n):n
pretul materialului:22.55
cantitatea din stoc:200
Informatii de nomenclator de materiale:
=========================================
codul materialui: 20000
denumirea materialului: fier*beton*fi16
unitatea de masura: kg
====================================
dobanda_cumulata=suma_cumulata-dobanda::s0;
}
};
// descrierea functiei afiseaza_rezultat in afara clasei
void dobanda::afiseaza_rezultat(int k)
{
cout<<"\n "<<setw(4)<<k<<" ";
cout<<" "<<setw(13)<<setiosflags(ios::fixed);
cout<<setprecision(2)<<dobanda::suma_cumulata;
cout<<" "<<setw(13)<<setiosflags(ios::fixed);
cout<<setprecision(2)<<dobanda::dobanda_cumulata;
};
// descrierea functiei afiseaza_linie in afara clasei
void dobanda::afiseaza_linie(int m)
{
calcul_dobanda(m);
afiseaza_rezultat(m);
}
// descrierea functiei principale main
void main()
{
int wn; double wp, ws0;
char r='d',tip_depozit;
while(r=='d')
{
cout<<"\n tip depozit implicit(s0=100000,p=10%,n=10 ani)?(d/n):";
cin>>tip_depozit;
if (tip_depozit=='d')
{
cout<<"\n tip depozit implicit(s0=100000,p=10%,n=10 ani)";
//apelarea functiei constructor cu parametri impliciti
dobanda implicit;
}
else
{
// citirea parametrilor efectivi expliciti
cout<<"\n tip depozit explicit(s0<>100000,p<>10%,n<>10 ani)";
do
{
cout<<"\n suma initiala depusa (100000<=s0<=1000000):";
cin>>ws0;
}
while((ws0<100000)||(ws0>1000000));
do
{
cout<<"\n dobanda anuala % (10<=p<=100):";
cin>>wp;
}
while((wp<10)||(wp>100));
do
{
cout<<"\n perioada depozitului (5<=n<=20):";
cin>>wn;
}
while((wn<5)||(wn>20));
//apelarea functiei constructor cu parametri expliciti
dobanda explicita(ws0,wp,wn);
}
cout<<"\n continuati?(d/n):";
cin>>r;
}
}
In urma executarii acestui program, s-au obtinut urmatoarele rezultate, care scot in
evidenta: declararea prototipurilor tuturor functiilor, in corpul clasei, inclusiv a functiei
constructor cu parametri formali impliciti, descriera tuturor functiilor in afara clasei, apelarea
functiei constructor cu si fara parametri efectivi expliciti.
tip depozit implicit(s0=100000,p=10%,n=10 ani)?(d/n):d
tip depozit implicit(s0=100000,p=10%,n=10 ani)
suma depusa=100000 dobanda=10% perioada=10 ani
=====================================
anul suma cumulata dobanda cumulata
=====================================
1
110000.00
10000.00
2
121000.00
21000.00
3
133100.00
33100.00
4
146410.00
46410.00
5
161051.00
61051.00
6
177156.10
77156.10
7
194871.71
94871.71
8
214358.88
114358.88
9
235794.77
135794.77
10
259374.25
159374.25
=====================================
continuati?(d/n):d
tip depozit implicit(s0=100000,p=10%,n=10 ani)?(d/n):n
tip depozit explicit(s0<>100000,p<>10%,n<>10 ani)
suma initiala depusa (100000<=s0<=1000000):1000000
dobanda anuala % (10<=p<=100):100
perioada depozitului (5<=n<=20):8
suma depusa=1000000.00 dobanda=100.00% perioada=8 ani
=====================================
anul suma cumulata dobanda cumulata
=====================================
1
2000000.00
1000000.00
2
4000000.00
3000000.00
3
8000000.00
7000000.00
4
16000000.00
15000000.00
5
32000000.00
31000000.00
6
64000000.00
63000000.00
7 128000000.00
127000000.00
8 256000000.00
255000000.00
=====================================
continuati?(d/n):d
tip depozit implicit(s0=100000,p=10%,n=10 ani)?(d/n):d
tip depozit implicit(s0=100000,p=10%,n=10 ani)
suma depusa=100000.00 dobanda=10.00% perioada=10 ani
=====================================
anul suma cumulata dobanda cumulata
=====================================
1
110000.00
10000.00
2
121000.00
21000.00
3
133100.00
33100.00
4
146410.00
46410.00
5
161051.00
61051.00
6
177156.10
77156.10
7
194871.71
94871.71
8
214358.88
114358.88
9
235794.77
135794.77
10
259374.25
159374.25
=====================================
continuati?(d/n):n
.
nume_functie_constructor::nume_tabloun = new char[numar_octetin];
if ((nume_functie_constructor::nume_tablou1 &&
(nume_functie_constructor::nume_tablou2 &&
.
(nume_functie_constructor::nume_tabloun ) == 0)
{
nume_functie_constructor::pointer_tabloun =
(tip_componentan*)malloc(n*sizeof(tip_componentan));
iar verificarea alocarii necesarului de memorie se poate face asemanator ca la tablourile de
siruri, prezentata mai sus.
if((!nume_functie_constructor::pointer_tablou1) ||
(!nume_functie_constructor::pointer_tablou2) ||
(!nume_functie_constructor::pointer_tabloun) == 0)
{
cout<<"\n alocarea dinamica a tablourilor, nereusita in functia constructor";
exit(1);
}
Problema 28
Se da o matrice dreptunghiulara de n linii si m coloane, unde m reprezinta numarul
de tipuri de produse fabricate intr-o uzina, iar n numarul de tipuri de materiale folosite la
fabricarea acestora. Un element al matricei a[i,j] reprezinta cantitatea, in aceeasi unitate de
masura, din materialul i consumat pentru produsul j. Un vector de m componente contine
numarul de produse fabricate din fiecare tip. Se cere sa se determine un vector de n
componente care sa contina cantitatile totale, din fiecare tip de material, consumate pentru
realizarea fabricatiei celor m tipuri de produse. Cunoscandu-se, apoi, intr-un vector, costurile
unitare de materiale pe fiecare tip de material, sa se calculuze valoarea fiecarui tip de
material consumat si valoarea totala a tuturor materialelor consumate. Pentru rezolvarea
acestei aplicatii se va folosi o clasa adecvat definita care contine o functie constructor ce va
initializa datele membre de tip pointeri la tablouri si va calcula si afisa cele cerute in
problema. Se vor folosi parametri formali si efectivi de tip pointer, pentru transmiterea lor
intre functia principala si functia constructor, utilizanduse, din acest motiv, alocarea dinamica
de memorie si verificarea alocarii memoriei dinamice necesara tablourilor.
#include<iostream.h>
#include<iomanip.h>
#include<malloc.h>
#include<stdlib.h>
#define nmax 20
#define mmax 20
int i,j;
// definirea clasei consunuri
class consumuri
{
public:
consumuri::consumuri(int n, int m, double *pc, double *pp, double *pv);
// declararea datelor membru publice
int n;
int m;
double *pc; //pointer la matricea consumurilor specifice
double *pp; //pointer la vectorul produselor fabricate
double *pv; //pointer la vectorul costurilor unitare ale materialelor
private:
double *pmateriale; //pointer la vectorul materialelor consumate
double *pcosturi; //pointer la vectorul costurilor materialelor
double costotal;
//declararea prototipurilor functiilor membru private
// prototipul functiei de afisare a consumurilor
//specifice de materiale pe produse
void afiseaza_matrice_consumuri(int n, int m);
// prototipul functiei de calcul a consumurilor de materiale
void calcul_consumuri(int n, int m);
// prototipul functiei de calcul ale costurilor de materiale
void calcul_costuri_materiale(int n);
// prototipul functiei de afiseare vector produse
void afiseaza_vector_produse(int m);
// prototipul functiei de afiseare vector consumuri de materiale
void afiseaza_vector_consumuri(int n);
// prototipul functiei de afiseare vector consturi unitare pe materiale
void afiseaza_vector_costuri_unitare(int n);
// prototipul functiei de afiseare vector consturi totale pe materiale
void afiseaza_vector_costuri_materiale(int n);
};
// descrierea functiei constructor consumuri in afara clasei
consumuri::consumuri(int n, int m, double *pc, double *pp, double *pv)
{
cout<<"\n functia constructor consumuri";
// alocarea dinamica de memorie pentru tablourile aplicatiei
consumuri::pc=(double*)malloc(nmax*mmax);
consumuri::pp=(double*)malloc(mmax);
consumuri::pv=(double*)malloc(nmax);
consumuri::pmateriale=(double*)malloc(nmax);
consumuri::pcosturi=(double*)malloc(mmax);
//verificarea necesarului de memorie
for(i=0;i<n;i++)
for(j=0;j<m;j++) consumuri::pc[i*m+j]=pc[i*m+j];
// initializarea vectorului produselor fabricate
for(i=0;i<m;i++) consumuri::pp[i]=pp[i];
// initializarea vectorului costurilor unitare ale materialelor folosite
for(i=0;i<n;i++) consumuri::pv[i]=pv[i];
cout<<"\n matricea consumurilor de materiale pe produse";
cout<<"\n================================\n";
afiseaza_matrice_consumuri(n,m);
cout<<"\n=================================";
cout<<"\n
vectorul produselor fabricate";
cout<<"\n ================================\n";
afiseaza_vector_produse(m);
cout<<"\n ================================\n";
cout<<"\n vectorul costurilor unitare pe materiale\n";
cout<<"\n =================================";
afiseaza_vector_costuri_unitare(n);
cout<<"\n =================================";
calcul_consumuri(n,m);
cout<<"\n
vectorul materialelor consumate";
cout<<"\n ================================\n";
afiseaza_vector_consumuri(n);
cout<<"\n =================================";
calcul_costuri_materiale(n);
cout<<"\n
vectorul costurilor totale pe materiale";
cout<<"\n =================================";
afiseaza_vector_costuri_materiale(n);
cout<<"\n =================================";
};
// descrierea functiei calcul_consumuri
// in afara clasei cu ajutorul pointerilor
void consumuri::calcul_consumuri(int n,int m)
{
for (i=0;i<n;i++)
{
consumuri::pmateriale[i]=0;
for (j=0;j<m;j++)
{
consumuri::pmateriale[i]=consumuri::pmateriale[i]+
consumuri::pc[i*m+j] * consumuri::pp[j];
}
}
}
// descrierea functiei calcul_costuri_materiale
//in afara clasei cu ajutorul pointerilor
void consumuri::calcul_costuri_materiale(int n)
{
consumuri::costotal=0;
for (i=0;i<n;i++)
{
consumuri::pcosturi[i]=consumuri::pmateriale[i] * consumuri::pv[i];
consumuri::costotal= consumuri::costotal + consumuri::pcosturi[i];
}
}
// descrierea functiei afiseaza_matrice_consumuri
//in afara clasei cu ajutorul pointerilor
void consumuri::afiseaza_matrice_consumuri(int n, int m)
{
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
cout<<" "<<setw(7)<<setiosflags(ios::fixed);
cout<<setprecision(3)<<consumuri::pc[i*m+j];
}
cout<<"\n";
}
}
// descrierea functiei afiseaza_vector_produse
// in afara clasei cu ajutorul pointerilor
void consumuri::afiseaza_vector_produse(int m)
{
cout<<"\n";
for(i=0;i<m;i++)
{
cout<<" "<<setw(7)<<setiosflags(ios::fixed);
cout<<setprecision(2)<<consumuri::pp[i];
}
}
// descrierea functiei afiseaza_vector_consumuri
// in afara clasei cu ajutorul pointerilor
void consumuri::afiseaza_vector_consumuri(int n)
{
cout<<"\n";
for(i=0;i<n;i++)
{
cout<<" "<<setw(7)<<setiosflags(ios::fixed);
cout<<setprecision(2)<<consumuri::pmateriale[i];
}
}
// descrierea functiei afiseaza_vector_consturi_unitare
// in afara clasei cu ajutorul pointerilor
void consumuri::afiseaza_vector_costuri_unitare(int n)
{
cout<<"\n";
for(i=0;i<n;i++)
{
cout<<" "<<setw(7)<<setiosflags(ios::fixed);
cout<<setprecision(2)<<consumuri::pv[i];
}
}
// descrierea functiei afiseaza_vector_costuri_materiale
// in afara clasei cu ajutorul pointerilor
void consumuri::afiseaza_vector_costuri_materiale(int n)
{
cout<<"\n";
for(i=0;i<n;i++)
{
cout<<" "<<setw(7)<<setiosflags(ios::fixed);
cout<<setprecision(2)<<consumuri::pcosturi[i];
}
cout<<"\n valoare totala costuri materiale="<<consumuri::costotal;
}
// descrierea functiei principale main()
void main()
{
int n,m;
// declararea pointerilor la tablourile aplivatiei
double *ptrc,*ptrp,*ptrv;
char r='d';
// alocarea memoriei pentru tablourile date in aplicatie
ptrc=(double*)malloc(nmax*mmax);
ptrp=(double*)malloc(mmax);
ptrv=(double*)malloc(nmax);
// verificarea alocarii memoriei pentru tablurile date in aplicatie
if((!ptrc)||(!ptrp)||(!ptrv))
{
cout<<"\n alocarea tablourilor nereusita in functia principala";
exit(1);
}
while(r=='d')
{
do
{
cout<<"\n numarul de produse fabricate,m(1<=m<=20):";
cin>>m;
}
while((m<1)||(m>20));
do
{
cout<<"\n numarul de materiale folosite,n(1<=n<=20):";
cin>>n;
}
while((n<1)||(n>20));
//citirea matricii consumurilor specifice de materiale pe produs
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
cout<<"\n materialul "<<i<<" din produsul "<<j<<" =";
cin>>ptrc[i*m+j];
}
cout<<"\n matricea consumurilor:\n";
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
cout<<ptrc[i*m+j]<<" ";
}
cout<<"\n";
}
for(i=0;i<m;i++)
{
cout<<"\n numarul de bucati fabricate din produsul "<<i<<" =";
cin>>ptrp[i];
}
for(i=0;i<n;i++)
{
cout<<"\n costul unitar al materialului "<<i<<" =";
cin>>ptrv[i];
}
//apelarea functiei constructor, consumuri, cu parametri expliciti
consumuri functie_consumuri(n,m,ptrc,ptrp,ptrv);
cout<<"\n continuati?(d/n):";
cin>>r;
}
}
Rezultatele executiei programului sunt afisate in continuare, putandu-se usor observa,
modul in care, unei functii constructor, i se transmit parametri efectivi de tip pointeri la
tablouri, alocarea dinamica de memorie pentru tablourile pointate ale functiei principale
main, cat si pentru datele membre, de tip pointeri la tablouri, ale clasei corespunzatoare si
verificarea alocarii memoriei pentru tablourile aplicatiei.
numarul de produse fabricate,m(1<=m<=20):3
numarul de materiale folosite,n(1<=n<=20):2
materialul 0 din produsul 0 =1
materialul 0 din produsul 1 =2
materialul 0 din produsul 2 =3
materialul 1 din produsul 0 =4
materialul 1 din produsul 1 =5
materialul 1 din produsul 2 =6
matricea consumurilor:
123
456
numarul de bucati fabricate din produsul 0 =1
numarul de bucati fabricate din produsul 1 =2
numarul de bucati fabricate din produsul 2 =3
costul unitar al materialului 0 =1
costul unitar al materialului 1 =2
functia constructor consumuri
matricea consumurilor de materiale pe produse
=============================================
1.000 2.000 3.000
4.000 5.000 6.000
==============================================
vectorul produselor fabricate
=============================================
1.00 2.00 3.00
=============================================
vectorul costurilor unitare pe material
=============================================
1.00 2.00
==============================================
vectorul materialelor consumate
=============================================
14.00 32.00
==============================================
vectorul costurilor totale pe materiale
=============================================
14.00 64.00
valoare totala costuri materiale=78.00
==============================================
continuati?(d/n):d
numarul de produse fabricate,m(1<=m<=20):2
numarul de materiale folosite,n(1<=n<=20):3
materialul 0 din produsul 0 =6
materialul 0 din produsul 1 =5
materialul 1 din produsul 0 =4
materialul 1 din produsul 1 =3
materialul 2 din produsul 0 =2
materialul 2 din produsul 1 =1
matricea consumurilor:
6.00 5.00
4.00 3.00
2.00 1.00
numarul de bucati fabricate din produsul 0 =1
numarul de bucati fabricate din produsul 1 =2
costul unitar al materialului 0 =1
costul unitar al materialului 1 =2
costul unitar al materialului 2 =3
functia constructor consumuri
matricea consumurilor de materiale pe produse
=============================================
6.000 5.000
4.000 3.000
2.000 1.000
==============================================
vectorul produselor fabricate
=============================================
1.00 2.00
=============================================
cost_venit (int n, int *p, double cf, double cp, double pv);
// supraincarcarea functiei constructor prin declararea
// celei de-a doua functie constructor
cost_venit(void);
// declararea datelor membru publice
int n; // numarul de componente ale vectorului produse
int *p; // pointer la vectorul cu cantitatile de produse de fabricat
double cf; // cheltuielile fixe de fabricatie a produselor
double cp; // cheltuielile variabile de fabricatie pe produs
double pv; // pretul unitar de vanzare a produsului private:
private:
// pointer la vectorul costurilor totale
// pe cantitati variabile de productie
double *ct;
//pointer la vectorul veniturilor pe cantitati variabile de produse
double *vt;
int produs_critic;
int maxim_produse; // numarul maxim de produse propuse ptr fabricare
double cost_critic; // costul total critic
double venit_critic;// venitul total critic
// declararea prototipurilor functiilor membru private
// prototipul functiei de ordonare vector produse
void ordonare_vector_produse(int n);
void determinare_max_produse(int n);
// prototipul functiei de afisare a cantitatilor
// produselor de fabricat
void afiseaza_vector_produse(int n);
// prototipul functiei de afisare a datelor: cf,cp,pv
// ale produselor de fabricat
void afiseaza_date_produse(void);
// prototipul functiei de calcul al costurilor totale
void calcul_costuri_produse(int n);
// prototipul functiei de calcul ale veniturilor din vanzari
void calcul_venituri_produse(int n);
// prototipul functiei de afiseare vector costuri
void afiseaza_vector_costuri(int n);
// prototipul functiei de afiseare vector venituri
void afiseaza_vector_venituri(int n);
// prototipul functiei de afiseare vector profit
void afiseaza_vector_profit(int n);
// prototipul functiei de calcul al punctului critic
void calcul_punct_critic(int n);
// prototipul functiei de afiseare a punctului critic
void afiseaza_punct_critic();
};
// descrierea primei functii constructor, de baza.
// cost_venit in afara clasei
cost_venit::cost_venit (int n, int *p, double cf, double cp, double pv)
{
cout<<"\n functia constructor cost_venit";
cost_venit::cost_venit(void)
{
cerr<<"\n lista parametrilor efectivi eronata";
//exit(1);
}
// descrierea functiei calcul_costuri_produse
//in afara clasei cu ajutorul pointerilor
void cost_venit::ordonare_vector_produse(int n)
{
int ok,paux;
ok=1;
while(ok)
{
ok=0;
for(i=0;i<n-1;i++)
{
if(p[i]>p[i+1])
{
paux=cost_venit::p[i]; cost_venit::p[i]=p[i+1];
cost_venit::p[i+1]=paux; ok=1;
}
}
}
}
void cost_venit::determinare_max_produse(int n)
{
cost_venit::maxim_produse=cost_venit::p[0];
for(i=0;i<n;i++)
if(cost_venit::p[i]>cost_venit::maxim_produse)
cost_venit::maxim_produse=cost_venit::p[i];
cout<<"\n nr maxim de produse de fabricat:";
cout<<cost_venit::maxim_produse;
}
void cost_venit::calcul_costuri_produse(int n)
{
for (i=0;i<n;i++)
cost_venit::ct[i]=cost_venit::cf+cost_venit::cp * cost_venit::p[i];
}
// descrierea functiei calcul_venituri_produse
//in afara clasei cu ajutorul pointerilor
void cost_venit::calcul_venituri_produse(int n)
{
for (i=0;i<n;i++)
cost_venit::vt[i]=cost_venit::pv*cost_venit::p[i];
}
// descrierea functiei afiseaza_vector_produse
// in afara clasei cu ajutorul pointerilor
void cost_venit::afiseaza_vector_produse(int n)
{
cout<<"\n";
for(i=0;i<n;i++)
{
cout<<" "<<setw(7)<<setiosflags(ios::fixed);
cout<<setprecision(2)<<cost_venit::p[i];
}
}
// descrierea functiei afiseaza_vector_costuri
//in afara clasei cu ajutorul pointerilor
void cost_venit::afiseaza_vector_costuri(int n)
{
for(i=0;i<n;i++)
{
cout<<" "<<setw(7)<<setiosflags(ios::fixed);
cout<<setprecision(3)<<cost_venit::ct[i];
}
}
// descrierea functiei afiseaza_vector_profit
//in afara clasei cu ajutorul pointerilor
void cost_venit::afiseaza_vector_profit(int n)
{
for(i=0;i<n;i++)
{
cout<<" "<<setw(7)<<setiosflags(ios::fixed);
cout<<setprecision(3)<<cost_venit::vt[i]-cost_venit::ct[i]<<" ";
}
}
// descrierea functiei afiseaza_vector_venituri
//in afara clasei cu ajutorul pointerilor
void cost_venit::afiseaza_vector_venituri(int n)
{
for(i=0;i<n;i++)
{
cout<<" "<<setw(7)<<setiosflags(ios::fixed);
cout<<setprecision(3)<<cost_venit::vt[i];
}
}
// descrierea functiei calcul_punct_critic
//in afara clasei cu ajutorul pointerilor
void cost_venit::calcul_punct_critic(int n)
{
int ok=0;double ct,vt;
for(i=0;i<cost_venit::maxim_produse;i++)
{
ct=cost_venit::cf+cost_venit::cp * i;
vt=cost_venit::pv * i;
if (vt<ct)
continue;
else
{
ok=1;
cost_venit::cost_critic=ct;
cost_venit::venit_critic=vt;
cost_venit::produs_critic=i;
break;
}
}
if(!ok)
{
cout<<"\n nu exista punct critic";
cout<<"\n la structura aleasa fabrica inregistreaza pierderi";
}
else
{
cout<<"\n afisarea punctului critic ";
cout<<"\n =================================\n";
afiseaza_punct_critic();
cout<<"\n =================================\n";
}
}
// descrierea functiei afiseaza_punct_critic
//in afara clasei cu ajutorul pointerilor
void cost_venit::afiseaza_punct_critic()
{
cout<<"\n punctul critic este atunci cand:\n";
cout<<"\n nr produse ="<<cost_venit::produs_critic;
cout<<"\n costurile totale ="<<cost_venit::cost_critic;
cout<<"\n veniturile totale ="<<cost_venit::venit_critic;
}
void cost_venit::afiseaza_date_produse()
{
cout<<"\n cheltuielile fixe ale fabricii:"<<cost_venit::cf;
cout<<"\n costul de productie pe produs :"<<cost_venit::cp;
cout<<"\n pretul de vanzare al produsului:"<<cost_venit::pv;
}
void main()
{
int n;
// declararea pointerului la vectorul produse al aplicatiei,
// a cheltuielilor fixe, variabile pe produs si a pretului de vanzare
int *ptrp; double cf,cp,pv;
char r='d';
// alocarea memoriei pentru tabloul produse
ptrp=(int*)malloc(nmax);
// verificarea alocarii memoriei pentru tablul de produse
if(!ptrp)
{
cout<<"\n alocarea vectorului de produse nereusita in functia principala";
exit(1);
}
while(r=='d')
{
do
{
cout<<"\n numarul de variante de fabricate,n(1<=n<=20):";
cin>>n;
}
while((n<1)||(n>20));
do
{
cout<<"\n cheltuielile fixe ale fabricii(10000<<cf<<1000000):";
cin>>cf;
}
while((cf<10000)||(cf>1000000));
do
{
cout<<"\n costurile unitare de productie (10<<cp<<100):";
cin>>cp;
}
while((cp<10)||(cp>100));
do
{
cout<<"\n preturile unitare de vanzare (100<<cp<<300):";
cin>>pv;
}
while((pv<100)||(pv>300));
//citirea vectorului cu cantitatile posibile de fabricat
for(i=0;i<n;i++)
{
cout<<"\n cantitatea de fabricat din varianta "<<i<<" =";
cin>>ptrp[i];
}
cout<<"\n variantele cantitatile de fabricat:\n";
for(i=0;i<n;i++) cout<<ptrp[i]<<" ";
//apelarea functiei constructor, consumuri, cu parametri expliciti
cost_venit f_cost_venit(n,ptrp,cf,cp,pv);
// apelarea fara parametri a functiei constructor supraincarcata
cost_venit f_cost_venit_vida;
cout<<"\n continuati?(d/n):";
cin>>r;
}
}
In urma executarii acestui program se obtin rezultatele afisate mai jos, care ilustreaza
modul in care se realizeaza supraincarcarea functiei constructor, alocarea dinamica de
memorie pentru vectorii folositi precum si verificarea alocarii memoriei necesare acestora.
Apelarea functiei constructor cu parametri efectivi valizi, determina initializarea datelor
membre, obtinerea si afisarea rezultatelor, iar apelarea eronata a functiei constructor, in cazul
de fata fara specificarea parametrilor efectivi, antreneaza executarea celei de-a doua functii
constructor, care va afisa mesajul de eroare corespunzator "lista parametrilor efectivi
eronata".
int i;
struct tipfact
{
unsigned int cod;
char denumire[20];
char umas[2];
double pret;
double cant;
double valoare;
double tva;
};
class facturare
{
public:
// void factura_citita (struct tipfact f,int i)
void f_factura (struct tipfact f,int i)
{
facturare::factura[i]=f;
}
struct tipfact factura[20];
//void factura_ordonare (int n)
void f_factura (int n) //a doua functie cu acelasi nume
{
int ok; struct tipfact aux;
ok=1;
while (ok)
{
ok=0;
for(i=0;i<n-1;i++)
if(facturare::factura[i].cod>facturare::factura[i+1].cod)
{
aux=facturare::factura[i];
facturare::factura[i]=facturare::factura[i+1];
facturare::factura[i+1]=aux;
ok=1;
}
}
}
void calculeaza_factura(int n)
{
for(i=0;i<n;i++)
{
facturare::factura[i].valoare=facturare::factura[i].pret*facturare::factura[i].cant;
facturare::factura[i].tva=0.19*facturare::factura[i].valoare;
}
}
void afiseaza_factura(int n)
{
for(i=0;i<n;i++)
{
cout<<"\n";
cout<<setw(5)<<setiosflags(ios::right)<<facturare::factura[i].cod;
cout<<setw(12)<<setiosflags(ios::left)<<facturare::factura[i].denumire;
cout<<setw(3)<<setiosflags(ios::right)<<facturare::factura[i].umas;
cout<<setw(10)<<setprecision(2)<<setiosflags(ios::fixed);
cout<<setiosflags(ios::right)<<facturare::factura[i].pret;
cout<<setw(10)<<setprecision(2)<<setiosflags(ios::fixed);
cout<<setiosflags(ios::right)<<facturare::factura[i].cant;
cout<<setw(10)<<setprecision(2)<<setiosflags(ios::fixed);
cout<<setiosflags(ios::right)<<facturare::factura[i].valoare;
cout<<setw(10)<<setprecision(2)<<setiosflags(ios::fixed);
cout<<setiosflags(ios::right)<<facturare::factura[i].tva;
}
}
};
void main(void)
{
int n; struct tipfact f;char r='d';
while(r=='d')
{
facturare obfactura;
do
{
cout<<"\n numarul de pozitii din factura (1<=n<=20):";
cin>>n;
}
while((n<1)||(n>20));
for(i=0;i<n;i++)
{
do
{
cout<<"\n cod material "<<i<<" (1000-9999):";
cin>>f.cod;
}
while((f.cod<1000)||(f.cod>9999));
cout<<"\n denumire material "<<i<<":";
cin>>f.denumire;
cout<<"\n unitate de masura (bc,kg,mp,ml,mc) "<<i<<":";
cin>>f.umas;
cout<<"\n cod pret "<<i<<":";
cin>>f.pret;
cout<<"\n cantitate material "<<i<<":";
cin>>f.cant;
//obfactura.factura_citita(f,i);
// se aleleaza functia pentru inregistrarea unui rand al facturii
obfactura.f_factura(f,i);
}
// obfactura.factura_ordonare(n);
// se aleleaza functia pentru ordonarea dupa coduri a produselor facturii
obfactura.f_factura(n);
cout<<"\n
factura furnizor
";
cout<<"\n ==========================================";
cout<<"\n cod denumire umas pret cant valoare tva ";
cout<<"\n =========================================\n";
// se apeleaza functia de calcul a facturii
obfactura.calculeaza_factura(n);
// se apeleaza functia de afisare a facturii
obfactura.afiseaza_factura(n);
cout<<"\n ==========================================";
cout<<"\n continuati facturarea?(d/n):";
cin>>r;
}
}
In urma executarii acestui program sau obtinut rezultatele afisate mai jos, care pun in
evidenta elementele de calcul ale unei facturi, cat, mai ales, modul de supraincarcare si
utilizare a unor functii membre, inlaturandu-se ambiguitatile legate de folosirea acelorasi
identificatori, prin utilizarea de parametri efectivi de apel diferiti ca numar sau ca tip.
numarul de pozitii din factura (1<=n<=20):2
cod material 0 (1000-9999):500
denumire material 0:var
unitate de masura (bc,kg,mp,ml,mc) 0:kg
pret art 0:0.85
cantitate material 0:255.00
cod material 1 (1000-9999):300
denumire material 1:ciment
unitate de masura (bc,kg,mp,ml,mc) 1:kg
pret art 1:0.55
cantitate material 1:375.85
factura furnizor
====================================================
cod denumire umas pret cant valoare tva
====================================
300 ciment kg 0.85 255.00 216.75 41.18
500 var
kg 0.55 375.85 206.72 39.28
====================================
continuati facturarea?(d/n):d
numarul de pozitii din factura (1<=n<=20):
Observatii:
- functia destructor trebuie sa aiba acelasi nume ca functia constructor
asociata, preccedat in mod definitoriu de caracterul tilda(~);
- functia destructor nu accepta parametri formali si, ca si functia constructor, nu poate
returna nicio valoare;
- utilitatea evidenta a functiilor destructor se face imperios simtita, mai ales, atunci
cand clasele aloca memorie dinamica unor date membre, cum ar fi matricele, structurile si
alte tipuri complexe de date. Prin functiile destructor se poate elibera memoria alocata pe
parcursul executarii programului, unor date membre;
- prin functiile destructor se pot efectua multe din operatiile specifice listelor simplu si
dublu inlantuite, cum arfi: stergerea sau adaugarea, unuor elemente in lizta;
- functiile destructor nu trebuie apelate si executate inaintea incheierii ciclului de
existenta a instantei obiect respective, ci numai cand se asigura faptul ca instanta obiect
urmeaza efectiv sa fie distrusa.
Problema 31
Se considera o echpa de muncitori (max=20) cu structura: cod matricol (intre 1000 si 9999),
nume, prenume, salariu brut, somaj, CAS (Contributia pentru Asigurari Sociale),
CASS (Contributia pentru Asigurari Sociale de Sanatate), baza de impozitare, impozitul pe
salariu, retineri si rest de plata. Prin intermediul unei clase, in care a fost definita o functie
constructor careia i se transmit parametri efectivi: cod matricol, nume, prenume, salariu brut
si retinerile, sa se calculeze: contributia de somaj, CAS, CASS, baza de impozitare,
impozitul, si restul de plata pentru toti muncitorii din echipa, condusi de seful de achipa aflat
in capul listei, pentru seful de sectie si inginerul sef. Concomitent cu functia constructor
{
cout<<"\n s-a distrus instanta inginerului sef ";
cout<<statplata[0].nume<<" "<<statplata[0].prenume;
}
};
// declararea vectorului cu structurile angajatilor
struct tipangajat statplata[nmax];
char tm;
// descrierea functiei de calcul al salariilor
void calculeaza_statplata(int n)
{
for(i=0;i<n;i++)
{
salarii::statplata[i].somaj=salarii::statplata[i].brut*psomaj/100;
salarii::statplata[i].cas=salarii::statplata[i].brut*pcas/100;
salarii::statplata[i].cass=salarii::statplata[i].brut*pcass/100;
salarii::statplata[i].bazaimpozit=salarii::statplata[i].brut salarii::statplata[i].somaj-salarii::statplata[i].cas-salarii::statplata[i].cass;
salarii::statplata[i].impozit=salarii::statplata[i].bazaimpozit*0.16;
salarii::statplata[i].restplata=salarii::statplata[i].bazaimpozit salarii::statplata[i].impozit-salarii::statplata[i].retineri;
}
};
// descrierea functiei de afisare stat de plata
void afiseaza_statplata(int n)
{
for(i=0;i<n;i++)
{
cout<<"\n";
cout<<"\n matricol:"<<salarii::statplata[i].matricol;
cout<<"\n nume:"<<salarii::statplata[i].nume;
cout<<"\n prenume:"<<salarii::statplata[i].prenume;
cout<<"\n salariu brut:"<<setprecision(2)<<setiosflags(ios::fixed);
cout<<salarii::statplata[i].brut;
cout<<"\n somaj:"<<setprecision(2)<<setiosflags(ios::fixed);
cout<<salarii::statplata[i].somaj;
cout<<"\n CAS:"<<setprecision(2)<<setiosflags(ios::fixed);
cout<<salarii::statplata[i].cas;
cout<<"\n CASS:"<<setprecision(2)<<setiosflags(ios::fixed);
cout<<salarii::statplata[i].cass;
cout<<"\n impozit:"<<setprecision(2)<<setiosflags(ios::fixed);
cout<<salarii::statplata[i].impozit;
cout<<"\n retineri:"<<setprecision(2)<<setiosflags(ios::fixed);
cout<<salarii::statplata[i].retineri;
cout<<"\n rest plata:"<<setprecision(2)<<setiosflags(ios::fixed);
cout<<salarii::statplata[i].restplata;
}
};
};
void main(void)
{
// declararea vectorilor de structuri pentru
// angajati, sef de sectie si inginer sef
struct tipangajat p[nmax],psefsectie[1],pingsef[1];
char r='d';int n;
while(r=='d')
{
do
{
cout<<"\n numarul de angajati (1<=n<="<<nmax<<"):";
cin>>n;
}
while ((n<1)||(n>nmax));
// citirea datelor unui angajat
for(i=0;i<n;i++)
{
cout<<"\n cod matricol "<<i<<" (1000-9999):";
cin>>p[i].matricol;
cout<<"\n nume :";
cin>>p[i].nume;
cout<<"\n prenume :";
cin>>p[i].prenume;
cout<<"\n salariu brut :";
cin>>p[i].brut;
cout<<"\n retineri :";
cin>>p[i].retineri;
}
cout<<"\n==================================";
// creearea instantei angajat a clasei salarii
salarii angajat(p,n,'m');
cout<<"\n stat de plata muncitori";
cout<<"\n==================================";
// apelarea functiei ptr calcularea salariilor angajatilor
angajat.calculeaza_statplata(n);
// afisarea salariilor angajatilor
angajat.afiseaza_statplata(n);
cout<<"\n ==================================";
cout<<"\n cod matricol sef sectie (1000-9999):";
cin>>psefsectie[0].matricol;
cout<<"\n nume sef sectie:";
cin>>psefsectie[0].nume;
cout<<"\n prenume sef sectie:";
cin>>psefsectie[0].prenume;
cout<<"\n salariu brut sef sectie :";
cin>>psefsectie[0].brut;
cout<<"\n retineri sef sectie:";
cin>>psefsectie[0].retineri;
cout<<"\n ===================================";
// creearea instantei sefsectie a clasei salarii
salarii sefsectie(psefsectie,1,'a');
====================================================
matricol:100
nume:pop
prenume:ion
salariu brut:3000.00
somaj:30.00
CAS:285.00
CASS:195.00
impozit:398.40
retineri:1000.00
rest plata:1091.60
matricol:200
nume:stanescu
prenume:stefan
salariu brut:2000.00
somaj:20.00
CAS:190.00
CASS:130.00
impozit:265.60
retineri:850.00
rest plata:544.40
====================================================
cod matricol sef sectie (1000-9999):300
nume sef sectie:popescu
prenume sef sectie:sandu
salariu brut sef sectie :4000
retineri sef sectie:1200
====================================================
stat de plata sef de sectie
====================================================
matricol:300
nume:popescu
prenume:sandu
salariu brut:4000.00
somaj:40.00
CAS:380.00
CASS:260.00
impozit:531.20
retineri:1200.00
rest plata:1588.80
========================================
cod matricol ing. sef (1000-9999):500
nume ing. sef:stabu
prenume ing. sef:spiridon
salariu brut ing. sef :5000
retineri ing. sef:2000
========================================
stat de plata inginer sef
========================================
matricol:500
nume:stabu
prenume:spiridon
salariu brut:5000.00
somaj:50.00
CAS:475.00
CASS:325.00
impozit:664.00
retineri:2000.00
rest plata:1486.00
========================================
continuati salarizarea?(d/n):n
s-a distrus instanta inginerului sef stabu spiridon
s-a distrus instanta sefului de sectie popescu sandu
s-a distrus instanta muncitorilor cu seful de achipa pop ion
}
stivuire_incarcare::varfstiva--;
*ptrstructura=*stivuire_incarcare::varfstiva;
ptrstructura=stivuire_incarcare::varfstiva;
return 1;
}
void main(void)
{
int k,n;
struct tipstiva *ptrcontainera,*ptrcontainers,container,containers;
stivuire_incarcare obiect1,obiect2;
char rasp;k=0;
int terminat=0;
ptrcontainera=(struct tipstiva*)malloc(sizeof(struct tipstiva));
if(ptrcontainera==NULL)
{
cout<<"\n memorie insuficienta un container ";
exit(1);
}
do
{
cout<<"\n numarul maxim de containere, n(1<=n<="<<nmax<<")=";
cin>>n;
}
while((n<1)||(n>nmax));
while(!terminat)
{
cout<<"\n a - asezare container in stiva";
cout<<"\n s - scoatere container din stiva";
cout<<"\n t - terminare program";
cout<<"\n Alegeti operatia dorita:";
cin>>rasp;
switch (rasp)
{
case 'a':
if(k<n)
{
k++;
cout<<"\n cod container:";
cin>>container.cc;
cout<<"\n continut container:";
cin>>container.continut;
cout<<"\n ziua ambalarii:";
cin>>container.data.zi;
cout<<"\n luna ambalarii:";
cin>>container.data.luna;
cout<<"\n anul ambalarii:";
cin>>container.data.an;
cout<<"\n greutate container:";
cin>>container.greutate;
ptrcontainera=&container;
if(k%2)
obiect1.depune_in_stiva(ptrcontainera);
else
obiect2.depune_in_stiva(ptrcontainera);
}
else
cout<<"\n depasirea capacitatii de depozitare";
break;
case 's':
if(k>=1)
{
ptrcontainers=(struct tipstiva*)malloc(sizeof(struct tipstiva));
if(ptrcontainers==NULL)
{
cout<<"\n memorie insuficienta ptr un container ";
exit(1);
}
if(k%2)
{
obiect1.extrage_din_stiva(ptrcontainers);
containers=*ptrcontainers;
cout<<"\n s-a extras containerul obiectului 1:";
cout<<"\n =======================================:";
cout<<"\n cod container :"<<containers.cc;
cout<<"\n continut container :"<<containers.continut;
cout<<"\n data containerului :"<<containers.data.zi;
cout<<"/"<<containers.data.zi<<"/"<<containers.data.an;
cout<<"\n greutate container :"<<containers.greutate;
}
else
{
obiect2.extrage_din_stiva(ptrcontainers);
containers=*ptrcontainers;
cout<<"\n s-a extras containerul obiectului 2:";
cout<<"\n ===================================:";
cout<<"\n cod container :"<<containers.cc;
cout<<"\n continut container :"<<containers.continut;
cout<<"\n data containerului :"<<containers.data.zi;
cout<<"/"<<containers.data.zi<<"/"<<containers.data.an;
cout<<"\n greutate container :"<<containers.greutate;
}
k--;
}
else
cout<<"\n nu mai sunt containere depozitate";
break;
case 't':
terminat=1;
break;
default:
cout<<"\n operatie gresit selectata";
}
}
}
Rezultatele executiei programului de mai sus, sunt afisate in continuare, punandu-se
in evidenta urmatoarele: initializarea si alocarea memoriei pentru o stiva de structuri,
depunerea adreselor structurilor intr-o stiva si a structurilor aferente la adresle specificate in
stiva, extragerea adreselor structurilor din stiva si a structurilor corespunzatoare de la aceste
adrese precum si distrugerea instantelor celor doua obiecte create in program dupa terminarea
folosirii acestora.
initializarea stivei de containere
initializarea stivei de containere
numarul maxim de containere, n(1<=n<=6)=4
a - asezare container in stiva
s - scoatere container din stiva
t - terminare program
Alegeti operatia dorita:a
cod container:100
continut container:ciment
ziua ambalarii:11
luna ambalarii:11
anul ambalarii:2005
greutate container:150
varf stiva =0x00790610
cod container =100
a - asezare container in stiva
s - scoatere container din stiva
t - terminare program
Alegeti operatia dorita:a
cod container:200
continut container:var
ziua ambalarii:21
luna ambalarii:11
anul ambalarii:2005
greutate container:400
varf stiva =0x007904F0
cod container =200
a - asezare container in stiva
s - scoatere container din stiva
t - terminare program
Alegeti operatia dorita:a
cod container:300
continut container:suruburi
ziua ambalarii:11
luna ambalarii:10
anul ambalarii:2005
greutate container:125
varf stiva =0x00790638
cod container =300