functii inline. date si functii statice. c++

26
Introducere Modalităţile (tehnicile, paradigmele) de programare au evoluat de-a lungul anilor, reflectând trecerea de la programe de dimensiuni reduse, la programe şi aplicaţii de dimensiuni foarte mari, pentru coordonarea cărora sunt necesare tehnici evoluate. Software-ul de dimensiuni mari, care nu poate fi realizat de o singură persoană , intră în categoria sistemelor complexe, cu o mare diversitate de aplicaţii. Situaţiile reale şi experiene ale psihologilor au relevat limitele capacităţii umane în perceperea sistemelor complexe, adică imposibilitatea unei persoane de a percepe şi controla simultan un număr mare de entităţi de informaţie. De aceea, este esenţială descompunerea şi organizarea sistemelor complexe, pentru a fi percepute, proiectate sau conduse. Modul în care este abordată programarea, din punct de vedere al descompunerii programelor, defineşte mai multe tehnici de programare , care s-au dezvoltat şi au evoluat odată cu evoluţia sistemelor de calcul. 3

Upload: masteringlove

Post on 21-Oct-2015

272 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Functii Inline. Date Si Functii Statice. C++

Introducere

Modalităţile (tehnicile, paradigmele) de programare au evoluat de-a lungul

anilor, reflectând trecerea de la programe de dimensiuni reduse, la programe şi

aplicaţii de dimensiuni foarte mari, pentru coordonarea cărora sunt necesare tehnici

evoluate.

Software-ul de dimensiuni mari, care nu poate fi realizat de o singură

persoană , intră în categoria sistemelor complexe, cu o mare diversitate de

aplicaţii. Situaţiile reale şi experiene ale psihologilor au relevat limitele capacităţii

umane în perceperea sistemelor complexe, adică imposibilitatea unei persoane de

a percepe şi controla simultan un număr mare de entităţi de informaţie. De aceea,

este esenţială descompunerea şi organizarea sistemelor complexe, pentru a fi

percepute, proiectate sau conduse.

Modul în care este abordată programarea, din punct de vedere al

descompunerii programelor, defineşte mai multe tehnici de programare , care s-au

dezvoltat şi au evoluat odată cu evoluţia sistemelor de calcul.

Programarea procedurală este prima modalitate de programare care a fost

şi este încă frecvent folosită. În programarea procedurală accentul se pune pe

descompunerea programului în proceduri (funcţii) care sunt apelate în ordinea de

desfăşurare a algoritmului. Limbajele care suportă această tehnică de programare

prevăd posibilităţi de transfer a argumentelor către funcţii şi de returnare a

valorilor rezultate. Limbajul Fortran a fost primul limbaj de programare

procedurală. Au urmat Algol60, Algol68, Pascal, iar C este unul din ultimele

invenţii în acest domeniu.

Programarea modulară. În cursul evoluţiei programării procedurale,

accentul în proiectarea programelor s-a deplasat de la proiectarea procedurilor

către organizarea datelor, această deplasare reflectând creşterea dimensiunilor

programelor. O mulţime de proceduri corelate, împreună cu datele pe care le

3

Page 2: Functii Inline. Date Si Functii Statice. C++

manevrează , sunt organizate ca un modul. Tehnica de programare modulară

decide descompunerea unui program în module, care încorporează o parte din

datele programului şi funcţiile care le manevrează . Această tehnică este cunoscută

ca tehnică de ascundere a datelor (data-hiding). În programarea modulară stilul de

programare este în continuare procedural, iar datele şi procedurile sunt grupate în

module, existând posibilitatea de ascundere a unor informaţii definite într-un

modul, faţă de celelalte module. Gruparea de date şi proceduri în module nu

implică şi o asociere strictă între acestea.

Programarea orientată pe obiecte apelează la o modalitate nouã de gândire

a unei probleme. Spre deosebire de programarea proceduralã care se concentreazã

pe structuri de date si algoritmi, programarea orientatã pe obiecte se concentreazã

pe definirea de obiecte care modeleazã problema ce trebuie rezolvatã. În

programarea orientatã pe obiecte (POO) un program are rolul de a simula stãrile si

activitãtile obiectelor lumii reale. Pe lângã structuri de date (care descriu stãrile

obiectelor, atributele acestora) trebuie incluse si metodele asociate obiectelor, adicã

