Sunteți pe pagina 1din 12

8. Template-uri de clase.

Tratarea excepiilor care pot


aprea la alocarea dinamic a memoriei
Obiective
- nelegerea modului n care se pot folosi template-urile de clase pentru crearea
grupurilor de tipuri de date
- nelegerea distinciei ntre clase template i template-uri de clase
- nelegerea legturii ntre template-uri, prieteni, motenire i membri statici
- Studierea modului n care se trateaz excepiile care pot aprea la alocarea
dinamic a memoriei
- Studierea modului n care se poate folosi auto_ptr pentru a preveni problemele
de alocare i dealocare a memoriei

- Template-uri de clase
Template-urile (abloanele) de clase se mai numesc i tipuri parametrizate i se
folosesc pentru crearea claselor generice. Pentru adaptarea unei astfel de clase,
este nevoie de unul sau mai muli parametri de tip care transform clasa dintr-una
generic n una particular.
Pentru a nelege ce este un template de clas vom folosi noiunea de stiv
(stack). Aceasta este o structur de date care permite stocarea unor valori, ordinea
de citire a acestora fiind invers ordinii n care au fost nscrise n colecie. Regula
last-in-first-out specific stivelor este valabil indiferent de tipul elementelor care sunt
ncrcate. Cnd se pune problema instanierii unei stive, trebuie specificat tipul de
dat al elementelor. Template-urile de clase ofer posibilitatea implementrii unei
stive generice care poate fi particularizat pentru un tip specific de dat.
Template-urile de clase ncurajeaz reutilizarea codului prin posiblitatea de a
crea dintr-o clas generic a unei versiuni specifice unui tip de dat. Atunci cnd
programatorul dorete s foloseasc o variant adaptat unui tip de dat pentru
ablonul su, are la dispoziie o modalitate simpl de scriere pe baza creia
compilatorul scrie codul surs cerut. Astfel, clasa template Stack ar putea deveni o
baz pentru crearea unor clase adaptate: stiv de valori double, stiv de valori int,
stiv de valori char, stiv de valori Employee.
Exemplu
tstack1.h
#ifndef TSTACK1_H
#define TSTACK1_H
template <class T>
class Stack
{
public:
Stack(int = 10); //stiva are dimensiunea implicita 10
~Stack() { delete[] stackPtr; } //destructor
bool push(const T&); //insereaza un element in stiva
bool pop(T&);
//extrage un element din stiva
private:
int size;
//numarul de elemente din stiva
int top;
//localizarea elementului din varful stivei

Programarea calculatoarelor i limbaje de programare I

T* stackPtr; //pointer la stiva


bool isEmpty() const {return top == -1;}
//functii
bool isFull() const {return top == size-1;} //utilitare
};
template<class T>
Stack<T>::Stack(int s)
{
size = s > 0 ? s : 10;
top = -1; //initial stiva este goala
stackPtr = new T[size]; //alocarea spatiului pentru elemente
}
//Introduce un element in stiva
//Intoarce 1 daca s-a putut face inserarea si 0 in caz contrar
template<class T>
bool Stack<T>::push(const T& pushValue)
{
if(!isFull())
{
stackPtr[++top] = pushValue; //plaseaza elementul in stiva
return true; //inserare realizata cu succes
}
return false; //inserarea nu s-a putut realiza
}
//Extrage un element din stiva
template<class T>
bool Stack<T>::pop(T& popValue)
{
if(!isEmpty())
{
popValue = stackPtr[top--]; //sterge elementul din stiva
return true; //extragere realizata cu succes
}
return false; //extragerea nu s-a putut realiza
}
#endif
test_tstack1.cpp
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include "tstack1.h"
int main()
{
Stack<double> doubleStack(5);
double f = 1.1;
2

Programarea calculatoarelor i limbaje de programare I

cout << "Inserarea elementelor in doubleStack\n";


while(doubleStack.push(f))
{
cout << f << ' ';
f += 1.1;
}
cout << "\nStiva este plina. "
<< "Nu se mai poate insera elementul " << f
<< "\n\nExtragerea elementelor din doubleStack\n";
while(doubleStack.pop(f))
cout << f << ' ';
cout << "\nStiva este goala. "
<< "Nu se mai pot extrage elemente\n";
Stack<int> intStack;
int i = 1;
cout << "\nInserarea elementelor in intStack\n";
while(intStack.push(i))
{
cout << i << ' ';
++i;
}
cout << "\nStiva este plina. "
<< "Nu se mai poate insera elementul " << i
<< "\n\nExtragerea elementelor din intStack\n";
while(intStack.pop(i))
cout << i << ' ';
cout << "\nStiva este goala. "
<< "Nu se mai pot extrage elemente\n";
return 0;
}
Rulnd acest program obinem urmtorul rezultat:
Inserarea elementelor in doubleStack
1.1 2.2 3.3 4.4 5.5
Stiva este plina. Nu se mai poate insera elementul 6.6
Extragerea elementelor din doubleStack
5.5 4.4 3.3 2.2 1.1
Stiva este goala. Nu se mai pot extrage elemente
Inserarea elementelor in intStack
1 2 3 4 5 6 7 8 9 10
3

