Sunteți pe pagina 1din 32

1

Concepte de baz ale limbajului C++

Modalitile (tehnicile, paradigmele) de programare au evoluat de-a lungul


anilor, reflectnd trecerea de la programe de dimensiuni reduse, la programe i
aplicaii de dimensiuni foarte mari, pentru coordonarea crora 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 aplicaii.
Situaiile reale i experiene ale psihologilor au relevat limitele capacitii
umane n perceperea sistemelor complexe, adic imposibilitatea unei persoane de a
percepe i controla simultan un numr mare de entiti de informaie. De aceea, este
esenial descompunerea i organizarea sistemelor complexe, pentru a fi percepute,
proiectate sau conduse. n sistemele complexe, ordinea este introdus n general printro organizare ierarhic, pe mai multe tipuri i nivele de ierarhie. n organizarea
ierarhic a sistemelor complexe se evideniaz dou tipuri de ierarhii: ierarhia de
agregare sau structural i ierarhia de tip.
n ierarhia de agregare se poate afirma despre un obiect c este o parte a altui
obiect, mai complex. Exemple de astfel de descompuneri se pot da din orice domeniu.
De exemplu, un calculator poate fi studiat prin descompunerea lui n subansamble
componente: placa de baz, placa video, monitor, etc; la rndul ei, placa de baz este
compus din placheta de circuit imprimat, procesor, memorie, etc. Acest fel de
ierarhie poate fi exprimat printr-o afirmaie de genul este o parte din.
Pe de alt parte, fiecare obiect poate fi ncadrat ntr-o categorie (clas, tip) mai
larg, care conine mai multe obiecte cu proprieti comune. De exemplu, procesorul
este o component electronic; monitorul este un dispozitiv de afiare, etc. Aceast
ierarhie se refer la apartenena obiectelor la o anumit clas (sau tip - este de
tipul).
Este esenial s privim sistemele complexe din ambele perspective, studiindule att din perspectiva ierarhiei de agregare, deci a obiectelor care le compun, ct i a
ierarhiei de tip, deci a claselor crora le aparin obiectele componente. La rndul lor,
clasele din care fac parte obiectele pot fi organizate sau studiate ca elemente
componente ale unei ierarhii, prin care o clas este considerat ca primitiv (printe) a
unei alte clase. Cele dou tipuri de ierarhii, ierarhia de agregare (structural) i ierarhia

Elemente de Programare Orientat pe Obiecte

de clase (de tip) nu sunt independente, i, mpreun, pot s reprezinte un sistem


complex.
La fel ca oricare sistem complex, software-ul poate fi controlat prin
descompunerea lui. Rolul descompunerii unui sistem n general (i al programelor n
special) este de a permite nelegerea i manevrarea acestuia: sistemul este descompus
n pri din ce n ce mai mici, fiecare dintre ele putnd fi rafinat i dezvoltat
independent. Principiul divide-et-impera, care se aplic n multe situaii, este util i
n programare. Se pot identifica dou metode de descompunere a programelor:
descompunerea algoritmic i descompunerea orientat pe obiecte.
Descompunerea algoritmic permite abordarea structurat a programrii.
Programul este mprit n module, n funcie de aciunile pe care trebuie s le
efectueze, fiecare modul se mparte n elemente funcionale (blocuri, proceduri,
funcii), ntr-o structurare de sus n jos (top-down), care urmrete diagrama de trecere
a datelor n cursul execuiei.
Descompunerea orientat pe obiecte este o alternativ de descompunere n
care programul se mparte dup obiectele care pot fi identificate, fiecare obiect avnd
asociate o mulime de operaii care sunt apelate n cursul execuiei.
O problem nu poate fi abordat simultan prin ambele metode. Care dintre ele
este cea mai bun? Nu exist un rspuns absolut i universal valabil, dar experiena a
dovedit c pentru sisteme de dimensiuni mari, descompunerea orientat pe obiecte este
mai eficient, mai sigur i mai flexibil.

1.1

Tehnici de programare

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


descompunerii programelor, definete mai multe tehnici de programare (paradigme),
care s-au dezvoltat i au evoluat odat cu evoluia 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 (funcii) care sunt apelate n ordinea de
desfurare a algoritmului. Limbajele care suport aceast tehnic de programare
prevd posibiliti de transfer a argumentelor ctre funcii 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 invenii n acest domeniu.
Programarea modular. n cursul evoluiei programrii procedurale,
accentul n proiectarea programelor s-a deplasat de la proiectarea procedurilor ctre
organizarea datelor, aceast deplasare reflectnd creterea dimensiunilor programelor.
O mulime de proceduri corelate, mpreun cu datele pe care le manevreaz, sunt
organizate ca un modul. Tehnica de programare modular decide descompunerea unui
program n module, care ncorporeaz o parte din datele programului i funciile care
le manevreaz. Aceast tehnic este cunoscut ca tehnic de ascundere a datelor (datahiding). n programarea modular stilul de programare este n continuare procedural,
iar datele i procedurile sunt grupate n module, existnd posibilitatea de ascundere a

1. Concepte de baz ale limbajului C++

unor informaii definite ntr-un modul, fa de celelalte module. Gruparea de date i


proceduri n module nu implic i o asociere strict ntre acestea.
Modularitatea i ascunderea informaiilor sunt caracteristici implicite n
programarea orientat pe obiecte.
Programarea orientat pe obiecte reprezint aplicarea n domeniul
programrii a unei metode larg rspndite n tehnic, numit tehnologia orientat pe
obiecte, care se bazeaz pe modelul obiect. Modelul obiect al unei aplicaii implic
patru principii importante i anume:
abstractizare;
ncapsulare;
modularitate;
ierarhizare.
n afara acestor principii, modelul obiect mai presupune: tipizare, concuren
i persisten. Aproape nici unul dintre aceste principii nu este nou, dar utilizarea lor
mpreun n modelul obiect, are un rol sinergetic, de potenare reciproc.
Primele aplicaii ale acestor principii au fost introduse n limbajul Simula, care
a stat la baza dezvoltrii ulterioare i a altor limbaje care permit abordarea modelului
obiect: Smaltalk, Object Pascal, C++, Clos, Ada, Eiffel.
n momentul de fa modelul obiect se dovedete a fi un concept unificator n
tiina calculatoarelor n general, fiind aplicabil nu numai n programare, ci i n
arhitectura calculatoarelor, n proiecatarea interfeelor utilizator, n baze de date.
Programarea orientat pe obiecte (object-oriented programming) este o
metod de programare n care programele sunt organizate ca i colecii de obiecte
cooperante, fiecare dintre ele reprezentnd o instan a unei clase, iar clasele sunt
membre ale unei ierarhii de clase, corelate ntre ele prin relaii de motenire.
Exist trei pri importante ale acestei definiii:
Se folosesc obiecte, nu algoritmi, ca uniti constructive de baz, obiectele
fiind componente ale unei ierarhii de agregare.
Fiecare obiect este o instan (un exemplar) al unei clase.
Clasele sunt componente ale unei ierarhii de tip (este de tipul), fiind
corelate ntre ele prin relaii de motenire.
Dac lipsete una din aceste caracteristici, programarea nu se mai numete
orientat pe obiecte, ci programare prin abstactizarea datelor, deoarece o clas este un
tip de date abstract.
Un limbaj este considerat un limbaj de programare orientat pe obiecte dac
satisface mai multe cerine, ca de exemplu:
Suport obiecte (instane ale unor clase), clasele fiind tipuri definite de
utilizator (numite i tipuri abstracte de date).
Tipurile (clasele) pot moteni atribute de la alte clase, numite clase de
baz.
Dac un limbaj nu suport direct motenirea ntre clase se numete limbaj de
programare bazat pe obiecte (object-based), cum este, de exemplu, limbajul Ada.

Elemente de Programare Orientat pe Obiecte

Principiile modelului obiect aplicate n programare, enunate mai sus, vor fi


prezentate pe scurt n continuare, detalierea lor fiind reluat n cursul expunerii, dup
descrierea suportului oferit de limbajul C++ fiecreia dintre acestea.
Abstractizarea nseamn identificarea similitudinilor ntre diferite entiti,
situaii sau procese din lumea real, decizia de a se concentra atenia asupra acestor
aspecte comune i ignorarea pentru nceput a detaliilor. Abstractizarea identific
trsturile caracteristice eseniale ale unui obiect, care l deosebesc de toate celelalte
feluri de obiecte.
ncapsularea este procesul de compartimentare a elementelor unei
abstractizri n dou pri: structura i comportarea; ncapsularea separ comportarea
(accesat prin interfa) de structur, definit prin implementare. ncapsularea prevede
granie ntre diferite abstractizri, ceea ce conduce la o separare clar a acestora.
Modularizarea este procesul de partiionare a unui program n componente
individuale (module) ceea ce permite reducerea complexitii programului prin
definirea unor granie bine stabilite i documentate n program. n practica
programrii, modularizarea const n partiionarea programului n module care pot fi
compilate separat, dar care au conexiuni cu alte module ale programului. Modulele
servesc ca i containere n care sunt declarate clasele i obiectele programului.
Ierarhizarea este o modalitate de a ordona abstractizrile (tipurile abstracte de
date). Ierarhiile pot s denote relaii de tip sau relaii de agregare. Relaiile de tip sunt
definite prin motenirile ntre clase, prin care o clas (clasa derivat) motenete
structura sau comportarea definit n alt clas (clasa de baz). Relaiile de agregare
specific compunerea unui obiect din mai multe obiecte mai simple. Agregarea nu este
un concept specific programrii orientate pe obiecte, deoarece i limbajele de
programare procedural prezint suport pentru agregare prin structuri de tip
nregistrare (record n Pascal, struct n C, etc). Combinaia ntre motenire i
agregare reprezint ns un instrument puternic de exprimare a ierarhizrii n
programarea orientat pe obiecte.
Tipizarea. Tipul este o caracterizare precis, structural i comportamental a
unei colecii de entiti. Dei conceptual tipul este similar noiunii de clas, tipizarea se
refer la un aspect diferit al modelului obiect de cel la care se refer clasele. Tipizarea
este o accentuare a clasei unui obiect, astfel nct obiecte de clase diferite nu pot fi
intershimbate ntre ele sau, cel mult, pot fi interschimbate ntr-un mod foarte restrictiv.
Din punct de vedere al tipizrii, exist limbaje puternic tipizate (ca de exemplu,
Eiffel), n care nu este admis nici o operaie asupra unui operand dac aceasta nu a
fost exact prevzut pentru obiectul respectiv. Alte limbaje, cum este Smalltalk, sunt
limbaje netipizate, care admit la compilare orice fel de operaii asupra operanzilor,
eroarea violrii de tip manifestndu-se n timpul execuiei. Limbajul C++ este hibrid.
El are tendina de tipizare puternic, dar este posibil ignorarea sau inhibarea regulilor
de tipizare. Dei nu face parte din principiile fundamentale ale modelului obiect,
tipizarea aduce beneficii importante n programarea orientat pe obiecte.
Concurena permite ca mai multe obiecte diferite s fie n execuie n acelai
timp. Sistemele care implic concurena sunt sisteme cu procesoare multiple, n care
mai multe procese sau thread-uri (fire de execuie) pot fi executate concurent pe
procesoare diferite.