acele functii care modificã atributele obiectelor si care descriu comportamentul lor.

Concepte ale programării orientate pe obiecte

Conceptele programãrii orientate pe obiecte au apãrut din dezvoltãrile

realizate în cadrul limbajelor moderne de programare. Astfel, limbajele orientate

pe obiecte au noi structuri care îmbunãtãtesc întretinerea programului si fac ca

porţiuni mari de program sã fie reutilizabile, conducând astfel la scãderea costului

de dezvoltare a produselor software. Cele sase concepte de bazã ce caracterizeazã

programarea orientatã pe obiecte sunt :

Obiecte;

Clase;

Mesaje;

4

Page 3: Functii Inline. Date Si Functii Statice. C++

Incapsularea;

Polimorfismul;

Moştenirea.

Un obiect poate fi considerat ca fiind o entitate care încorporeazã atât

structuri de date (denumite atribute) cât si comportament (actiuni). Obiectele sunt

inteligente prin faptul cã realizeazã anumite actiuni si “stiu” cum sã execute aceste

actiuni. Inteligenta unui obiect reprezintã o formã de abstractizare prin faptul cã

presupune cã un obiect poate executa o actiune si ascunde detaliile referitoare la

modul în care se va realiza efectiv actiunea. Obiectele pot fi de tipuri diferite:

entitãti fizice, algoritmi, relatii sau subsisteme. Practic, obiectele sunt componente

de software reutilizabil care modeleazã elemente din lumea realã.

Clasele desemnează o colecţie de obiecte (de natură materială sau spirituală)

care au în comun faptul căpot fi caracterizate similar din punct de vedere

informational şi comportamental.

Obiectele pot comunica între ele prin intermediul mesajelor. Un mesaj este o

cerere adresată unui obiect pentru a invoca una din metodele sale. Astfel, un mesaj

conţine numele metodei şi argumentele metodei.

Încapsularea se referă la capacitatea de a separa aspectele externe ale unui

obiect (interfaţa), accesibile altor obiecte, de aspectele implementaţionale, interne

obiectului, care sunt ascunse faţă de celelalte obiecte. Utilizatorul unui obiect poate

accesa doar anumite metode ale acestuia, numite publice, în timp ce atributele şi

celelalte metode îi rămân inaccesibile (acestea se numesc private).

Moştenirea - mecanismul derivării, permite crearea facilă de noi clase, care

preiau caracteristicile unor clase de bază, deja definite. Derivarea are ca obiectiv

reutilizarea soft-ului, prin folosirea uneor funcţii deja scrise pentru clasele existente

5

Page 4: Functii Inline. Date Si Functii Statice. C++

şi eliminarea redundanţei descrierilor, în cazul claselor care au elemente comune,

funcţii sau date.

Termenul polimorfism se referă la comportamente alternative între clase

derivate înrudite. În cazul în care mai multe clase moştenesc atributele şi

comportamentele unei clase de bază, pot apărea situaţii în care comportamentul

unei clase derivate ar trebui să fie diferit de cel al clasei de bază sau de cel al clasei

derivate de tip frate (de pe acelaţi nivel). Aceasta înseamnă că un mesaj poate avea

efecte diferite în funcţie de clasa obiectului care primeşte mesajul.

Conceptul de tip de date este unul din conceptele fundamentale ale

programării. În matematică, ştiinţă, tehnică, economie şi alte domenii ale activităţii

umane se lucrează cu date, care sunt numere întregi, numere reale, şiruri de

caractere, valori logice sau structuri de date construite cu ajutorul acestora. Se

admite că, atît mulţimea numerelor întregi, cît şi cea a numerelor reale, sunt

mulţimi infinite. În programare, se are însă în vedere că este necesar să se respecte

anumite restricţii, legate de modul de reprezentare a datelor în calculator. Să

considerăm, de exemplu, mulţimea numerelor întregi. În matematică, aceasta este o

mulţime infinită. În calculator însă, numărul întreg se reprezintă într-o zonă de

memorie de lungime finită, de exemplu 4 octeţi (32 biţi), ceea ce înseamnă că

"mulţimea numerelor de tip întreg", care pot fi astfel reprezentate, este finită,

conţinînd 2 la puterea 32 valori. Trebuie avute în vedere, de asemenea, restric