Programarea calculatoarelor i limbaje de programare I

Stiva este plina. Nu se mai poate insera elementul 11


Extragerea elementelor din intStack
10 9 8 7 6 5 4 3 2 1
Stiva este goala. Nu se mai pot extrage elemente
Definiia clasei template Stack din programul de mai sus este similar unei
definiii obinuite, cu excepia faptului c este precedat de header-ul
template<class T>
care specific faptul c aceasta este definiia unei clase template cu parametrul T.
Atunci cnd clasa Stack va fi folosit pentru instanierea unui obiect, parametrul T
va fi nlocuit cu un tip particular de dat. Se poate folosi orice tip de dat pentru a
particulariza parametrul T. Tipul elementelor stocate in Stack este menionat
generic prin parametrul T n header-ul clasei i in definiiile funciilor membre. Pentru
tipurile de dat neprimitive care sunt folosite n rolul lui T exist dou constrngeri:
trebuie s aib constructor implicit i trebuie s suporte operatorul de asignare. Dac
un obiect al clasei Stack refer spaii de memorie alocate dinamic, operatorul de
asignare trebuie suprancrcat pentru acel tip de dat.
Prima instruciune a funciei main din exemplul anterior instaniaz obiectul
doubleStack de dimensiune 5. Obiectul este declarat ca fiind din clasa
Stack<double> (pronunat n englez Stack of double). Compilatorul asociaz
tipul double cu parametrul de tip T n template pentru a genera codul surs al clasei
Stack de tip double. Dei programatorul nu vede acest cod surs, el este inclus
automat n program i compilat.
Programul introduce n stiva doubleStack prin apelul funciei push valorile
1.1, 2.2, 3.3, 4.4 i 5.5 de tip double. Bucla care introduce valorile se termin
atunci cnd funcia push ncearc s insereze a asea valoare, iar stiva de
dimensiune 5 este deja plin. Aceste valori sunt apoi extrase i afiate printr-o bucl
care conine apelul funciei membre pop. Atunci cnd funcia ncearc s extrag a
asea valoare, moment n care stiva care are dimensiune 5 este deja goal, bucla
din care face parte apelul funciei pop se termin.
n mod similar, programul creeaz stiva intStack de tip Stack<int> de
dimeniune 10, n care insereaz valori, iar apoi le extrage i le afieaz.
Definiia n afara clasei a fiecrei funcii membre ncepe cu header-ul
template<class T>
Apoi fiecare funcie este scris obinuit, singura diferen fiind aceea c tipul
elementelor din stiv este, generic, T. Operatorul binar domeniu :: este folosit
mpreun cu numele clasei template Stack<T> pentru a face asocierea dintre
definiia funciei membre i domeniul clasei template. Cnd doubleStack este
instaniat ca fiind de tip Stack<double>, constructorul Stack folosete new pentru
a crea un tablou de elemente de tip double pentru a reprezenta stiva. Declaraia
stackPtr = new T[size];
din definiia clasei template Stack este transformat de compilator n clasa
Stack<double> sub forma
stackPtr = new double[size];
n exempul pe care l-am prezentat pn acum, funcia main conine dou
secvene de cod similare pentru a realiza aceleai operaii asupra obiectelor
doubleStack i intStack. Un alt exemplu de folosire a abloanelor de clase este