1. Concepte de baz ale limbajului C++

Persistena. Un obiect n software ocup un anumit spaiu n memorie i are o


existen ntr-o perioad determinat de timp n cursul execuiei programului. De
multe ori este necesar ca datele s supravieuiasc programului (exemplul tipic fiind
bazele de date), iar definirea de ctre fiecare programator a modului cum sunt salvate
datele pentru a fi pstrate dup terminarea programului poate conduce ctre scheme de
memorare dintre cele mai diferite i greu interschimbabile. Prin conceptul de
persisten se introduce un mod unitar de salvare i restaurare a datelor coninute de
obiecte ale programului.
Modelul obiect n domeniul programrii implic, pe lng implementarea
programului ntr-un limbaj anume, etape premergtoare de analiz i proiectare care
pregtesc structurarea efectiv a programului.
Analiza orientat pe obiecte este o metod de analiz i examinare a unei
aplicaii din perspectiva claselor i a obiectelor din domeniul problemei respective.
Proiectarea orientat pe obiecte este o metod de proiectare a sistemelor care
implic descompunerea orientat pe obiecte i asigur o modalitate de reprezentare
att static ct i dinamic a modelului sistemului proiectat.
Produsele analizei orientate pe obiecte servesc ca modele ale proiectrii
orientate pe obiecte, iar rezultatele acesteia folosesc direct n programare. Ca suport
pentru crearea modelului final al unei aplicaii, programarea i limbajele orientate pe
obiecte se recomand a fi studiate mai nti, pentru a beneficia de toate facilitile i
tehnicile oferite de acestea analitilor, proiectanilor i programatorilor.
Limbajul C++ este unul dintre cele mai utilizate limbaje de programare
orientate pe obiecte; compilatoare, biblioteci i instrumente de dezvoltare a
programelor C++ sunt disponibile att pentru calculatoare personale ct i pentru cele
mai dezvoltate sisteme i staii de lucru.
Limbajul C++ este o versiune extins a limbajului C, extensiile acestuia fiind
elaborate de ctre B. Stroustrup n anul 1980 n laboratoarele Bell din Murray Hill,
New Jersey. Extensiile dezvoltate de Stroustrup pentru limbajul C++ permit
programarea orientat pe obiecte, pstrnd eficiena, flexibilitatea i concepia de baz
a limbajului C. Numele iniial a fost C cu clase, numele de C++ fiindu-i atribuit n
anul 1983.
Scopul pentru care a fost creat C++ este acelai cu scopul pentru care este
abordat n general programarea orientat pe obiecte: dezvoltarea i administrarea
programelor foarte mari. Chiar dac superioritatea limbajului C++ este evident n
cazul dezvoltrii programelor foarte mari, nu exist limitri n a fi folosit n orice fel
de aplicaie, deoarece C++ este un limbaj tot att de eficient ca i limbajul C.
De la apariia sa, C++ a trecut prin trei revizii, n 1985, 1989 i ultima,
prilejuit de definirea standardului ANSI pentru acest limbaj. O prim versiune a
standardului a fost publicat n anul 1994, iar urmtoarea versiune este nc n lucru.
n general, limbajul C++ prevede mai multe faciliti i mai puine restricii
dect limbajul C, astfel nct majoritatea construciilor din C sunt legale i au aceeai
semnificaie i n C++.

Elemente de Programare Orientat pe Obiecte

n acest capitol sunt prezentate unitar i concis conceptele de baz n


programarea C++, att cele care sunt preluate din limbajul C ct i cele nou introduse.
Multe dintre ele sunt reluate i dezvoltate pe parcursul seciunilor urmtoare.
Cel mai scurt program C++ este:
main(){ }

Acesta definete o funcie numit main (), care nu primete nici un


argument, nu execut nimic i nu returneaz nici o valoare.
Dac se dorete ca programul s scrie un mesaj la consol (de tipul Hello,
World!), pe lng utilizarea funciei obinuite din limbajul C (funcia printf()),
n C++ se poate utiliza i o funcie de scriere la ieirea standard (cout). Aceast
funcie este funcia operator de scriere << care este definit n fiierul antet
iostream.h. Un astfel de program este urmtorul:
#include <iostream.h>
void main(){
cout << Hello, World!<< endl;
}

Prima operaie de scriere afieaz la consol irul Hello, World!, iar


urmtoarea (endl) introduce caracterul de linie nou. Operaia de citire de la tastatur
poate fi realizat n C++ printr-o instruciune care folosete funcia operator de citire
>>. De exemplu, n instruciunile care urmeaz se citete de la tastatur un numr
ntreg:
int i;
cin >> i;

Desigur, funcia scanf() de citire de la tastatur din limbajul C poate fi n


continuare folosit, dar pe parcursul exemplificrilor se vor folosi mai mult aceste
funcii C++ de citire i de scriere la consol. Descrierea detaliat a operaiilor de
intrare-ieire din C++ se gsete n seciunea 6.
Un program C++ const dintr-unul sau mai multe fiiere (files). Un fiier este
o bucat de text care conine cod surs C++ i comenzi de preprocesare i este
translatat din punct de vedere conceptual n mai multe faze. Prima faz este faza de
preprocesare care execut includerea altor fiiere i substituirea macrourilor.
Preprocesarea este controlat prin intermediul directivelor introduse prin linii care au
primul caracter #. Rezultatul preprocesrii este secvena de entiti (token semne). O
astfel de secven de entiti, adic fiierul rezultat dup preprocesare, se numete
unitate de translatare (translation unit).

1. Concepte de baz ale limbajului C++

1.2

Convenii lexicale

Exist cinci tipuri de entiti: identificatori (identifiers), cuvinte-cheie


(keywords), literale (literals), operatori (operators) i separatori (separators).
Caracterele: spaiu (blank), tabulatori orizontali i verticali (tabs), linie nou (new
line), caractere de formatare (formfeeds) i comentariile, numite n ansamblu spaii
albe (white spaces) sunt ignorate, cu excepia situaiei cnd folosesc pentru separarea
entitilor. Un spaiu alb este necesar pentru separarea identificatorilor, a cuvintelorcheie i a constantelor.
Comentariile din C, considerate ntre perechile de caractere /* i */ sunt
valabile la fel, fr posibilitatea de a fi incluse unele n altele (imbricate). Caracterele
// marcheaz nceputul unui comentariu care dureaz pn la sfritul liniei.
Identificatori. Un identificator este o secven de lungime oarecare de litere
i cifre, cu condiia ca primul caracter s fie liter sau caracterul de subliniere _
(underscore). Literele mici sunt diferite de literele mari corespunztoare. Toate
caracterele ntr-un identificator sunt semnificative.
Cuvinte-cheie. Urmtorii identificatori sunt rezervai pentru a fi utilizai ca i
cuvinte-cheie, i nu pot avea alt utilizare:
asm
auto
break
case
catch
char
class
const

continue
default
delete
do
double
else
enum
extern

float
for
friend
goto
if
inline
int
long

new
operator
private
protected
public
register
return
short

signed
sizeof
static
struct
switch
template
this
throw

try
typedef
union
unsigned
virtual
void
volatile
while

n plus, identificatori care conin dou caractere de subliniere (underscore) sau


ncep cu un astfel de caracter sunt utilizai n implementrile compilatoarelor C++ i
ale bibliotecilor i se recomand s fie evitai.
Literale (constante). Constantele se refer la valori fixe, pe care programul
nu le poate modifica. Exist mai multe feluri de constante: constante ntregi, constante
caracter, constante reale i constante ir de caractere.
O constant ntreg este reprezentat ca o succesiune de cifre; ea este
considerat n baz zecimal dac prima cifr este diferit de 0, n baza hexazecimal
dac ncepe cu 0x sau 0X, sau n baz octal, dac ncepe cu 0 (i acesta nu este urmat
de x sau X). Tipul unei constante ntregi depinde de valoarea acesteia i este astfel
stabilit nct s poat cuprinde valoarea dat.
O constant caracter este compus din unul sau mai multe caractere cuprinse
ntre ghilimele simple (de exemplu, x). O constant de un singur caracter este de
tipul char. Constantele multicaracter au tipul ntreg. Trebuie remarcat diferena fa
de limbajul C, n care constantele caracter au tipul int.