ţiile privind operaţiile care pot fi efectuate pe calculator asupra acestei mulţimi de

valori.

Prin tip de date (engl.: data type) se înţelege o mulţime de valori, căreia i se

asociază o mulţime de operaţii asupra valorilor respective.

Tipul unei date precizează mărimea si organizarea locaţiei de memorie în

care este stocată data respectivă, precum şi comportamentul datei sub acţiunea

operatorilor. De exemplu, dacă x si y sunt două variabile de tip întreg cu valorile 7

6

Page 5: Functii Inline. Date Si Functii Statice. C++

şi respectiv 2, atunci expresia x/y are ca rezultat numărul întreg 3, iar dacă x şi y

sunt variabile în virgule mobilă cu aceleaşi valori numerice, rezultatul evaluării

expresiei x/y este 3,5.

În fiecare limbaj de programare există un set de tipuri de date primitive,

numite şi tipuri de date fundamentale sau elementare. Acestea sunt tipuri

predefinite în limbajul respectiv, deci ele nu trebuie sa fie definite de către

programator. Cu ajutorul acestor tipuri primitive, programatorul poate să

construiască propriile sale tipuri de date derivate. În acest scop, limbajul de

programare îi pune la dispoziţie anumite modalităţi de construire.

În principiu, majoritatea limbajelor de programare admit că tipuri de date

primitive numerele întregi şi reale, caracterele şi valorile logice (booleene). Pot

exista însă mai multe tipuri de numere întregi sau reale, care să difere între ele prin

lungimea zonei de memorie alocate. Pot exista, de exemplu, numere întregi

reprezentate pe unul, doi, patru sau opt octeţi, ele fiind considerate tipuri de date

diferite.

Funcţiile sunt tipuri derivate şi reprezintă una din cele mai importante

caracteristici ale limbajelor C şi C++. Forma generală de definire a unei funcţii

este:

tip_returnat nume_func(tip1 arg1,tip2 arg2,……,tipn

argn) {

//corpul functiei

}

Funcţia cu numele nume_func returnează o valoare de tip tip_returnat şi

are un număr n de argumente formale declarate ca tip şi nume în lista de

argumente formale. Argumentele formale din declaraţia unei funcţii se mai numesc

7

Page 6: Functii Inline. Date Si Functii Statice. C++

şi parametrii funcţiei. Dacă o funcţie nu are argumente, atunci lista din paranteze

le rotunde este vidă .

O funcţie este un nume global, dacă nu este declarată de tip static. O funcţie

declarată static are domeniul de vizibilitate restrâns la fişierul în care a fost

definită.

Corpul funcţiei este propriuei şi nu poate fi accesat din afara acesteia (nici

printr-o instrucţiune goto). Corpul unei funcţii este o instrucţiune compusă , adică

o succesiune de instrucţiuni şi declaraţii incluse între acolade. În corpul funcţiei se

pot defini variabile, care sunt locale şi se memorează în segmentul de stivă al

programului. Dacă nu sunt declarate static, variabilele locale se crează la fiecare

apel al funcţiei şi se distrug atunci când este părăsit blocul în care au fost definite.

Nu se pot defini funcţii în interiorul unei funcţii. Argumentele formale ale unei

funcţii sunt considerate variabile locale ale funcţiei, ca orice altă variabilă definită

în funcţia respectivă.

Dacă o funcţie nu are de returnat nici o valoare, atunci tip_returnat din

declaraţia funcţiei este tipul void şi nu este necesară o instrucţiune de returnare

(return) în funcţie. În toate celelalte cazuri, în corpul funcţiei trebuie să fie

prevăzută returnarea unei variabile de tipul tip_returnat, folosind instrucţiunea

return. Dacă în definiţie nu este prevăzut un tip_returnat, se consideră implicit

eeturnarea unei valori de tip întreg.

8

Page 7: Functii Inline. Date Si Functii Statice. C++

Funcţii Inline

La apelul unei funcţii obişnuite se întrerupe execuţia funcţiei apelante şi se

execută un salt la adresa de memorie la care se găseşte corpul funcţiei apelate. La

terminarea execuţiei funcţiei apelate se revine în funcţia apelantă, reluându-se

execuţia cu instrucţiunea imediat următoare apelului de funcţie. În situaţiile în care

corpul funcţiei apelate este format din câteva instrucţiuni, operaţiile descrise