Programarea calculatoarelor i limbaje de programare I

cea a funciilor template. Funcia testStack din exemplul urmtor este similar
funciei main din exemplul anterior pentru c introduce o serie de valori n Stack<T>
prin funcia push i extrage aceste valori prin funcia pop. Funcia testStack
folosete parametrul formal T de tip pentru a reprezenta tipul de dat al valorilor
stocate n Stack<T>.
Exemplu
test2_tstack1.h
#include<iostream>
using std::cout;
using std::cin;
using std::endl;
#include "tstack1.h"
template<class T>
void testStack(
Stack<T> &theStack,
T value,
T increment,
const char* stackName)
{
cout << "\nInserarea elementelor in " << stackName << '\n';
while(theStack.push(value))
{
cout << value << ' ';
value += increment;
}
cout <<
<<
<<
<<

"\nStiva este plina. Nu se mai poate insera elementul "


value
"\n\nExtragerea elementelor din "
stackName << '\n';

while(theStack.pop(value))
cout << value << ' ';
cout << "\nStiva este goala. Nu se mai pot extrage elemente\n";
}
int main()
{
Stack<double> doubleStack(5);
Stack<int> intStack;
testStack(doubleStack, 1.1, 1.1, "doubleStack");
testStack(intStack, 1, 1, "intStack");
return 0;
}
tstack1.h
5

Programarea calculatoarelor i limbaje de programare I

#ifndef TSTACK1_H
#define TSTACK1_H
template <class T>
class Stack
{
public:
Stack(int = 10); //stiva are dimensiunea implicita 10
~Stack() { delete[] stackPtr; } //destructor
bool push(const T&); //insereaza un element in stiva
bool pop(T&);
//extrage un element din stiva
private:
int size;
//numarul de elemente din stiva
int top;
//localizarea elementului din varful stivei
T* stackPtr; //pointer la stiva
bool isEmpty() const {return top == -1;}
//functii
bool isFull() const {return top == size-1;} //utilitare
};
template<class T>
Stack<T>::Stack(int s)
{
size = s > 0 ? s : 10;
top = -1; //initial stiva este goala
stackPtr = new T[size]; //alocarea spatiului pentru elemente
}
//Introduce un element in stiva
//Intoarce 1 daca s-a putut face inserarea si 0 in caz contrar
template<class T>
bool Stack<T>::push(const T& pushValue)
{
if(!isFull())
{
stackPtr[++top] = pushValue; //plaseaza elementul in stiva
return true; //inserare realizata cu succes
}
return false; //inserarea nu s-a putut realiza
}
//Extrage un element din stiva
template<class T>
bool Stack<T>::pop(T& popValue)
{
if(!isEmpty())
{
popValue = stackPtr[top--]; //sterge elementul din stiva
return true; //extragere realizata cu succes
}
return false; //extragerea nu s-a putut realiza
}

Programarea calculatoarelor i limbaje de programare I

#endif
Rulnd acest program obinem urmtorul rezultat:
Inserarea elementelor in doubleStack
1.1 2.2 3.3 4.4 5.5
Stiva este plina. Nu se mai poate insera elementul 6.6
Extragerea elementelor din doubleStack
5.5 4.4 3.3 2.2 1.1
Stiva este goala. Nu se mai pot extrage elemente
Inserarea elementelor in intStack
1 2 3 4 5 6 7 8 9 10
Stiva este plina. Nu se mai poate insera elementul 11
Extragerea elementelor din intStack
10 9 8 7 6 5 4 3 2 1
Stiva este goala. Nu se mai pot extrage elemente
n funcia main se instaniaz dou obiecte de tip Stack<double> numit
doubleStack i Stack<int> numit intStack. Aceste obiecte sunt folosite in cele
dou apeluri ale funciei testStack:
testStack(doubleStack, 1.1, 1.1, "doubleStack");
testStack(intStack, 1, 1, "intStack");
Remarcm faptul c programul din primul exemplu i cel de mai sus conduc la
rezultate identice.

Template-uri de clase i parametri non-tip