Elemente de Programare Orientat pe Obiecte

O constant real (cu virgul flotant) este alctuit dintr-o parte ntreag,
punctul zecimal, o parte fracionar i opional, un exponent ntreg cu semn precedat
de caracterul e sau E. Pot lipsi partea ntreag sau partea fracionar, dar nu
amndou. Tipul constantei flotante este double, dac nu conine un sufix care s
specifice explicit tipul (f sau F, pentru float; l sau L pentru long double).
O constant ir de caractere este o secven de caractere cuprins ntre
ghilimele duble i este de tipul vector de caractere. O constant ir de caractere are
clasa de memorare static i se iniializeaz cu caracterele date, la care se adaug
caracterul \0 (care are valoarea zero).
Este de asemenea posibil s fie definite constante simbolice (constante cu
nume). Acestea sunt prezentate n subseciunea urmtoare.

1.3

Declaraii, definiii

Un nume (name) poate reprezenta un obiect, un tip, o enumeraie, o funcie, o


mulime de funcii, un membru al unei clase, o valoare sau o etichet. Un nume este
introdus n program printr-o declaraie (declaration). Un nume poate fi folosit numai
ntr-o zon a programului, denumit domeniul numelui (scope).
Un obiect (object) este o regiune de memorie, iar semnificaia valorilor care
se afl memorate ntr-un obiect depind de tipul lui. Orice obiect are o durat de via
(lifetime) care depinde de clasa de memorare creia i aparine.
O declaraie (declaration) introduce unul sau mai multe nume ntr-un
program. ntr-o declaraie a unui nume se poate introduce, opional, o expresie de
iniializare (iniializator) pentru acel nume (de exemplu: int i = 1;)
O definiie (definition) stabilete entitatea la care se refer numele respectiv.
Ea rezerv cantitatea necesar de memorie obiectului respectiv i execut iniializrile
corespunztoare. O declaraie este i o definiie, cu excepia urmtoarelor situaii:
conine specificatorul extern fr o expresie de iniializare sau corp al
funciei;
este o declaraie a unei funcii fr specificarea corpului acesteia;
este o declaraie a numelui unei clase;
este o declaraie typedef;
este o declaraie a unui membru de tip static al unei clase.
De exemplu, urmtoarele sunt definiii:
int a;
extern const c = 1;
int f(int x) {return x+1;}
enum {up, down};

n timp ce urmtoarele sunt doar declaraii:


extern int a;
extern const c;
int f(int);

1. Concepte de baz ale limbajului C++

struct S;
typedef int Int;

Trebuie s existe o singur definiie a fiecrui obiect, funcie, clas sau


enumeraie folosit n program. Dac o funcie nu este niciodat apelat sau dac
numele unei clase nu este niciodat folosit ntr-un mod care s necesite definiia
acesteia, ele pot s nu fie definite. O declaraie poate fi repetat de mai multe ori n
program, n timp ce definiiile nu pot fi repetate. De exemplu:
struct S;
struct S;
int a;
int a;

//
//
//
//

corect,
corect,
corect,
eroare,

redeclarare
redeclarare
definiie
redefinire

Domeniul de definiie (scope) al unui nume este zona din program n care
numele este cunoscut i poate fi folosit. Dat fiind c un nume este fcut cunoscut
printr-o declaraie, domeniile numelor se difereniaz n funcie de locul n care este
introdus declaraia n program. Exist patru categorii de domenii: local, funcie, clas
i fiier.
Domeniul local: un nume declarat ntr-un bloc (o secven de instruciuni
cuprins ntre dou acolade) este local blocului i poate fi folosit numai n acel bloc,
ncepnd din locul declaraiei i pn la sfritul blocului i n toate blocurile incluse
dup punctul de declaraie. Argumentele formale ale unei funcii sunt tratate ca i cnd
ar fi declarate n blocul exterior al funciei respective.
Domeniul funcie: un nume declarat ntr-o funcie poate fi folosit n funcia
respectiv, ncepnd din punctul de declaraie i pn la sfritul blocului n care se
afl declaraia. Domeniul funcie poate fi considerat un caz particular de domeniu
local.
Domeniul clas: Un nume al unui membru al unei clase este local clasei
respective. Posibilitile de utilizare al acestor tipuri de nume vor fi prezentate ulterior.
Domeniul fiier: Un nume declarat n afara oricrui bloc sau clas are ca
domeniu fiierul n care a fost declarat i poate fi utilizat din punctul declaraiei pn
la sfritul fiierului. Numele cu domeniu fiier se numesc nume globale.
Domeniul de vizibilitate. Un nume este vizibil n ntregul su domeniu de
definiie dac nu este redefinit ntr-un bloc inclus n domeniul respectiv. Dac ntr-un
bloc interior domeniului unui nume se redefinete (sau se redeclar) acelai nume,
atunci numele iniial (din blocul exterior) este parial ascuns, i anume n tot domeniul
redeclarrii. De exemplu:
void fv1(){
int i = 10;
// definitie variabila i
{
// in acest bloc variabila i din blocul exterior
// este ascunsa datorit redefinirii
int i = 100;
cout << i << endl; // afiseaza 100
}
cout << i << endl;
// afiseaza 10
}

Elemente de Programare Orientat pe Obiecte

10

Un nume cu domeniu fiier poate fi accesat ntr-un domeniu n care este


ascuns prin redefinire, dac se folosete operatorul de rezoluie pentru nume globale
(operatorul :: fr nici un nume n faa lui).
Redefinirea unui nume este admis numai n domenii diferite. Dac unul din
domenii este inclus n cellalt domeniu, atunci redefinirea provoac ascunderea
numelui din domeniul exterior n domeniul interior. Redefinirea n domenii identice
produce eroare de compilare.
Durata de via a obiectelor. Un obiect este creat atunci cnd se ntlnete
definiia lui (care este unic) i este distrus (n mod automat) atunci cnd se prsete
domeniul lui de definiie. Un obiect cu un nume global se creeaz i se iniializeaz o
singur dat i are durata de via pn la terminarea programului. Obiectele locale se
creeaz de fiecare dat cnd execuia programului ajunge n punctul de definire a
acestora, cu excepia variabilelor locale declarate de tip static.
O variabil (obiect) se declar de tip static prin prefixarea declaraiei
acesteia cu cuvntul-cheie static. De exemplu, execuia programului:
#include <iostream.h>
int a = 0;
//variabila globala se initializeaza
// inainte de nceperea executiei
void f(){
int b = 1;
// se creaza si se initializeaza
// la fiecare apel al functiei f()
a++; b++;
static int c = a; //se initializeaza o singura data
//la prima executie a instruct.
c += 2;
cout << a = <<a << b = << b<< c = << c <<endl;
}
void main (){
for (int i=0;i<3;i++)
f();
}

produce mesajele:
a = 1
a = 2
a = 3

b
b
b

= 2
= 2
= 2

c = 3
c = 5
c = 7

O variabil (obiect) global sau static, care nu este iniializat explicit, este
iniializat automat cu 0. n afara acestui mod de creare a obiectelor, se mai pot crea
obiecte n memoria liber (heap), a cror durat de via este controlat explicit
folosind funcii sau operatori de alocare. Acest mod de creare a obiectelor este
prezentat n subseciunea 2.4.
Categorii de memorare. Exist patru specificatori de categorii de memorare
a obiectelor: auto, static, register, extern.

1. Concepte de baz ale limbajului C++

11

Obiectele care sunt declarate automatice (folosind specificatorul auto la


nceputul declaraiei) sunt obiecte locale (declarate ntr-un bloc) care se iniializeaz la
fiecare invocare a blocului. Utilizarea acestui specificator este redundant i rareori
este folosit.
O declaraie register este o declaraie auto care mai indic n plus
compilatorului c acel obiect este intens folosit i, ca urmare, compilatorul va ncerca
s-i aloce spaiu de memorare ntr-un registru al procesorului.
Un obiect global poate fi declarat o singur dat ntr-unul din fiierele
programului. Pentru a fi cunoscut i n alte fiiere din program, n celelate fiiere se
declar acel obiect folosind specificatorul extern.
Un obiect declarat folosind specificatorul static este memorat permanent i
nu este iniializat dect o singur dat. Un astfel de obiect nu este cunoscut dect n
interiorul fiierului sau funciei n care este declarat i nu poate fi declarat extern.
Se pot remarca cele dou semnificaii ale specificatorului static: o semnificaie se
refer la domeniul de vizibilitate, pe care l restrnge la nivel de funcie, respectiv
fiier; cealalt semnificaie se refer la clasa de memorare i asigur o memorare
permanent a obiectului i o durat de via egal cu durata de execuie a programului.
Aceast dubl aciune a specificatorului static difereniaz
comportamentul unui obiect declarat static dup domeniul lui de definiie.
Astfel, un obiect global de tip static este memorat permanent, dar este
cunoscut numai n fiierul n care a fost declarat. n aceast situaie, specificatorul
static are doar rolul de a restrnge domeniul de vizibilitate al obiectului.
Pentru un obiect local specificatorul static are rolul de a modifica clasa de
memorare: obiectul are domeniu de definiie local (este cunoscut numai n blocul n
care a fost declarat), dar este memorat permanent i i pstreaz valorile ntre invocri
succesive ale blocului respectiv.

1.4

Tipuri