anterior (implicate în apel şi revenire) pot fi mai complicate decât un apel prin

expandare (în care apelul funcţiei este înlocuit cu însuşi corpul funcţiei apelate).

Pentru eliminarea acestor dezavantaje, se folosesc funcţiile inline.

Prezenţa funcţiilor inline anunţă compilatorul să nu mai genereze

instrucţiunile în cod maşină necesare apelului şi revenirii, ceea ce conduce la

mărirea timpului de compilare în favoarea micşorării timpului de execuţie.

Utilizarea funcţiilor inline se justifică doar în situaţiile în care codul generat de

compilator pentru execuţia corpului funcţiei este mai mic decât codul generat

pentru apel şi revenire.

Practic, funcţiile care au corpul format din maximum trei instrucţiuni şi nu

conţin instrucţiuni repetitive (for, while, do-while), pot fi declarate

inline.

Declararea unei funcţii inline se realizează explicit, specificând în antetul funcţiei

respective cuvântul cheie inline.

inline tip_val_ret nume_fct (lista_declar_par_formali);

În cazul metodelor unei clase, dacă acestea sunt definite în interiorul clasei,

ele sunt considerate, implicit, funcţii inline (în exerciţiul anterior, funcţiile

arată_Lung, arată_Lat şi calcul_arie sunt, implicit, funcţii inline).

Există şi posibilitatea de a declara metoda la declararea clasei şi de a specifica,

explicit, că este funcţie inline la definirea funcţiei.

9

Page 8: Functii Inline. Date Si Functii Statice. C++

Exerciţiu: Să se definească tipul de date complex, cu datele membru parte

reală şi parte imaginară. Operaţiile care pot fi realizate asupra datelor de acest tip,

vor fi: citirea unei date de tip complex (citirea valorilor pentru partea reală şi cea

imaginară); afişarea unei date de tip complex; calculul modulului unui complex;

calculul argumentului unui complex; incrementarea părţii imaginare;

decrementarea părţii imaginare; funcţii care returnează valoarea părţii reale şi a

părţii imaginare a unei date de tip complex; adunarea a două date de tip complex;

înmulţirea a două date de tip complex.

#include <iostream.h>

#include <math.h>

#define PI 3.14159

class complex{

double real, imag;

public:

int citire();

void afisare();

double modul();

double arg();

void incrpi()

10

Page 9: Functii Inline. Date Si Functii Statice. C++

//incrementeaza partea imaginara; FUNCŢIE INLINE,

implicit, fiind definită în interiorul clasei

{ imag++;}

inline void decrpi();//decrementarea partii

imaginare

double retreal(); //returneaza partea reala

double retimag(); //returneaza partea imaginara

void adun_c(complex, complex);//aduna 2 numere

complexe

void inm_c(complex*, complex*);//produsul a 2

numere complexe

};

inline double complex::modul()

{ return sqrt(real*real+imag*imag);}

int complex::citire()

{ cout<<"P. reala:"; if (!(cin>>real)) return 0;

cout<<"P. imag:";if (!(cin>>imag)) return 0 ;

return 1; }

void complex::afisare()

{ if (imag>=0)

11

Page 10: Functii Inline. Date Si Functii Statice. C++

cout<<real<<"+"<<imag<<"*i"<<"\n";

else cout<<real<<imag<<"*i\n";}

double complex::arg()

{if (real==0 && imag==0) return 0.0;

if (imag==0) //z=p. reala

if (real>0) return 0.0;

else return PI;

if (real==0)

if (imag>0) return PI/2;

else return (3*PI)/2;

double x=atan(imag/real);

if (real<0) return PI+x;

if (imag<0) return 2*PI+x; return x;}

inline void complex::decrpi()

{ imag--;}

double complex::retreal()

{ return real;}

double complex::retimag()

{ return imag; }

12

Page 11: Functii Inline. Date Si Functii Statice. C++

void complex::adun_c (complex x1, complex x2)

{real=x1.real+x2.real;

imag=x1.imag+x2.imag;}

void complex::inm_c(complex *x1, complex *x2)

{real=x1->real*x2->real-x1->imag*x2->imag;

imag=x1->real*x2->imag+x1->imag*x2->real;}

void main()