Clasa template Stack folosete numai parametrul de tip n header-ul templateului. Se pot folosi, ns, i parametri non-tip. Header-ul acestei clase ar putea fi
modificat astfel nct s primeasc un parametru suplimentar de tip ntreg astfel:
template<class T, int elements> //elements este parametru non-tip
Atunci, o declaraie a unui obiect ar fi:
Stack<double, 100> mostRecentSalesFigures;
care ar instania la compilare o stiv numit mostRecentSalesFigures cu 100 de
elemente cu valori de tip double. Aceast clas ar fi de tip Stack<double, 100>.
Header-ul clasei ar putea, atunci, s conin o dat membr private declarat ca
tablou astfel:
T stackHolder[elements];

Template-uri i membri statici


n clasele care nu sunt de tip template, o copie a unei date membre de tip
static este partajat de de toate obiectele clasei i data de tip static trebuie
iniializat n domeniul fiier.
Fiecare clas instaniat dintr-un template de clas are propria copie a fiecrui
membru static din template. Toate obiectele unei clase partajeaz acea dat
membra static. Ca i n cazul claselor non-template, membrii static trebuie
iniializat o singur dat, n domeniul fiier. De asemenea, fiecare clas va avea
propria copie a funciilor membre statice.

Programarea calculatoarelor i limbaje de programare I

- Tratarea excepiilor care pot aprea la alocarea dinamic


a memoriei
Constructorii, destructorii i tratarea excepiilor
n aceast seciune vom vedea cum putem trata excepiile care pot aprea n
urma apelului constructorului unei clase atunci cnd se aloc dinamic memorie. Cum
ar trebui, de exemplu, s se comporte constructorul clasei String atunci cnd apare
o eroare la apelul operatorului new prin care se arat c nu este suficient spaiu n
memoria calculatorului pentru pstrarea reprezentrii interne a irului de caractere?
Problema este c un constructor nu poate returna o valoare, astfel c ar trebui gsit
alt mecanism prin care codului apelant s i se transmit aceast eroare. O variant
ar fi returnarea obiectului chiar dac el nu a fost corect construit, n sperana c
utilizatorul clasei va face testele necesare nainte de a folosi obiectul. O alt variant
este setarea valorii unei variabile din afara constructorului prin a crei valoare s
semnalizm eroarea care a aprut. A treia variant este generarea unei excepii prin
care s semnalm eroarea aprut n constructor.
Excepiile generate n constructori conduc la apelul automat al destructorilor
pentru obiectele construite care sunt parte a obiectului gazd, nainte de a de
declana excepia.
Sunt apelai destructorii tuturor obiectelor automatice construite n blocul try n
care a aprut excepia, nainte de a se declana excepia.
Dac un obiect are obiecte membre i apare o excepie nainte de construirea
complet a obiectului gazd, atunci se apeleaz automat toi destructorii obiectelor
membre care au fost construite naite de apariia erorii.
O excepie care apare n destructor poate fi interceptat prin plasarea funciei
care apeleaz destructorul ntr-un bloc try nsoit de un catch adaptat excepiei.

Procesarea excepiilor care apar la apelul operatorului new