Fiecare nume ntr-un program C++ are un tip asociat lui, care determin ce
operaii se pot aplica entitii la care se refer acest nume.
Un nume folosit pentru a specifica tipul unui alt nume ntr-o declaraie este un
nume de tip. Singurele operaii care se pot aplica unui nume de tip sunt: sizeof,
(care determin cantitatea de memorie necesar memorrii unui obiect de acel tip) i
new (operaia de alocare n memoria liber a unui obiect de tipul respectiv).

1.4.1

Tipuri fundamentale

n C++ sunt definite urmtoarele tipuri fundamentale:

Tipuri de ntreg, pentru definirea numerelor ntregi de diferite dimensiuni


(ca numr de octei ocupai n memorie):

char
short int

1 octet
2 octei

Elemente de Programare Orientat pe Obiecte

12
int
long

2 sau 4 octei
4 sau 8 octei

Tipuri de numere flotante, pentru definirea numerelor reale (reprezentate


ca numere cu virgul flotant):

float
double
long double

4 octei
8 octei
12 sau 16 octei

Aceste tipuri sunt denumite mpreun tipuri aritmetice. Pentru tipurile ntreg,
exist variante de declaraie cu semn (signed) i fr semn (unsigned).

Tipul void specific o mulime vid de valori. Nu se poate declara un


obiect cu acest tip, dar acest tip poate fi utilizat n conversii de pointeri i
ca tip de returnare al unei funcii

1.4.2

Tipuri derivate

Se pot defini conceptual un numr infinit de tipuri derivate pornind de la


tipurile fundamentale. Tipurile derivate sunt:
tablouri de obiecte,
pointeri la obiecte,
referine,
funcii,
constante simbolice,
clase, structuri, uniuni,
pointeri la membrii claselor.
n continuare se vor prezenta primele cinci tipuri derivate, iar celelate vor fi
introduse pe parcursul seciunii urmtoare. Ca terminologie, clasele (mpreun cu
structurile i uniunile) sunt denumite tipuri definite de utilizator (user-defined types),
iar celelate tipuri sunt denumite tipuri predefinite (built-in types)
1.4.2.1 Tablouri de obiecte
Un tablou (array) de obiecte poate fi construit din obiecte dintr-un tip
fundamental (cu excepia tipului void), din pointeri, din enumeraii sau din alte
tablouri. n traducere, pentru array se mai ntlnesc termenii vector i matrice. n acest
text sunt folosii termenii tablou (pentru array multidimensional) i vector (pentru
array unidimensional).
Declaraia: T D[expresie] introduce un tablou de obiecte de tipul T,
cu numele D i cu un numr de elemente al tabloului dat de valoarea expresiei, care
trebuie s fie de tip constant ntreg. Pentru valoarea N a acestei expresii, tabloul are N
elemente, numerotate de la 0 la N-1.
Un tablou bidimensional se poate construi printr-o declaraie de forma:
T D[dim1][dim2];

1. Concepte de baz ale limbajului C++

13

i reprezint dim1 tablouri unidimensionale, fiecare de dimensiune dim2. Elementele


tabloului bidimensional se memoreaz cu valori succesive pentru indicele din dreapta
astfel:
D[0][0], D[0][1], D[0][dim2-1],
D[1][0], D[1][1], D[1][dim2-1],.
D[dim1-1][0], D[dim1-1][1], D[dim1-1][dim2-1].

ntr-un mod asemntor se pot construi tablouri multidimensionale, cu o


limitare a numrului de dimensiuni care depinde de implementare.
1.4.2.2 Pointeri
Pentru majoritatea tipurilor T, T* este un tip denumit pointer la T,
adic o variabil de tipul T* memoreaz adresa unui obiect de tipul T.
Operaia fundamental asupra unui pointer este operaia de derefereniere
(dereferencing), adic accesarea obiectului a crui adres o reprezint pointerul
respectiv. Operatorul de derefereniere este operatorul unar *. De exemplu:
char c1 = a;
char* p1 = &c1;
char c2 = *p1;

// variabila c1
// p memoreaz adresa lui c1
// dereferentiere, c2 = a;

Operatorul & este operatorul adres, care se utilizeaz pentru a obine adresa
unei variabile.
Tipul void* este folosit pentru a indica adresa unui obiect de tip necunoscut.
Asupra pointerilor sunt admise unele operaii aritmetice. De exemplu, se
consider un vector de caractere dintre care ultimul este caracterul 0 (se mai numete
ir de caractere terminat cu nul). Pentru calculul numrului de caractere se pot folosi
operaii cu pointeri astfel:
int strlen(char* p){
int i = 0;
while (*p++) i++;
return i;
}

Funcia strlen() returneaz numrul de caractere ale irului, fr


caracterul terminal 0, folosind operaia de incrementare a pointerului i operaia de
derefereniere pentru a testa valoarea caracterului. O alt implementare posibil a
funciei este urmtoarea:
int strlen(char* p){
char* q = p;
while (*q++);
return q-p-1;
}

Elemente de Programare Orientat pe Obiecte

14

n C++, ca i n limbajul C, pointerii i tablourile sunt puternic corelate. Un


nume al unui tablou poate fi folosit ca un pointer la primul element al tabloului. De
exemplu, se poate scrie:
char alpha[] = abcdef;
char* p = alpha;
char* q = &alpha[0]; // p = q

Rezultatul aplicrii operatorilor aritmetici +, -, ++, -- asupra pointerilor


depinde de tipul obiectului indicat. Atunci cnd se aplic un operator aritmetic unui
pointer p de tip T*, se consider c p indic un element al unui tablou de obiecte de
tip T; p+1 va indica urmtorul element al tabloului, iar p-1 va indica elementul
precedent al tabloului. Acest lucru nseamn c valoarea lui p+1 este cu sizeof(T)
octei mai mare dect valoarea lui p.
Pointeri la funcii vor fi prezentai la paragraful de descriere a funciilor.
Pointerii la membrii nestatici ai claselor nu sunt considerai pointeri la obiecte i vor fi
prezentai n seciunea urmtoare.
1.4.2.3 Referine
O referin (reference) este un nume alternativ al unui obiect. Utilizarea
principal a referinelor se face pentru specificarea argumentelor i a valorilor
returnate de funcii, n general, i pentru suprancrcarea operatorilor n special.
Notaia X& nseamn referin la un obiect de tipul X. De exemplu:
int i = 1;
int& r = i;
int x = r;
r++;

// r i i se refer la aceeai entitate


// x = 1
// i = 2;

Implementarea obinuit a unei referine se face printr-un pointer constant


care este derefereniat de fiecare dat cnd este utilizat.
Aa cum se poate observa, pentru definirea unei referine se folosete
operatorul adres &, dar difer tipul construciei n care este folosit. De exemplu:
int a = 5;
int* pi = &a;
int& r = a;

//
//
//
//

& calculeaz adresa;


pi este adresa lui a
& introduce o referinta;
r este o referin (alt nume) pt. a

O referin este utilizat ca argument pentru o funcie care poate s modifice


valoarea acestui argument. De exemplu:
void incr(int& x) {x++;}
void f(){
int i = 1;
incr(i); // i = 2;
}

1. Concepte de baz ale limbajului C++

15

O alt utilizare important a referinelor este pentru definirea funciilor care


pot fi folosite att ca membru drept ct i ca membru stng al unei expresii de
asignare. De exemplu:
#include <iostream.h>
int& fr(int v[], int i){
return v[i];
}
void main(){
int x[] = {1,2,3,4};
fr(x,2) = 7;
cout <<fr(x,0)<<fr(x,1)<<fr(x,2)<< fr(x,3)<<endl;
}

La execuia acestui program se obine mesajul:


1

Deoarece valoarea returnat de funcie este referina (numele) unui element al


vectorului, acesta poate fi modificat prin folosirea funciei fr() ca membru stng al
egalitii.
1.4.2.4 Funcii
Funciile sunt tipuri derivate i reprezint una din cele mai importante
caracteristici ale limbajelor C i C++. Forma general de definire a unei funcii este:
tip_returnat nume_func(tip1 arg1,tip2 arg2,,tipn argn)
{
//corpul functiei
}

Funcia cu numele nume_func returneaz o valoare de tip tip_returnat


i are un numr n de argumente formale declarate ca tip i nume n lista de argumente
formale. Argumentele formale din declaraia unei funcii se mai numesc i parametrii
funciei. Dac o funcie nu are argumente, atunci lista din parantezele rotunde este
vid. Notaia din C: f(void) este redundant.
O funcie este un nume global, dac nu este declarat de tip static. O
funcie declarat static are domeniul de vizibilitate restrns la fiierul n care a fost
definit.
Corpul funciei este propriu ei i nu poate fi accesat din afara acesteia (nici
printr-o instruciune goto). Corpul unei funcii este o instruciune compus, adic o
succesiune de instruciuni i declaraii incluse ntre acolade. n corpul funciei 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 funciei
i se distrug atunci cnd este prsit blocul n care au fost definite. Nu se pot defini
funcii n interiorul unei funcii. Argumentele formale ale unei funcii sunt considerate
variabile locale ale funciei, ca orice alt variabil definit n funcia respectiv.

Elemente de Programare Orientat pe Obiecte

16

Dac o funcie nu are de returnat nici o valoare, atunci tip_returnat din


declaraia funciei este tipul void i nu este necesar o instruciune de returnare
(return) n funcie. n toate celelalte cazuri, n corpul funciei trebuie s fie
prevzut returnarea unei variabile de tipul tip_returnat, folosind instruciunea
return. Dac n definiie nu este prevzut un tip_returnat, se consider
implicit returnarea unei valori de tip ntreg.
Prototipurile funciilor. Pentru apelul unei funcii este necesar cunoaterea
definiiei sau a prototipului acesteia. Prototipul unei funcii este de forma:
tip_returnat nume_func(tip1 arg1,., tipn argn);