{complex z1;z1.citire();

cout<<"z1=";z1.afisare();

complex z2;z2.citire();cout<<"z2=";z2.afisare();

cout<<"Modulul z2="<<z2.modul()<<'\n';

cout<<"Agument z2="<<z2.arg()<<'\n';

cout<<"P. reala z2="<<z2.retreal()<<"P imag

z2="<<z2.retimag()<<'\n';

z2.incrpi();cout<<"Dupa increm p

imag="<<z2.retimag()<<'\n';z2.afisare();

complex z3;z3.adun_c(z1,z2);cout<<"Adunare

z1+z2=";z3.afisare();

complex*pz1=&z1,*pz2=&z2;z3.inm_c(pz1,pz2);

cout<<"Inmultire z1+z2=";z3.afisare();

13

Page 12: Functii Inline. Date Si Functii Statice. C++

Date şi Funcţii statice

Implicit membrii de date sunt alocati pe obiecte. De exemplul fiecare

angajat al unei firme are propiul sau nume, cnp etc. Exista, insa unele propietati

care sunt impartite de catre toate obiectele unei clase, cum ar fi de exemplu, pentru

clasa angajat, numarul total de angajati ai unei firme, salariul mediu al firmei etc.

O varinata posibila ar fi stocarea acestor informatii intr-o variabila globală

uzuală. De exemplu, am putea utiliza o variabilă de tip întreg pentru a păstra

numărul de obiecte angajat. Problema acestei soluţii este ca variabilele globale

sunt declarate in afara clasei; pentru putea fi aduse în interiorul calsei aceste

variabile trebuie sa fie declarate de tip static.

Datele statice nu se regasesc în fiecare set de valori ale clasei, ci într-un

singur exemplar, pentru toate obiectele clasei. Datele ce apar in toate obiectele se

alocă de catre un constructor , dar cum un membru static nu face parte din nici un

obiect, nu se aloca prin constructor. Asfel, la definirea clasei, o data statică nu se

consideră definita, ci doar declarată, urmand a avea o definitie externă clasei.

Legatura cu declaraţia din interiorul clasei se face prin operatorul de rezolutie ::

precedat de numele clasei din care face parte precum si de tipul variabilei statice,

asfel:

class angajat

{

//...

Static int total_ang;

//...

}

int angajat::total_ang=0;;

Variabila total_ang va fi unica pentru toti angajatii. Se poate observa ca o

data cu definirea varbilei statice s-a realizat si inţializarea acesteia.

14

Page 13: Functii Inline. Date Si Functii Statice. C++

Functiile membre statice efectueaza prelucrari care nu sunt individualizate

pe obiecte, ci prelucrări care au loc la nivelul clasei. Funcţiile statice nu aparţin

unui obiect anume si deci nu beneficiaza de referinta implicita a obiectului asociat

( pointerul this). Daca funcţia membră statică operează pe o data nestatică a clasei,

obiectul trebuie transmis explicit ca parametru, in timp ce cu datele membre

statice, lucreaza in mod direct.

Programul următor redefineşte clasa angajat, prin adaugarea datelor membre

statice total_ang si total_b care vor retine numarul total de angajati si numarul

total de barbati. Clasa va contine si trei functii membre statice care vor returna

valorile reţinute în cele două date statice.

class angajat

{

private:

int varsta;

float salariul;

char gen;

static int total_ang;

static int total_b;

public:

char nume[20];

angajat()

{strcpy(nume,”Anonim”);

varsta=0;

salariul=0;

total_ang++;

}

~angajat(){total_ang--;}

15

Page 14: Functii Inline. Date Si Functii Statice. C++

void seteaza_valori()

{cout<<”Numele:”

cin>>nume;

cout>>”salariul:”

cin>>salariul;

cout<<”varsta”

cin>>varsta;

}

static int spune_total_ang() {return total_ang;}

static int spune_total_b(){return total_b;}

static int numara_total_b (angajat *ang)

{if(ang->gen==”B”) total_b++;}

void afisare()

{cout<<”nume: ”<<nume<<endl;

cout<<”varsta: ”<<varsta<<endl;

cout<<”salariul: ” <<salariul;

}

}

int angajat::total_ang=0;

int angajat::total_b=0;

void main()

{ angajat tab[20];

int i, n;

cout<<"\n Cate obiecte doriti sa creati?";

cin>>n;

for (i=0;i<n;i++)

{tab[i].seteaza_valori();

16

Page 15: Functii Inline. Date Si Functii Statice. C++

angajat::numara_total_b(&tab[i]);

}

cout<<”firma are un total de

angajati”<<angajat::spune_total_ang;

cout<<”din care”<<angajat::spune_total_b<<” sunt

barbati”;

}

In programul de mai sus se remarca faptul ca intretinerea variabilei total_ang

cade in sarcina constructorilor si a destructorului, care incrementeaza sau

decrementreaza acestă variabilă. De asemenea, funcţia membră statică

numara_total_b() primeste ca parametru referinţa la un obiect de tip angajat pentru

că utilizează data membră gen care nu este statică. Întrucât variabilele membru

statice nu apartin unui obiect anume, ele pot fi accesate si prin prefixarea numelui

clasei de operatorul “::”.

17

Page 16: Functii Inline. Date Si Functii Statice. C++

Concluzii

Pe măsuta evoluării metodelor şi tehinicilor de programare se observă o

tendinţă tot mai mare spre crearea unor programe de volume foarte mari, care

cuprind şi operează cu masive de date imense. La momentul actual marea

majoritate a proiectelor realizate atît de profesionişti cît şi de amatori sunt niste

sisteme complexe care nu pot fi create şi gestionate de o singura persoană. Ca o

soluţie pentu situaţia creată a fost descompunerea programelor în mai multe părţi

componente pentru a putea fi mai uşor de creat şi administrat. În vederea acestui

fapt, au fost concepute, pe măsura dezvoltării tehnologiilor şi a gîndirii inginereşti,

diferite metode de programare precum programarea procedurlă, modulară şi

orientată pe obiecte. Fiecare din aceste metode îşi găseşte aplicare în practică în

dependenţă de fiecare caz în parte cu care se confruntă programatorii. Programarea

orientată pe obiecte reprezintă o viziune totalmente nouă asupra gîndirii unei

probleme, fiind cea mai eficientă metodă de programare atunci cînd este vorba de

proiecte masive.

În C++ se observă un şir de îmbunătăţiri faţă de versiune mai veche, C,

printre care fiins şi aplicarea funcţiilor inline, care se utilizează atunci cînd se

lucrează cu funcţii complicate, corpul cărora are mai multe instrucţiuni. Utilizarea

acestui tip de funcţii anunţă compilatorul să nu mai genereze instrucţiunile în cod

maşină necesare apelului şi revenirii, ceea ce conduce la mărirea timpului de

compilare în favoarea micşorării timpului de execuţie. Utilizarea funcţiilor inline

se justifică doar în situaţiile în care codul generat de compilator pentru execuţia

corpului funcţiei este mai mic decât codul generat pentru apel şi revenire.

Datele statice se utilizează pentru ca toate obiectele clasei să aiba acces la

datele care sunt comune, şi în acelaşi timp sa fie economisit spaţiul ocupat de date

în caz ca ar fi fost nevoie sa fie cîte un set de date aparte pentru fiecare obiect al

clasei. Astfel aceste elemente noi ale tehnicilor de programare permit eficientizarea

18

Page 17: Functii Inline. Date Si Functii Statice. C++

procesului prin simplificarea operaţiunilor şi micşorarea timpului de execuţie.

Functiile membre statice efectueaza prelucrari care nu sunt individualizate pe

obiecte, ci prelucrări care au loc la nivelul clasei. Funcţiile statice nu aparţin unui

obiect anume si deci nu beneficiaza de referinta implicita a obiectului asociat

( pointerul this). Daca funcţia membră statică operează pe o data nestatică a clasei,

obiectul trebuie transmis explicit ca parametru, in timp ce cu datele membre

statice, lucreaza in mod direct.

Bibliografie

Oprea M., Programare orientată pe obiecte - Exemple în limbajul C+

+, Editura Matrix Rom.

Dr. Kris Jamasa, Totul despre C si C++, Editura Teora.

Ion Smeureanu, Programare orientată pe obiecte în Limbajul C++,

Editura CISON, Bucureşti 2005.

Liviu Negrescu, Limbajul C++ , Editura ALBASTRA , Cluj 2000.

Luminita Duţa, Programarea calculatoarelor în limbajul C++ ,

Editura Cetatea de Scaun 2006.

19