Exist mai multe metode prin care se pot trata excepiile care apar la alocarea
dinamic a memoriei. n unele exemple din cursurile anterioare am folosit macroul
assert pentru a testa valoarea returnat de new. Acesta nu este, ns, un mecanism
robust pentru c nu permite continuarea programului dup apariia excepiei. C++
standard arat c atunci cand apare o eroare la apelul lui new, acesta genereaz o
excepie de tip bad_alloc definit n fiierul header <new>. Unele compilatoare pot
s nu fie compatibile cu C++ standard i atunci trebuie folosit versiunea lui new care
returneaz valoarea 0 n caz de excepie, ca n exemplul urmtor. Al doilea i al
treilea exemplu din acest paragraf vor arta cum se folosete varianta oferit de C++
standard.
Exemplu
test_new.h
#include <iostream>
using std::cout;
int main()
{
double *ptr[50];
for(int i = 0; i < 50; i++)
{
ptr[i] = new double[50000000];
8

Programarea calculatoarelor i limbaje de programare I

if(ptr[i]
{
cout <<
<<
break;
}
else
cout <<
<<

== 0)
"Alocarea memoriei nu a fost posibila pentru ptr["
i << "]\n";

"S-au alocat 50000000 locatii double in ptr["


i << "]\n";

}
return 0;
}
Rulnd acest program putem obine, n funcie de calculator i de compilatorul
instalat, urmtorul rezultat:
S-au alocat 50000000 locatii double in ptr[0]
S-au alocat 50000000 locatii double in ptr[1]
S-au alocat 50000000 locatii double in ptr[2]
Alocarea memoriei nu a fost posibila pentru ptr[3]
Bucla for ar trebui s repete de 50 de ori operaia de alocare dinamic a 50000000
de locaii de memorie de tip double. Dac la un moment dat memoria devine
insuficient, operatorul new nu mai poate realiza corect alocarea memoriei i
returneaz valoarea 0. n acest caz se tiprete mesajul de pe ramura then:
Alocarea memoriei nu a fost posibila i bucla se ncheie.
Exemplul urmtor demonstreaz modul n care se poate trata excepia
bad_alloc la imposibilitatea alocrii memoriei prin operatorul new.
Exemplu
test_bad_alloc.h
#include <iostream>
using std::cout;
using std::endl;
#include <new>
using std::bad_alloc;
int main()
{
double *ptr[50];
try
{
for(int i = 0; i < 50; i++)
{
ptr[i] = new double[50000000];
cout << "S-au alocat 50000000 locatii double in ptr["
<< i << "]\n";
}
}

Programarea calculatoarelor i limbaje de programare I

catch(bad_alloc e)
{
cout << "A aparut urmatoarea exceptie:
<< e.what() << endl;
}

"

return 0;
}
Rulnd acest program putem obine, n funcie de calculator i de compilatorul
instalat, urmtorul rezultat:
S-au alocat 50000000 locatii double in ptr[0]
S-au alocat 50000000 locatii double in ptr[1]
S-au alocat 50000000 locatii double in ptr[2]
A aparut urmatoarea exceptie: Allocation Failure
Atunci cnd alocarea dinamic nu mai este posibil, n blocul catch se tiprete
mesajul A aparut urmatoarea exceptie urmat de descrierea excepiei aa
cum este ea generat de compilator. Acest mesaj poate s difere de la un compilator
la altul.
Este posibil modificarea metodei standard prin care compilatorul trateaz
eroarea de nealocare a memoriei. Funcia set_new_handler definit de C++
standard n header-ul <new> primete ca argument implicit un pointer la o funcie
fr niciun argument i care returneaz void. Programatorul poate nregistra
aceast funcie ca fiind cea care se apeleaz la apariia erorii la alocarea memoriei
printr-un apel al lui set_new_handler. Odat nregistrat noua funcie, operatorul
new nu va mai genera excepia bad_alloc, ci va executa corpul noii funcii.
Exemplu
test_set_new_handler.h
#include <iostream>
using std::cout;
using std::cerr;
#include <new>
#include <cstdlib>
using std::set_new_handler;
void customNewHandler()
{
cerr << "A fost apelata functia customNewHandler";
abort();
}
int main()
{
double *ptr[50];
//Inregistrarea functiei customNewHandler care se apeleaza

10

Programarea calculatoarelor i limbaje de programare I

//la aparitia erorii de alocare a memoriei


set_new_handler(customNewHandler);
for(int i = 0; i < 50; i++)
{
ptr[i] = new double[50000000];
cout << "S-au alocat 50000000 locatii double in ptr["
<< i << "]\n";
}
return 0;
}
Rulnd acest program putem obine, n funcie de calculator i de compilatorul
instalat, urmtorul rezultat:
S-au alocat 50000000 locatii double in ptr[0]
S-au alocat 50000000 locatii double in ptr[1]
S-au alocat 50000000 locatii double in ptr[2]
A fost apelata functia customNewHandler

Clasa auto_ptr i alocarea dinamic a memoriei