Numele argumentelor formale sunt opionale n prototipul unei funcii. Prototipurile


permit compilatorului s verifice tipurile argumentelor de apel i s semnaleze eroare
la conversii ilegale. Spre deosebire de limbajul C, unde este admis i simpla
declaraie a numelui funciei (fr tipurile argumentelor de apel), utilizarea
prototipurilor este obligatorie n C++. De exemplu:
double f2(int, double);
double f3(int a, double f){
/*..*/
double t = f/a;
return t;

// prototip functie f2
// definitie functie f3

void fp(){
double r1 = f1(7, 8.9);
double r2 = f2(7, 8.9);
char str[] = "abcde";
double r3 = f3(7, str);

// eroare,
// identificator nedeclarat
// corect, fol. prototipul
// eroare de tip argument

double f1(int
/*..*/
double t =
return t;
}
double f2(int
/*...*/
double t =
return t;
}

a, double f) {
a + f;
a, double f) {

// definiie funcie f2()

a*f;

La compilare apare o eroare datorit apelului funciei f1(), care nu este


definit, nici declarat prin prototip n domeniul funciei apelante fp() i o eroare
datorat apelului funciei f3() cu un argument (argumentul al doilea) care nu poate fi
convertit la tipul argumentului formal.
Transferul argumentelor funciilor. La apelul unei funcii, argumentele de
apel (se mai numesc i argumente reale sau efective) iniializeaz argumentele formale

1. Concepte de baz ale limbajului C++

17

din declaraia funciei, n ordinea din declaraie. Argumentele unei funcii se pot
transfera n dou moduri: apelul prin valoare i apelul prin referin.
n apelul prin valoare se copiaz valoarea argumentului real n argumentul
formal corespunztor al funciei. n acest caz, modificrile efectuate asupra
argumentului funciei nu modific argumentul real.
n apelul prin referin este accesat direct variabila din argumentul real
transmis funciei, care poate fi deci modificat. Ca exemplificare, se definete o
funcie swap() care realizeaz intershimbul ntre valorile a dou variabile. Dac nu
se folosesc referine, argumentele de apel ale funciei trebuie s fie pointeri la
variabilele respective. Pointerii, ca argumente de apel, nu vor fi modificai, dar
variabilele indicate de acetia pot fi modificate. Funcia swap() cu argumente
pointeri arat astfel:
void swap(int* x, int* y){
int t;
t = *x;
// dereferentiere
*x = *y;
*y = t;
}

Aceeai funcie swap(), folosind argumente de tip referin, arat astfel:


void swap(int& x, int& y){
int t;
t = x;
x = y;
y = t;
}

Se poate observa perfecta simetrie ntre cele dou implementri i c, n mod


evident, referina folosete adresa variabilei pentru a o putea modifica (deci un
pointer). Dar, n cazul referinelor, pointerul i defererenierea sunt ascunse,
programatorul nu trebuie s le prevad explicit, programul rezultat este mai concis i
mai clar.
Referinele sunt deosebit de utile n apelul funciilor ale cror argumente sunt
obiecte de dimensiuni mari i copierea lor n argumentele formale (plasate n
segmentul de stiv al programului) ar fi foarte ineficient.
Argumente implicite ale funciilor. Se ntmpl frecvent ca o funcie s aib
un numr mai mare de argumente dect sunt necesare n cazurile simple dar frecvente
de apel. Dac nu este necesar s fie transmis ntotdeauna valoarea real a unui
argument i acesta poate lua, de cele mai multe ori, o valoare implicit, atunci n
declaraia funciei se prevede o expresie de iniializare a acestui argument, iar din apel
poate s lipseasc valoarea argumentului corespunztor.
De exemplu, o funcie pentru stabilirea datei calendaristice, care prevede
valori implicite pentru argumentele luna i an:

Elemente de Programare Orientat pe Obiecte

18

struct data{
int zi;
int luna;
int an;
} g_data;
void setdata(int zi, int luna=9, int an =1999){
g_data.zi = zi;
g_data.luna = luna;
g_data.an = an;
}
void main(){
setdata(15);
// 15 9 1999
setdata(21,7);
// 21 7 1999
setdata(20,1,2000);
// 21 1 2000
}

Numai argumentele de la sfritul listei pot fi argumente implicite. De


exemplu, este eronat urmtoarea declaraie:
void setdata(int zi, int luna=9, int an); // eroare

Pointeri la funcii. Dat fiind c o funcie are o localizare n memorie, aceast


valoare poate fi atribuit unui pointer. Adresa unei funciei este punctul de intrare n
funcie i, de aceea, funcia poate fi apelat folosind un pointer.
Tipul unui pointer la o funcie se definete folosind tipul valorii returnate i
tipurile argumentelor formale ale funciei. nainte de apelul unei funcii prin pointer,
trebuie s fie asignat valoarea pointerului folosind numele funciei. De exemplu:
float func1(int x, float y){
return x + y;
}
float func2(int x, float y){
return x * y;
}
void main(){
float (*pf)(int, float);

pf = func1;
float z = (*pf)(3, 1.2f);
cout << z << endl;
pf = func2;
z = (*pf)(3, 1.2f);
cout << z << endl;

// definire tip pointer


//
//
//
//
//
//

asignare valoare pointer


apel functie
afiseaza 4.2
asignare valoare pointer
apel functie
afiseaza 3.6

Dei din acest exemplu simplu nu reiese care ar putea fi avantajul folosirii
apelului prin pointer a unei funcii, exist totui situaii cnd apelul prin pointeri este
foarte avantajos. De exemplu, poate s fie nlocuit o instruciune switch care
selecteaz dintre mai multe apeluri de funcii, cu un vector de pointeri la funcii care
se pot apela prin pointerii corespunztori.

1. Concepte de baz ale limbajului C++

19

Suprancrcarea funciilor. n limbajul C, fiecare funcie definit n program


trebuie s aib un nume diferit. n C++, mai multe funcii pot avea acelai nume n
acelai domeniu de definiie, dac se pot diferenia prin numrul sau tipul
argumentelor de apel. Acest mecanism se numete suprancrcarea funciilor
(function overloading). n traducere, se mai ntrebuineaz i denumirile de
suprapunere, redefinire, supradefinire; n textul de fa este preferat termenul de
suprancrcare. Suprancrcarea se poate aplica att funciilor ct i operatorilor; n
seciunea aceasta este prezentat suprancrcarea funciilor, iar suprancrcarea
operatorilor este descris n seciunea 4.
Dac n acelai domeniu sunt definite mai multe funcii cu acelai nume, la
fiecare apel se selecteaz funcia corect prin compararea tipurilor argumentelor reale
de apel cu tipurile argumentelor formale ale funciei. De exemplu:
double abs(double);
int abs(int);
abs(1);
abs(1.0);

// apeleaza abs(int)
// apeleaza abs(double)

Acceptarea mai multor versiuni ale unei funcii cu acelai nume este
condiionat de posibilitatea selectrii fr ambiguitate a uneia dintre acestea dup
tipul sau numrul argumentelor. Nu este admis ca funciile s difere doar prin tipul
returnat.
Dou funcii declarate cu acelai nume se refer la aceeai funcie dac sunt n
acelai domeniu i au numr i tipuri identice de argumente. O funcie declarat local
nu este n acelai domeniu cu o funcie cu domeniul la nivel de fiier. De exemplu:
int f(char*);
void g(){
extern f(int);
f(abcd); // eroare, f(int) ascunde f(char*)
//deci nu exista f(char*) n acest domeniu
}

Situaii asemntoare, de ascundere i nu de suprancrcare n domenii diferite


vor mai fi prezentate n seciunea 5, dedicat claselor derivate.
Selecia funciei la apel se bazeaz pe cea mai bun potrivire a argumentelor
(best argument matching). Dac printre funciile suprancrcate exist o funcie care
are toate argumentele de tipuri identice cu argumentele din apel, atunci aceast funcie
prezint cea mai bun potrivire a argumentelor i este selectat.
Se consider de exemplu funcia suprancrcat de calcul a ridicrii la o putere
a unui numr, funcia power():
int power(int, int);
long power(long,int);
double power(double, int);
double power(double, double);
power(7, 8);
// selecteaza power(int, int)
power(5.6, 2);
// selecteaza power(double, int)
power(6.7, 2.5);
// selecteaza power(double, double)

Elemente de Programare Orientat pe Obiecte

20

n aceste apeluri s-a selectat versiunea funciei power() pe baza coincidenei


dintre argumentele de apel i argumentele formale.
n cazul n care nu exist o astfel de coinciden, se fac conversii ale
argumentelor efective (de apel) ctre tipul argumentelor formale. Compilatorul
ncearc cea mai bun potrivire pentru fiecare argument n parte prin conversii pentru
tipuri predefinite care s nu conduc la trunchieri (pierderi de informaie). De
exemplu:
long a = 100;
int b = 10;
float c = 2.3f;
float d = 5.6f;
double e = 7.0;
double f = 2;
power(a,b);
power((int)a, b);
power(c,a);
power(c,d);
power(e,d);

//
//
//
//
//

selecteaza
selecteaza
selecteaza
selecteaza
selecteaza

power(long, int)
power(int, int)
power(double, int)
power(double, double)
power(double, double)

Dac prin astfel de conversii nu se poate stabili cea mai bun potrivire a
argumentelor, atunci sunt ncercate i conversii pentru tipuri definite de utilizatori.
Apelul este acceptat numai dac selecia unei versiuni a funciei (pe baza criteriului de
cea mai bun potrivire a argumentelor) este unic. Conversiile ntre date de tipuri
definite de utilizatori sunt prezentate n seciunea 4, dedicat suprancrcrii
operatorilor.
1.4.2.5 Constante simbolice
O constant simbolic (sau constant cu nume) este un nume a crui valoare
nu poate fi modificat n cursul programului. n C++ exist trei modaliti de a defini
constante simbolice:
Orice valoare, de orice tip care poate primi un nume, poate fi folosit ca o
constant simbolic prin adugarea cuvntului-cheie const n declaraia
acesteia.
Orice nume de funcie sau de tablou este o constant simbolic.
O enumeraie definete o mulime de constante ntregi.
De exemplu, urmtoarele declaraii introduc constante simbolice prin folosirea
cuvntului-cheie const:
const int val = 100;
const double d[] = {1.2, 2.8, 9.5};

Deoarece constantele nu pot fi modificate, ele trebuie s fie iniializate n


declaraie. ncercarea de modificare ulterioar este detectat ca eroare n timpul
compilrii:
val++;
d = 200;

// eroare
// eroare

1. Concepte de baz ale limbajului C++

21

Cuvntul-cheie const modific tipul obiectului, restricionnd modul n care


acesta poate fi folosit.
Un aspect interesant i intens folosit n programare, este acela de a declara
pointeri la constante. Atunci cnd se folosete un pointer, sunt implicate dou obiecte:
pointerul nsui i obiectul ctre care indic pointerul.
Prin prefixarea declaraiei unui pointer cu cuvntul const, obiectul indicat
este fcut constant, nu pointerul nsui. De exemplu:
const char* pc = abcd;// pc este pointer la o constant
pc[2] = m;
// eroare, nu se poate modifica
// obiectul constant
pc = ghij;
// corect, este modificat
// valoarea pointerului
pc++;
// corect

Pentru ca pointerul nsui s fie constant, se folosete operatorul *const:


char *const cp = abcd;// cp este pointer constant;
cp[2] = m;
// corect, modifica valoarea
cp++;
// eroare, pointer constant

Posibilitatea de declarare a pointerilor la constante este folosit n special


pentru transmiterea argumentelor funciilor. Prin declararea unui argument de tip
pointer la constant, este interzis modificarea de ctre funcie a obiectului indicat. De
exemplu:
char* strcpy(char* d, const char* s);

n aceast funcie irul s nu poate fi modificat.


n mod asemntor, specificatorul const care nsoete un argument tip
referin la apelul unei funcii, mpiedic modificarea acestuia de ctre funcia
respectiv.
Enumeraii. O alt metod de a defini constante ntregi este prin enumeraie.
De exemplu, enumeraia:
enum {
INPUT,
OUTPUT,
INOUT,
};

este echivalent cu declararea urmtoarelor constante:


const INPUT = 0;
const OUTPUT = 1;
const INOUT = 2;

Valorile asignate implicit constantelor ncep de la 0 i sunt n ordine cresctoare.


Enumeraiile pot avea nume. De exemplu:
enum states{

Elemente de Programare Orientat pe Obiecte

22
good,
bad,
fail

};
void fe (states st ){
if (st != good){
//.
}
}

Un nume declarat de tipul unei enumeraii poate lua orice valoare particular
cuprins n enumeraie.
n sfrit, este posibil iniializarea elementelor unei enumeraii:
enum states{
good = 0x00,
bad = 0x01,
fail = 0x10
};

Valorile de iniializare nu trebuie neaprat s ia valori succesive.


1.4.2.6 Specificatorul typedef
Declaraiile care conin cuvntul-cheie typedef declar identificatori care
pot fi folosii pentru denumirea tipurilor fundamentale sau derivate n domeniile de
definiie ale acestora. O declaraie care conine specificatorul typedef nu introduce
un nume nou n program, ci realizeaz o echivalen sintactic a unui nume nou cu un
alt nume, fundamental sau derivat. De exemplu, n declaraiile:
typedef int KM, *PKM;
KM dist;
PKM pd;

KM este de tip ntreg, iar pd este pointer la ntreg.


O structur fr nume definit printr-un specificator typedef capt numele
introdus de acesta:
typedef struct { /**/} S; //structura este denumit S.
S struct1;

Acesta este modul obinuit de declaraie n C, unde numele unei structuri nu


poate fi folosit ca un nume de tip fr s fie nsoit de cuvntul-cheie struct. Acest
stil este admis i n C++, pentru a se asigura compatibilitatea. Dar stilul mai normal
pentru C++ este de a declara o structur cu nume i fr typedef:
struct SC{/*...*/};
SC struct2;

1. Concepte de baz ale limbajului C++

23

1.4.2.7 Specificatorul volatile


Specificatorul volatile indic faptul c valoarea obiectului poate fi
modificat pe alte ci dect cele declarate explicit n program. De exemplu, adresa
unei variabile globale poate fi transmis unei rutine de interfa a sistemului, care
modific valoarea acesteia, fr o instruciune explicit din program. Acest lucru este
important, deoarece majoritatea compilatoarelor de C i C++ optimizeaz automat
evaluarea expresiilor prin presupunerea c o variabil rmne neschimbat atta timp
ct nu apare n partea stng a unei operaii de asignare. Specificatorul volatile
mpiedic aplicarea unor astfel de optimizri.
1.4.2.8 Clase, structuri, uniuni
Pe lng tipurile de date fundamentale ale limbajului, n C++ se pot defini
tipuri de date noi prin definirea unor clase. Aceste tipuri se numesc tipuri definite de
utilizator (user-defined types) i se pot utiliza ntr-un mod asemntor utilizrii
tipurilor predefinite. Aceste tipuri mai sunt denumite i tipuri de date abstracte
(abstract data types), dar n aceast lucrare s-a folosit termenul de tip definit de
utilizator, aa cum l prefer autorul limbajului. De exemplu, declaraia:
class X {
// corpul clasei X
// declaraii de date i funcii membre
};

este i o definiie a clasei X, care introduce un tip nou de date. Prin aceast definiie se
asociaz numele X cu entitatea definit n corpul clasei. Dup definirea unui astfel de
tip de date, se pot declara (defini) obiecte de tipul respectiv, la fel ca i variabilele
(obiecte) de tipuri predefinite:
X obx1;

// obiect obx1 de tipul X

Clasele, structurile i uniunile n C++, precum i pointeri la membrii claselor,


vor fi prezentate detaliat n seciunea urmtoare. n acest punct au fost introduse doar
pentru precizrile legate de tipuri, declaraii i definiii.

1.5

Expresii i operatori

O expresie este o secven de operatori i operanzi care specific executarea


unor calcule. n C++ operatorii pot fi suprancrcai, adic li se poate atribui un anumit
mod de operare atunci cnd se aplic tipurilor definite de utilizator (clase). Operatorii
suprancrcai urmeaz aceleai reguli sintactice ca i operatorii normali, dar operaiile
efectuate pot s difere de ale acestora. Suprancrcarea operatorilor nu poate modifica
regulile de aplicare ale acestora asupra tipurilor pentru care ei sunt definii n limbaj.
Ordinea de evaluare a unei subexpresii este determinat de precedena
(precedence) i gruparea operatorilor. Regulile matematice obinuite de asociativitate

Elemente de Programare Orientat pe Obiecte

24

i comutativitate se aplic pentru acei operatori care sunt n mod real asociativi sau
comutativi.
O expresie care se refer la un obiect sau funcie este denumit valoare stnga
(left value, prescurtat lvalue). Aceast denumire provine din faptul c o astfel de
valoare poate fi folosit ca membru stng al unei expresii de asignare: E1 = E2.
Operandul E1 trebuie s fie expresie lvalue. n expresii, unii operatori produc expresii
lvalue, alii necesit expresii lvalue. O expresie lvalue este modificabil dac nu este
numele unei funcii, numele unui tablou, sau constant.

1.5.1 Operatori specifici C++


Majoritatea operatorilor C++ sunt preluai din limbajul C, cu aceeai sintax i
reguli de operare. n plus fa de operatorii C, n C++ mai sunt introdui urmtorii
operatori:
operatorul de rezoluie (::)
operatorul de lansare excepie (throw)
operatorii de alocare-eliberare dinamic a memoriei new i delete.
Operatorul de lansare excepie (throw) este descris n seciunea 8. Ceilali
operatori sunt descrii n continuare.
1.5.1.1 Operatorul de rezoluie
Operatorul de rezoluie (::) este folosit pentru modificarea domeniului de
vizibilitate al unui nume. Pentru acest operator (scope resolution operator), n
traduceri se mai ntlnesc termenii de operator de domeniu sau operator de acces.
Operatorul de rezoluie permite folosirea unui identificator ntr-un bloc n care el nu
este vizibil. Dac operatorul de rezoluie nu este precedat de nici un nume de clas,
atunci este accesat numele global care urmeaz acestui operator. De exemplu:
int g = 10;
int f(){
int g = 20;
//
return ::g;
}
void main(){
cout << f() << endl; // afiseaza 10
}

n acest exemplu operatorul de rezoluie a fost folosit pentru a accesa variabila


global g, ascuns de variabila local cu acelai nume din funcie. Deoarece utilizarea
cea mai extins a operatorului de rezoluie este legat de utilizarea claselor, el va fi
reluat pe parcursul seciunilor urmtoare.

1. Concepte de baz ale limbajului C++

25

1.5.1.2 Operatorii new i delete


n limbajul C se pot aloca dinamic zone n memoria liber (heap) folosind
funcii de bibliotec (de exemplu, malloc(), calloc(), realloc()) i se pot
elibera folosind funcia free(). La aceste posibiliti, care se pstreaz n continuare
n C++, se adaug operatorii de alocare i eliberare dinamic a memoriei, new i
delete. Aceti operatori unari prezint avantaje substaniale fa de funciile de
alocare din C i de aceea sunt n mod evident preferai n programele scrise n C++.
Pentru alocarea unei singure date (obiect), operatorul new are urmtoarea
form general:
tip_data* p = new tip_data(initializare);

unde tip_data este un tip de date predefinit sau definit de utilizator (clas), p este
pointerul (adresa de nceput) a zonei alocate n memoria liber, returnat la execuia
operatorului new, iar initializare este o expresie care depinde de tipul datei i
permite iniializarea zonei de memorie alocate. Dac alocarea nu este posibil,
pointerul returnat este NULL.
Forma de utilizare a operatorului new pentru alocarea unui vector de date
(tablou unidimensional) de dimensiune dim, este urmtoarea:
tip_data* p = new tip_data[dim];

La alocarea unui vector nu se poate transmite o expresie de iniializare a zonei


de memorie alocat.
Operatorul delete elibereaz o zon din memoria heap. El poate avea una
din urmtoarele forme:
delete p; delete []p;

Prima form se utilizeaz pentru eliberarea unei zone de memorie ocupat de o singur
dat (obiect), nu de un vector. Pointerul p trebuie s fie un pointer la o zon de
memorie alocat anterior printr-un operator new. Operatorul delete trebuie s fie
folosit doar cu un pointer valid, alocat numai cu new i care nu a fost modificat sau nu
a mai fost eliberat zona de memorie mai nainte (cu un alt operator delete sau prin
apelul unei funcii free()). Folosirea operatorului delete cu un pointer invalid
este o operaie cu rezultat nedefinit, cel mai adesea producnd erori de execuie grave.
Cea de-a doua form a operatorului delete[] se folosete pentru eliberarea
unei zone de memorie ocupat de un vector de date. Pentru tipurile de date predefinite
ale limbajului, se poate folosi i prima form pentru eliberarea unui vector, dar, n
cazul obiectelor de tipuri definite de utilizator, acest lucru nu mai este valabil. Aceast
situaie va fi detaliat n seciunea urmtoare.
Cteva exemple de utilizare a operatorilor new i delete:
int *pi = new int(3);
double *pd = new double;
char *pc1 = new char[12];
char *pc2 = new char[20];
delete pi;
delete pd;

//
//
//
//

alocare int i iniializare


alocare double neinitializat
vector de 12 caractere
vector de 20 caractere

Elemente de Programare Orientat pe Obiecte

26
delete pc1;
delete []pc2;

//corect, char e tip predefinit


// corect, elibereaza vector

n legtur cu cele dou metode de alocare dinamic, prin operatorii newdelete i prin funciile de bibliotec malloc-free, fr s fie o regul precis, se
recomand evitarea combinrii lor, deoarece nu exist garania compatibilitii ntre
ele.

1.5.2

Precedena operatorilor

n tabelul urmtor sunt prezentai concis operatorii din limbajul C++ grupai
n ordinea precedenei lor. n fiecare compartiment sunt trecui operatorii cu aceeai
preceden. Un operator dat are o preceden mai ridicat dect un altul dintr-un
compartiment aflat mai jos n tabel. Operatorii se aplic n ordinea precedenei lor. De
exemplu, a+b*c nseamn a+(b*c), deoarece nmulirea (*) are o preceden mai
ridicat dect adunarea (+).

Operatori C++
::

operator rezoluie

nume_clas::membru

::

nume global

::nume

selecie membru

obiect.membru

->

selecie membru

pointer->membru

[]

indexare

pointer[expr]

()

apel funcie

expr (lista_expr)

()

conversie explicit

tip(list_expr)

sizeof

dimensiune obiect

sizeof expr

sizeof

dimensiune tip

sizeof (tip)

++

post incrementare

lvalue++

++

pre incrementare

++lvalue

--

post decrementare

lvalue--

--

pre decrementare

--lvalue

complement

~expr

negaie

!expr

minus unar

-expr

plus unar

+expr

&

adres

&lvalue

1. Concepte de baz ale limbajului C++

27

derefereniere

*expr

new

alocare

new tip

delete

eliberare(dezalocare)

delete pointer

delete[]

eliberare tablou

delete[]pointer

()

conversie cast

(tip)expr

.*

selecie membru

obiect.*pointer_la_membru

->*

selecie membru

pointer->*pointer_la_membru

nmulire

expr * expr

mprire

expr / expr

modulo

expr % expr

adunare

expr + expr

scdere

expr - expr

<<

depl. logic stnga

expr << expr

>>

depl. logic dreapta

expr >> expr

<

mai mic

expr < expr

<=

mai mic sau egal

expr <= expr

>

mai mare

expr > expr

>=

mai mare sau egal

expr >=expr

==

egal

expr == expr

!=

diferit

expr != expr

&

AND orientat pe bii

expr & expr

XOR orientat pe bii

expr ^ expr

OR orientat pe bii

expr | expr

&&

AND logic (I)

expr && expr

||

OR logic (SAU)

expr || expr

?:

expresie condi.

expr ? expr : expr

asignare simpl

lvalue = expr

*=

nmulire i asignare

expr *= expr

/=

mprire i asignare

expr /= expr

%=

modulo i asignare

expr %= expr

+=

adunare i asignare

expr += expr

-=

scdere i asignare

expr -= expr

Elemente de Programare Orientat pe Obiecte

28
<<=

depl. stg i asignare

expr <<= expr

>>=

depl. dr. i asignare

expr >>= expr

&=

AND i asignare

expr &= expr

|=

OR i asignare

expr |= expr

^=

XOR i asignare

expr ^= expr

throw

lansare excepie

throw expresie

virgul(secveniere)

expr, expr

1.6

Conversii standard

Unii operatori pot provoca conversia valorii unui operand de la un tip la altul,
n funcie de tipul operanzilor. Conversiile standard executate pentru tipurile
predefinite n C++ sunt identice cu cele din limbajul C i de aceea vor fi descrise
foarte succint. Astfel de conversii intervin n urmtoarele situaii:
Conversia unor operanzi de tipuri diferite ntr-o expresie aritmetic.
Conversia unui argument de apel al unei funcii la tipul argumentului
formal corespunztor.
Conversia valorii returnate de o funcie din tipul folosit n instruciunea
return n tipul din declaraia funciei.
n toate aceste situaii se respect cteva reguli de conversie care sunt descrise
n continuare.

1.6.1

Conversiile aritmetice

Atunci cnd ntr-o expresie sunt combinate constante i variabile de tipuri


diferite, ele sunt convertite la acelai tip, n general n tipul cu valoarea cea mai mare,
aciune care se numete promovarea tipului. Mai nti toate valorile de tip char i
short int sunt convertite n int (promovare la ntreg). Dup aceea, toate celelate
conversii sunt efectuate dup urmtorul algoritm:
dac un element este long double
atunci urmtorul este convertit n long double
altfel dac un element este double
atunci urmtorul este convertit n double
altfel dac un element este float
atunci urmtorul este convertit n float
altfel dac un element este unsigned long
atunci urmtorul este convertit n unsigned long
altfel dac un element este long int i
urmtorul este unsigned int
dac long int poate reprezenta toate
valorile unui unsigned int
atunci unsigned int este convertit n long int

1. Concepte de baz ale limbajului C++

29

altfel amndou sunt conv.n unsigned long int


altfel dac un element este unsigned int
atunci urmtorul este convertit n unsigned int

Dup aplicarea acestor reguli de conversie, fiecare pereche de elemente este


de acelai tip, iar rezultatul fiecrei operaii este de acelai tip cu cel al ambelor
elemente.

1.6.2

Conversia pointerilor

Urmtoarele conversii standard se aplic pointerilor:


O expresie constant evaluat la zero este convertit ntr-un pointer, numit
pointer nul. Un pointer nul nu este neaprat reprezentat ca un ntreg cu
valoarea 0.
Un pointer la orice valoare neconstant i nevolatil poate fi convertit n
void*.
Un pointer la funcie poate fi convertit n void*, cu condiia ca pointerul
void* s aib capacitate de reprezentare suficient pentru toate valorile
posibile ale unui astfel de pointer la funcie.
Numele unui tablou poate fi convertit n pointer la primul element al
tabloului.
Conversiile ntre pointerii claselor de baz i derivate, precum i conversia
ntre referine la clase de baz i derivate sunt prezentate n seciunea 5.
Alte conversii (descrise n seciunile urmtoare) sunt posibile prin:
Iniializarea obiectelor de tipuri definite de utilizator (clase);
Suprancrcarea operatorului de conversie.
Conversiile ntre tipurile de date din C++ se supun principiului tipizrii
propriu modelului obiect. Se poate observa faptul c C++ este un limbaj hibrid din
punct de vedere al tipizrii: sunt verificate conversiile ntre tipurile de date i sunt
rejectate acele conversii considerate neadmisibile. Pe de alt parte, limbajul admite
forarea conversiilor (prin operatorul de conversie cast), situaie n care este inhibat
verificarea de tip a operanzilor. Dar aceast forare se face pe rspunderea
programatorului, care are posibilitatea s le prevad numai pe acelea pe care le
consider corecte.

1.7

Fiierele componente ale unui program C++

Orice program C++ care nu este foarte simplu este alctuit din mai multe
uniti de compilare, numite convenional fiiere.
Din punct de vedere al limbajului C++, un fiier reprezint un domeniu de
definiie (domeniul fiier), care este domeniul pentru funciile globale de tip static
i inline i pentru variabilele globale de tip static. Un fiier este, de asemenea,
o unitate de memorare n sistemul de fiiere i o unitate de compilare (un modul).

Elemente de Programare Orientat pe Obiecte

30

Dezvoltarea unui program ntr-un singur fiier este practic imposibil, deoarece
sunt apelate funcii din biblioteci i funcii ale sistemului de operare care sunt
memorate n mai multe fiiere. Chiar i partea de program scris de utilizator este
inconvenabil s fie toat cuprins ntr-un singur fiier, datorit dificultii de
organizare i de evideniere a diferitelor pri ale programului. Mai mult, dac
programul este curins ntr-o singur unitate de compilare, orice modificare trebuie
urmat de recompilarea ntregului fiier.
n organizarea pe mai multe fiiere a unui program, este necesar ca
programatorul s prevad declaraii care s permit analiza de ctre compilator a
fiecrei uniti de compilare luat izolat dar, n acelai timp, i utilizarea unitar a
numelor i a tipurilor definite. Orice sistem de programare permite o astfel de
organizare i legare a unitilor compilate separat, n principal prin programul de
linkare (linker).

1.7.1

Linkarea modulelor

Dac nu este specificat altfel, un nume care nu este local (definit ntr-o funcie
sau clas) trebuie s se refere la aceeai entitate n oricare din unitile de compilare
(fiiere) ale programului, adic trebuie s existe o singur funcie, valoare, tip sau
obiect nelocal cu acelai nume. De exemplu, se consider fiierele:
// fisier1.cpp
int x = 0;
void f() {/* corpul functiei*/}
// fisier2.cpp
extern int x;
void f();
int g() {
x = f();
}

Variabila x i funcia f() utilizate n funcia g() din fiierul


fisier2.cpp sunt definite n fisier1.cpp; cuvntul-cheie extern din
declaraia variabile x n fisier2.cpp este doar o declaraie, nu o definiie. La fel,
prototipul funciei f()este declarat n fiier2.cpp, iar definiia acesteia se
gsete n fiier1.cpp.
Erorile de programare care se refer la definiii multiple (n fiiere diferite), la
lipsa definiiilor sau la neconcordana ntre definiii i declaraii sunt detectate i
semnalate de linker.
Numele declarate static sunt locale n fiecare dintre fiiere. Obiectele sau
funciile cu nume cunoscute numai ntr-un fiier au linkare intern (internal linkage).
Obiectele sau funciile cu nume care sunt cunoscute n mai mult de un fiier au linkare
extern (external linkage). Numele tipurilor (numele claselor i ale enumeraiilor) nu
au nici o linkare, dar ele trebuie s fie definite n mod unic n program.

1. Concepte de baz ale limbajului C++

1.7.2

31

Fiiere antet

Pentru a se asigura consistena declaraiilor ntr-un program compus din mai


multe fiiere se folosesc fiiere antet (header files) care conin informaii de interfa
ntre unitile programului i sunt incluse n fiierele surs. Includerea unui fiier (cel
mai probabil fiier antet) ntr-un alt fiier surs se specific prin directiva:
#include nume_fisier

La ntlnirea acestei directive, se nlocuiete aceast linie surs cu ntreg fiierul


nume_fisier. Numele fiierului inclus se ncadreaz ntre ghilimele dac este n
directorul curent sau ntre paranteze ascuite <> dac este n directorul standard de
includeri. Fiierele antet au extensia .h, iar celelate fiiere surs au una din extensiile
admise de compilatorul respectiv (.C, .cpp, .cxx, .cc).
Includerea fiierelor antet n fiierele surs produce recompilarea acestora la
compilarea fiecrui fiier surs. Acest aspect poate s nu influeneze prea mult
eficiena de compilare, deoarece fiierele antet conin n general declaraii care nu
necesit analiz intens n compilare. Se poate, de asemenea ca sistemul de
programare s permit utilizarea fiierelor antet precompilate. Un fiier antet poate
conine:
Directive de includere
Macro definiii
Definiii de tipuri
Definiii de constante
Enumeraii
Definiii funcii inline
Definiii template
Declaraii de date
Declaraii de nume
Declaraii de funcii
Comentarii

#include antet2.h
#define BOOL int
struct point {double x, y;};
const double epsilon = 0.1;
enum state{good, false};
inline char get(char*p)
{return *p++;}
template<class T>
class V{/* */};
extern int x;
class X;
extern int func(char c);
/* comentariu */

Nu se introduc n fiierele antet:


Definiii de funcii normale
Definiii de date
Definiii tablouri constante

char get(char *p)


{return *p++;}
int x;
const int tb[] = {/*

*/};

Acestea nu sunt reguli impuse cu strictee, ci sugestii pentru un mod rezonabil


de utilizare a fiierelor antet.
Numrul de fiiere antet ale unui program poate s varieze de la unul singur
(pentru programele de dimensiuni reduse) la mai multe fiiere antet, n general cte un
fiier antet pentru fiecare fiier surs. Posibilitatea de mprire a unui program C++ n
mai multe module care pot fi compilate separat, dar care au conexiuni cu alte module
ale programului, reprezint caracteristica de modularitate a limbajului, care respect n
acest fel principiul modularitii, propriu modelului obiect.

Elemente de Programare Orientat pe Obiecte

32

Exerciii
E1.1 S se rescrie funciile strlen(), care returneaz lungimea unui ir,
strcmy(), care compar dou iruri i strcpy() care copiaz un ir n alt ir. S
se stabileasc ce fel de tipuri de argumente sunt necesare, dup aceea s se compare cu
versiunea standard declarat n <string.h>.
E1.2 Se consider urmtoarea operaie de copiere a dou iruri de caractere
terminate cu nul:
int len = strlen(q);
for (int i = 0; i<=len; i++) p[i] = q[i];

S se rescrie aceste instruciuni folosind operaii asupra pointerilor.


E1.3 S se scrie o funcie strcat() care concateneaz dou siruri. Se va folosi
operatorul new pentru alocarea spaiului necesar rezultatului.
E1.4

Fie urmtorul program:


int& fr(int a, int b){
int x = a+b;
return x;
}
void main(){
int& v = fr(4,6);
cout << v << endl;
cout << "mesaj\n";
cout << v << endl;
}

S se explice cauza execuiei eronate a acestui program (pentru referina v se


afieaz dou valori diferite).
E1.5 S se scrie o funcie atoi() care returneaz valoare de tip ntreg a unui ir
de cifre zecimale. S se scrie o funcie itoa() care genereaz irul de caractere care
reprezint un numr ntreg dat.
E1.6 S se scrie declaraiile pentru urmtoarele tipuri de variabile: pointer la un
caracter, un vector de 10 valori ntregi, pointer la un vector de 10 valori ntregi, un
pointer la un pointer la un caracter.
E1.7 S se scrie un program care tiprete dimensiunea tipurilor fundamentale de
date. Se va folosi operatorul sizeof.
E1.8 S se scrie o funcie n care se detecteaz eroarea de alocare a memoriei cu
operatorul de alocare new.

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

  • Par Tea 8
    Par Tea 8
    Document12 pagini
    Par Tea 8
    Codrut Rat
    Încă nu există evaluări
  • Hamming Cod
    Hamming Cod
    Document7 pagini
    Hamming Cod
    Diana Semionova
    Încă nu există evaluări
  • Hamming Cod
    Hamming Cod
    Document7 pagini
    Hamming Cod
    Diana Semionova
    Încă nu există evaluări
  • Cpis 08
    Cpis 08
    Document68 pagini
    Cpis 08
    Agapie Alexandru
    Încă nu există evaluări
  • Alex Activare Celule
    Alex Activare Celule
    Document2 pagini
    Alex Activare Celule
    Agapie Alexandru
    Încă nu există evaluări
  • Rezolvare Subiect Restanta
    Rezolvare Subiect Restanta
    Document4 pagini
    Rezolvare Subiect Restanta
    Agapie Alexandru
    Încă nu există evaluări
  • STRT Avr
    STRT Avr
    Document36 pagini
    STRT Avr
    Agapie Alexandru
    Încă nu există evaluări
  • Probleme Rezolvate C
    Probleme Rezolvate C
    Document10 pagini
    Probleme Rezolvate C
    ionutzlupu
    Încă nu există evaluări
  • Introducere in .Net Framework Suport de Curs Pentru Elevi
    Introducere in .Net Framework Suport de Curs Pentru Elevi
    Document112 pagini
    Introducere in .Net Framework Suport de Curs Pentru Elevi
    Valeriu Jecov
    Încă nu există evaluări
  • 7 Securitatea
    7 Securitatea
    Document14 pagini
    7 Securitatea
    Agapie Alexandru
    Încă nu există evaluări
  • Curs 7 8 Normalizarea
    Curs 7 8 Normalizarea
    Document0 pagini
    Curs 7 8 Normalizarea
    Agapie Alexandru
    Încă nu există evaluări
  • Set Spete Sapt 1-4 Noi
    Set Spete Sapt 1-4 Noi
    Document3 pagini
    Set Spete Sapt 1-4 Noi
    Agapie Alexandru
    Încă nu există evaluări
  • Radu Marsanu
    Radu Marsanu
    Document14 pagini
    Radu Marsanu
    Agapie Alexandru
    Încă nu există evaluări
  • 7 Securitatea
    7 Securitatea
    Document14 pagini
    7 Securitatea
    Agapie Alexandru
    Încă nu există evaluări
  • Curs 9 Dpi
    Curs 9 Dpi
    Document4 pagini
    Curs 9 Dpi
    Agapie Alexandru
    Încă nu există evaluări
  • New OpenDocumenthtml 5 Text
    New OpenDocumenthtml 5 Text
    Document2 pagini
    New OpenDocumenthtml 5 Text
    Agapie Alexandru
    Încă nu există evaluări
  • Ir
    Ir
    Document65 pagini
    Ir
    Agapie Alexandru
    Încă nu există evaluări