Alocarea dinamic a memoriei, asignarea adresei acestei zone de memorie
unui pointer, manipularea acelei zone de memorie prin intermediul pointerului i
dealocarea memoriei sunt operaii uzuale n programarea C++. O excepie care
apare dup alocarea memoriei i nainte de apelul operatorului delete pentru
dealocarea memoriei poate conduce la imposibilitatea dealocrii memoriei pn la
terminarea execuiei aplicaiei. C++ standard ofer clasa auto_ptr n header-ul
<memory> care trateaz astfel de situaii.
Un obiect din clasa auto_ptr menine un pointer la zona de memorie alocat
dinamic. Atunci cnd un obiect auto_ptr iese din domeniul su de definiie (scope),
se apeleaz automat operatorul delete pentru pointerul spre care pointeaz.
Clasa auto_ptr este un template i dispunde de operatorii * i ->, obiectele
sale putnd fi folosite ca variabilele pointer obinuite.
Programul de mai jos demonstreaz folosirea lui auto_ptr pentru obiecte din
clasa Integer definit tot n acest program.
Exemplu
test_auto_ptr.h
#include <iostream>
using std::cout;
using std::endl;
#include <memory>
using std::auto_ptr;
class Integer
{
public:
Integer(int i = 0) : value(i)
{cout << "Constructor pentru Integer: " << value << endl;}
~Integer()
{cout << "Destructor pentru Integer: " << value << endl;}

11

Programarea calculatoarelor i limbaje de programare I

void setInteger(int i) {value = i;}


int getInteger() {return value;}
private:
int value;
};
int main()
{
cout << "Crearea unui obiect auto_ptr catre un Integer\n";
auto_ptr<Integer> ptrToInteger(new Integer(7));
cout << "Folosirea lui auto_ptr pentru manipularea "
<< "obiectului Integer\n";
ptrToInteger->setInteger(99);
cout << "Intregul dupa setInteger: "
<< (*ptrToInteger).getInteger()
<< "\nTerminarea programului" << endl;
return 0;
}
Rulnd acest program obinem urmtorul rezultat:
Crearea unui obiect auto_ptr catre un Integer
Constructor pentru Integer: 7
Folosirea lui auto_ptr pentru manipularea obiectului Integer
Intregul dupa setInteger: 99
Terminarea programului
Destructor pentru Integer: 99
Prin instruciunea
auto_ptr<Integer> ptrToInteger(new Integer(7));
se creeaz obiectul ptrToInteger de tip auto_ptr<Integer> iniializat cu un
pointer la un obiect de tip Integer alocat dinamic i iniializat cu valoarea 7.
Instruciunea
ptrToInteger->setInteger(99);
folosete operatorul -> din auto_ptr pentru apelul funciei setInteger din clasa
Integer, iar instruciunea
(*ptrToInteger).getInteger()
folosete operatorul * din auto_ptr pentru a dereferenia ptrToInteger i a da
posiblitatea folosirii operatorului . n apelul funciei getInteger din clasa Integer.
Obiectul ptrToInteger este o variabil automatic n funcia main, de aceea
el va fi distrus la terminarea programului, apelnd automat destructorul clasei
Integer.
Prin acest comportament al clasei auto_ptr se pot preveni problemele care
pot aprea la imposibilitatea dealocrii memoriei (memory leaks). Aceast clas mai
este referit i prin sintagma smart pointer.

12

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

  • OrCAD Capture
    OrCAD Capture
    Document8 pagini
    OrCAD Capture
    AlexandruDîrlău
    Încă nu există evaluări
  • Dioda Zener
    Dioda Zener
    Document5 pagini
    Dioda Zener
    Marian Baciu
    Încă nu există evaluări
  • 11 Autocorelatie
    11 Autocorelatie
    Document24 pagini
    11 Autocorelatie
    Ştefan Pruteanu
    Încă nu există evaluări
  • LASD1v8 PDF
    LASD1v8 PDF
    Document403 pagini
    LASD1v8 PDF
    AlexandruDîrlău
    Încă nu există evaluări
  • PCLP2 Capitolul9
    PCLP2 Capitolul9
    Document13 pagini
    PCLP2 Capitolul9
    AlexandruDîrlău
    Încă nu există evaluări
  • Subcircuite Spice
    Subcircuite Spice
    Document4 pagini
    Subcircuite Spice
    AlexandruDîrlău
    Încă nu există evaluări
  • PCLP2 Capitolul7
    PCLP2 Capitolul7
    Document11 pagini
    PCLP2 Capitolul7
    AlexandruDîrlău
    Încă nu există evaluări
  • PCLP2 Capitolul4
    PCLP2 Capitolul4
    Document14 pagini
    PCLP2 Capitolul4
    AlexandruDîrlău
    Încă nu există evaluări
  • Cap6 AOC Memoria
    Cap6 AOC Memoria
    Document40 pagini
    Cap6 AOC Memoria
    Florescu Gabriel
    Încă nu există evaluări
  • PCLP2 Capitolul6
    PCLP2 Capitolul6
    Document12 pagini
    PCLP2 Capitolul6
    AlexandruDîrlău
    Încă nu există evaluări
  • PCLP2 Capitolul3
    PCLP2 Capitolul3
    Document19 pagini
    PCLP2 Capitolul3
    AlexandruDîrlău
    Încă nu există evaluări
  • PCLP2 Capitolul2
    PCLP2 Capitolul2
    Document11 pagini
    PCLP2 Capitolul2
    Ady Sin
    Încă nu există evaluări
  • PCLP2 Capitolul4
    PCLP2 Capitolul4
    Document14 pagini
    PCLP2 Capitolul4
    AlexandruDîrlău
    Încă nu există evaluări
  • PCLP2 Capitolul5
    PCLP2 Capitolul5
    Document12 pagini
    PCLP2 Capitolul5
    AlexandruDîrlău
    Încă nu există evaluări
  • PCLP2 Capitolul5
    PCLP2 Capitolul5
    Document12 pagini
    PCLP2 Capitolul5
    AlexandruDîrlău
    Încă nu există evaluări
  • PCLP2 Capitolul2
    PCLP2 Capitolul2
    Document11 pagini
    PCLP2 Capitolul2
    Ady Sin
    Încă nu există evaluări
  • PCLP2 Capitolul3
    PCLP2 Capitolul3
    Document19 pagini
    PCLP2 Capitolul3
    AlexandruDîrlău
    Încă nu există evaluări
  • Matrice C++
    Matrice C++
    Document2 pagini
    Matrice C++
    AlexandruDîrlău
    Încă nu există evaluări
  • PCLP2 Capitolul1
    PCLP2 Capitolul1
    Document13 pagini
    PCLP2 Capitolul1
    Emanuel Emy Gavrilă
    Încă nu există evaluări
  • 2014 2015 PCLP1 - Tema2 PDF
    2014 2015 PCLP1 - Tema2 PDF
    Document2 pagini
    2014 2015 PCLP1 - Tema2 PDF
    AlexandruDîrlău
    Încă nu există evaluări
  • Laborator 4
    Laborator 4
    Document11 pagini
    Laborator 4
    Cosmin Telescu
    Încă nu există evaluări
  • Laborator 4
    Laborator 4
    Document11 pagini
    Laborator 4
    Cosmin Telescu
    Încă nu există evaluări
  • Memoria Interna
    Memoria Interna
    Document12 pagini
    Memoria Interna
    mirelairimia
    Încă nu există evaluări
  • Matrice C++
    Matrice C++
    Document2 pagini
    Matrice C++
    AlexandruDîrlău
    Încă nu există evaluări
  • Cap6 AOC Memoria
    Cap6 AOC Memoria
    Document40 pagini
    Cap6 AOC Memoria
    Florescu Gabriel
    Încă nu există evaluări
  • Cap6 AOC Memoria
    Cap6 AOC Memoria
    Document40 pagini
    Cap6 AOC Memoria
    Florescu Gabriel
    Încă nu există evaluări
  • Matrice C++
    Matrice C++
    Document2 pagini
    Matrice C++
    AlexandruDîrlău
    Încă nu există evaluări
  • T2 DeCo Dec 2014 PDF
    T2 DeCo Dec 2014 PDF
    Document11 pagini
    T2 DeCo Dec 2014 PDF
    AlexandruDîrlău
    Încă nu există evaluări
  • T6 DeCo Dec 2014
    T6 DeCo Dec 2014
    Document9 pagini
    T6 DeCo Dec 2014
    AlexandruDîrlău
    Încă nu există evaluări