Documente Academic
Documente Profesional
Documente Cultură
, Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
LIVIANA TUDOR
BAZELE PROGRAMÃRII
ÎN LIMBAJUL C++
MATRIX ROM
Bucureşti 2010
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
LIVIANA TUDOR
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Referent ştiinţific
prof. dr. ing. Mircea Petrescu
Universitatea POLITEHNICA Bucureşti
Tehnoredactare computerizatã
lect. dr. Tudor Nicoleta Liviana
Universitatea Petrol-Gaze din Ploiesti
ltudor@upg-ploiesti.ro
tudorlivia@yahoo.com
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Bazele programãrii în limbajul C++
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
6.2. Instrucţiunea while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
6.3. Instrucţiunea do-while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
6.4. Instrucţiuni pentru transferul execuţiei . . . . . . . . . . . . . . . 84
7. Tablouri ( vectori, matrice, şiruri de caractere) . . . . . . . . . . . . . . . . . . . 89
7.1. Tablouri unidimensionale ( vectori) . . . . . . . . . . . . . . . . . . . 90
7.1.1. Cãutare în vectori . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
7.1.2. Sortarea unui vector . . . . . . . . . . . . . . . . . . . . . . . . . 99
7.1.3. Interclasarea a doi vectori ordonaţi . . . . . . . . . . . . 102
7.2. Tablouri bidimensionale ( matrice) . . . . . . . . . . . . . . . . . . . 105
7.3. Şiruri de caractere . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
8. Structuri şi uniuni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
8.1. Structuri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
8.2. Uniuni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
9. Funcţii C++ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
9.1. Prototipul, definiţia şi apelul unei funcţii . . . . . . . . . . . . . . 129
9.2. Transferul parametrilor unei funcţii . . . . . . . . . . . . . . . . . . 132
9.2.1. Transferul parametrilor prin valoare . . . . . . . . . . 133
9.2.2. Transferul parametrilor prin referinţã . . . . . . . . . 136
9.2.3. Transferul parametrilor de tip tablou . . . . . . . . . 138
9.2.4. Transferul parametrilor de tip structurã . . . . . . . 142
9.3. Funcţii cu un numãr neprecizat de parametri . . . . . . . . . . 145
9.4. Pointeri la funcţii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
9.5. Funcţii recursive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
9.5.1. Funcţii direct recursive . . . . . . . . . . . . . . . . . . . . . . 150
9.5.2. Recursivitatea şi metoda reluãrii (backtracking) 155
10. Structuri de date alocate dinamic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
10.1. Operaţii cu variabile de tip pointer . . . . . . . . . . . . . . . . . . 159
10.2. Pointeri cãtre tablouri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
10.3. Structuri autoreferite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
11. Liste şi arbori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
11.1. Liste, stive, cozi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
11.2. Tabele de dispersie (Hash) . . . . . . . . . . . . . . . . . . . . . . . . . 188
11.3. Arbori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191
11.3.1. Arbori binari . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
11.3. 2. Arbori oarecare . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Capitolul 1
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
UC = CPU (unitate centralã de prelucrare ) + MI ( memorie internã )
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Un octet (byte) 1o = 1 B = 8 biţi = cantitatea de informaţie memoratã într-o
locaţie.
Capacitatea totalã a memoriei reprezintã numãrul maxim de octeţi ce pot
fi înregistraţi.
Un Kilo-octet 1 Ko = 1 Kb (kilo-byte) = 1024 o = 210 o
Un Mega-octet (1 Mo) = 1024 Ko = 210 Ko
Un Giga-octet = 1024 Mo = 210 Mo
Un Tera-octet = 1024 Go = 210 Go
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
are capacitate foarte micã (64B), permite operaţii de citire şi scriere a datelor
şi este nevolatilã.
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
operare). Acesta încarcã în RAM nucleul sistemului de operare şi îl lanseazã în
execuţie. Nucleul va încãrca programele de aplicaţie şi utilitarele.
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Fig. 2. lansarea în execuţie a unui program.
Programele S. O.
Componentele majore ale unui S.O. sunt:
• programe de comandã şi control ( PCC ) - coordoneazã şi controleazã
funcţiile S.O., fiind programe supervizoare, monitoare şi executive). Au
componente
- rezidente ( sunt încãrcate în memoria internã încã de la generarea
S.O. şi pãstrate acolo pe tot parcursul execuţiei lucrãrilor de cãtre
S.O., ele formeazã nucleul S.O.)
- tranzitorii ( componente ce rãmân în memoria auxiliarã, fiind apelate
şi executate de cãtre nucleul S.O.)
• programe de servicii ( folosite pentru dezvoltarea programelor de aplicaţie,
fiind executate sub supravegherea PCC ). Ele pot fi clasificate în:
- translatoare (asamblor, macroasamblor, compilator, interpretor )
- editoare de legãturi
- încãrcãtoare
- editoare de texte
- programe pentru organizarea colecţiilor de date ( fişiere, baze de
date)
- alte utilitare.
Translatoarele de limbaje
• traduc programele sursã în programe obiect, ale cãror instrucţiuni în limbaj
maşinã pot fi executate de sistemul de calcul
• sunt douã categorii de translatoare:
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
- compilative ( realizeazã numai traducerea programului sursã în
program obiect), de exemplu:
- asambloare – traduc programele sursã, scrise în limbaje de
asamblare specifice S.C.
- compilatoare – traduc programele sursã scrise în limbaje
evoluate; unele compilatoare efectueazã şi lansarea în execuţie a
programelor ( LOAD and GO)
- interpretative (odatã cu compilarea, are loc si execuţia programului ).
x = a * ( b – c ) + d * ( e + 10)
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Fig. 4. Etapele procesului de compilare.
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
• sistemul de operare Netware, utilizat pentru administrarea serverelor de
fişiere, stocarea fişierelor, asigurând prelucrarea distribuitã şi centralizatã a
datelor, securitatea sistemului (exemplu, reţele Novell Netware).
Comunicarea este asiguratã de:
- folosirea de protocoale şi drivere LAN
- încãrcarea lui Netware Dos Requester pe fiecare client al reţelei
- folosire Link Support Layer (LSL)
- exemple de tipuri de clienţi acceptaţi de S.O. Netware 3.12. sunt:
clientul DOS, OS/2, Macintosh, Unix
Protocolul de comunicaţie este un set de reguli ce determinã modul de
comunicare în reţea, între staţii de lucru şi server.
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
x co c1 … cn = 0
ro r1 … rn
f0 f1 … fn
x = 27 co = 13 c1 = 6 c2 = 3 c3 =1 c4 = 0
r0 = 1 r1 = 1 r2 = 0 r3 = 1 r4 = 1
1 1 0 1 1
x=6 co = 3 c1 = 1 c2 = 0
r0 = 0 r1 = 1 r2 = 1
0 1 1
x = 27 co = 1 c1 = 0
r0 = 11 r1 = 1
B 1
unde [x] este partea întreagã a lui x şi {x} este partea fracţionarã a lui x.
Reprezentarea numãrului real x în baza p se reduce la reprezentarea
numãrului {x} în baza p şi foloseşte urmãtorul algoritm:
• se înmulţeşte în mod repetat partea fracţionarã a lui x cu baza p
• se descompune în parte întreagã şi parte fracţionarã, ş.a.m.d.
Notãm x1 = p * {x} = [x1] + {x1} = r -1 + {x1}, 0 ≤ r -1 < p
x2 = p * {x1} = [x2] + {x2} = r -2 + {x2}, 0 ≤ r -2 < p
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
x3 = p * {x2} = [x3] + {x3} = r -3 + {x3}, 0 ≤ r -3 < p
……………………………………………………..
xn = p * {xn-1} = [xn] + {xn} = r -n + {xn}, 0 ≤ r -n < p.
{x}p = p-1 r-1 + p-2 r-2 + ... + p-nr-n + ... = f( r –1) f( r –2) … f( r -n) = f –1 f –2 … f -n
{x}x1 x2 … xn
r -1 r -2 … r -n
f –1 f –2 … f -n
Exemplu: Sã se reprezinte x = 27.513 cu 4 cifre zecimale în baza 16
x = 27.513 = 27 + 0.513 = [x] + {x}
[x] = 27 1 0
11 1
B 1
[x] 16 = [ 27 ]16 = 1B
{x} = 0.513 0513*16 = 8.228 0.228*16 = 3.648 0.648*16 = 10.368 5.888
8 3 10 5
8 3 A 5
{ x } 16 = { 0.513 } 16 = 0.83A5
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
x, daca 0 ≤ x ≤ 31 − 1
y=
2 - 231 ≤ x ≤ 231 – 1
232 − | x |, daca − 231 ≤ x < 0 (prin complementare)
0, daca x ≥ 0
Observaţie: Primul bit =
1, daca x < 0
x = 231 – 1 = 7F.FF.FF.FF16
y = 232 – |x| = 232 – 231 = 231 * 2 – 231 = 231 ( prin complementare) = 8000000016
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Capitolul 2
Variabile
O noţiune de bazã în programare este cea de variabilã. O variabilã
reprezintã un ansamblu de patru elemente:
- numele variabilei
- tipul ei
- valoarea ei
- adresa din memorie, unde se salveazã variabila.
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Numele unei variabile este format din unul sau mai multe caractere: litere,
cifre, caracterul underscore (de subliniere), primul caracter fiind literã. Referirea
unei variabile se realizeazã prin intermediul numelui sãu. Exemple: a, b, S, min,
maxim, x1, etc.
Tipul variabilei indicã mulţimea de valori posibile ( întreg, real, caracter,
boolean, etc.), operaţiile ce pot fi aplicate acesteia, precum şi modul de
reprezentare în memoria calculatorului. Fiecare limbaj de programare permite
folosirea unor tipuri elementare de date, specifice acestuia. Pentru fiecare
variabilã folositã trebuie declarat în mod explicit tipul de date.
Valoarea unei variabile este valoarea efectivã memoratã la un moment dat. O
variabilã are în orice moment o singurã valoare, care se poate modifica printr-o
instrucţiune de atribuie sau de citire.
Adresa de memorie a unei variabile este adresa fizicã la care se aflã valoarea
variabilei în memoria calculatorului.
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Fig. 1. Structuri de control.
Schema logicã
Este o reprezentare graficã, ce permite vizualizarea înlãnţuirii şi
subordonãrii secvenţelor de operaţii. Foloseşte simboluri grafice numite blocuri
care prin forma lor, indicã tipul operaţiei.
Pseudocodul
Este o metodã de reprezentare a algoritmilor ce tinde spre un limbaj de
programare, neavând totuşi o sintaxã rigidã, precum limbajele de programare.
Elementele componente ale limbajului pseudocod sunt:
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
• instrucţiuni pentru citire
read lista_variabile
Exemple: read n
• instrucţiuni de atribuire
variabila expresie
Exemple: S 0
S=0
• instrucţiuni decizionale
if condiţie then instructiune_1
else instructiune_2
endif
Exemplu: if x >=0 then write ( “ numar pozitiv”)
else write (“negativ”)
endif
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Exemplul 2) Calculaţi suma primelor n numere naturale ( n este dat):
procedure suma
read n
s0
for i = 1 , n
ss+i
repeat
write (‘suma s =’,s)
end
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Exemplul 1) afişarea primelor 100 numere naturale
i=0
do
i i +1
write i
until i >= 100
Exemplul 2) Afişaţi primele n numere naturale, unde n este dat.
procedure afisare
read n
i=1
do
write i
i i+1
until i >= n+1
end
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
write (‘ suma = ‘, s)
return
end
Apelul procedurii într-o aplicaţie se realizeazã asfel:
call suma
function f ( x )
if x < 5 then f = 3 * x – 5
else if x <= 10 then f = 10
else f = 9 * x +1
endif
endif
end
Apelul functiei se poate realiza asfel:
write f(x)
sau
call f(x)
sau se pot utiliza alte variante de apel, în funcţie de aplicaţie.
• instrucţiunea
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
GOTO etichetã
unde eticheta indicã o instrucţiune din aceeaşi procedurã
Este indicat sã evitãm folosirea instrucţiunii goto deoarece îngreuneazã
înţelegerea algoritmului
2.3. Aplicaţii
Se dau 3 numere reale x, y, z. Sã se calculeze valoarea expresiei:
x + y, z < 0
E= x * y, z = 0
0, z > 0
procedure expresie
integer x, y, z, e
read x, y, z
if z < 0 then e x + y
else if z = 0 then e x * y
else e 0
endif
endif
write (‘expresia E = ‘, e)
return
end
Sã se citeascã n numere reale. Calculaţi şi afişaţi suma celor n numere.
Metoda 1: folosnd o structurã repetitivã “for”
procedure calcul
read n
s0
for i = 1 , n
read x
ss+x
repeat
write (‘suma s =’, s)
end
Metoda 2: folosnd o structurã repetitivã “while”
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
procedure calcul
read n
s0
i=1
while i <= n
read x
ss+x
i i+1
repeat
write (‘suma s =’,s)
end
Metoda 3: folosnd o structurã repetitivã “do-until”
procedure calcul
read n
s0
i=0
do
i i +1
read x
ss+x
until i >= n
write (‘suma s =’,s)
end
Sã se citeascã n natural. Afişaţi divizorii unui numãr n.
procedure divizori
read n
sw 0
for i = 2 , int ( n/2)
if n /i = int ( n/i)
write ( i, ‘ divizor’)
sw 1
endif
repeat
if sw = 0 then write (‘nu exista divizori’)
endif
end
Fie vectorul A = ( a[1], a[2], ..., a[n]), unde n este numãr natural dat. Numãraţi
elementele pare.
procedure divizori
array a[n]
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
read n
sw 0
for i = 1 , n
read ( a[i])
if a[i] mod 2 = 0 { restul impartirii la 2 }
write ( a[i], ‘ numar par’)
sw 1
endif
repeat
for i = 1 to n
write { a[i] )
repeat
if sw = 0 then write (‘nu exista numare pare’)
endif
end
Ordonarea crescãtoare a elementelor unui vector prin interschimbarea elementelor
procedure ordonare
array a[n]
read n
for i = 1 , n
read ( a[i])
repeat
write (‘vectorul initial:’)
for i = 1 to n
write { a[i] )
repeat
for i = 1 to n – 1
for j = i + 1 to n
if a[i] > a[j] then
aux a[i]
a[i] a[j]
a[j] aux
endif
repeat
repeat
write (‘vectorul ordonat crescator:’)
for i = 1 to n
write { a[i] )
repeat
end
Fie o matrice pãtraticã de ordinul n, cu numere întregi. Sã se calculeze suma
elementelor de pe diagonala secundarã a matricei:
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
procedure diagonala
array a[n, n]
read n
for i = 1 , n
for j = 1 to n
read ( a[i, j])
repeat
repeat
write (‘matricea A:’)
for i = 1 to n
for j = 1 to n
write ( a[i, j])
repeat
writeln
repeat
s0
for i = 1 to n
for j = 1 to n
if i + j = n + 1 then s s + a[i, j]
endif
repeat
repeat
write (‘s =’, s)
end
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Probleme propuse
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Capitolul 3
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
- semne de punctuaţie şi semne speciale (unele simboluri
constituie operatori în cadrul expresiilor)
;:,?.“< > =! \&^*+-/%#~
Câteva exemple de simboluri şi semnificaţiile acestora sunt prezentate în
tabelul 1:
semn semnificaţie
# diez
& ampersand
/ slash
\ backslash
~ tilda
Tabelul 1. simboluri C++
\n new line
\t horizontal tab
\v vertical tab
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
3.2. Vocabularul limbajului C++
Vocabularul limbajului C++ este alcãtuit din atomi lexicali:
identificatori
cuvinte cheie
constante
semne de punctuaţie
simboluri speciale
operatori
Constante
– pot fi numere, caractere, şiruri de caractere
- valoarea lor nu se modificã în timpul execuţiei programului
- în limbajul C, existã 4 tipuri de constante ( întregi, reale, de tip
caracter, şiruri de caractere)
- modul de declarare: este urmãtorul:
const tip var = valoare;
Printr-o astfel de declaraţie, se permite asignarea unei valori iniţiale unei
variabile ce nu poate fi modificatã ulterior în program.
Exemple:
i.constante întregi: 179, -28
ii.constante octale ( în baza 8) încep cu cifra 0 pentru identificare: 012,
074, 023
iii. constante hexazecimale încep cu ox: oxA4, oxB7
iv.constante reale – în format F (cu punct zecimal: 0.7, .8, 12.59) şi în
format exponenţial ( 1.4E+3, -2.8E-4 ): const float pi= 3.14;
1.4E+3 = 1.4 * 103
-2.8E-4 = -2.8 * 10-4
v.constante şir de caractere: “program ordonare”
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Observaţii:
• limbajul C++ extinde definiţia constantelor la clase şi funcţii
membru
• o constantã poate fi modificatã indirect prin intermediul unui
pointer, ca în exemplul urmãtor:
const x = 41;
*(int *)&x = 32;
Simboluri speciale
comentarii
// comentariu pe o linie
/*
comentariu pe linii
multiple
*/
sfârşit de linie, de paginã
== egalitate % modulo
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
!= diferit , virgulã ( operator de
secvenţiere)
Clase de precedenţã
Operatorii definesc operaţiile admise de operanzi. În limbajul C++, se pot
folosi urmãtoarele tipuri de operanzi:
- variabile
- constante
- funcţii
- expresii
O clasificare a operatorilor poate sã ia în considerare criterii precum:
• numãrul de operanzi cãrora li se aplicã ( operatori unari ++, - -,
binari +, -, ternari ?: etc.)
• prioritatea avutã în evaluarea expresiilor ( clase de precedenţã)
• tipul operanzilor ( aritmetici, logici, relaţionali, la nivel de bit)
Prioritãtile operatorilor impun ordinea de evaluare a expresiilor.
O clasã de precedenţã conţine operatori cu prioritãţi egale. Categoria 1 de
precedenţã are prioritatea cea mai mare, categoria 2 conţine operatorii unari, care
au prioritate mai micã decât cei din prima clasã, ş.a.m.d. Operatorul virgulã are
cea mai micã prioritate.
Conform precedenţei operatorilor în Borland C++, operatorii se împart în
15 categorii ( tabelul 4):
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Categoria Operator Descriere
1. operatori cu cea
() apel de funcţie
mai mare prioritate
[] indice în tablouri
selecţie indirectã de
componente ( în C++)
:: operatorul de rezoluţie ( în
C++)
. selecţie directã de componente
( în C++)
! NOT ( negaţie logicã)
2. operatori unari
~ NOT pe biţi
+ plus unar
- minus unar
++ incrementare
-- decrementare
& adresã
* indirectare
3. operatori
* înmulţire
multiplicativi
/
împãrţire
% restul modulo
+ plus binar
4. operatori aditivi
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
- minus binar
6. operatori
< mai mic
relaţionali
<= mai mic sau egal
/= atribuire cu împãrţire
+= atribuire cu adunare
-= atribuire cu scãdere
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
^= atribuire cu sau exclusiv pe biţi
Operatorii de atribuire
Sintaxa folositã pentru operaţia de atribuire este urmãtoarea:
expresie_unarã operator_atribuire expresie_de_atribuire
unde expresiile pot avea tipuri de date diferite. În limbajul C++ se fac conversii
implicite de tip, existând relaţia:
sizeof ( int) <= sizeof ( float) <= sizeof ( double)
De exemplu, în expresia E1 = E2, E1 trebuie sã fie o valoare-stângã
modificabilã. Valoarea lui E2 ( dupã conversia de tip), este memoratã în obiectul
E1. Pentru ambele tipuri de atribuire ( simplã şi compusã), operanzii E1 şi E2
trebuie sã respecte una dintre urmãtoarele reguli:
1. E1 şi E2 sunt de tip aritmetic
2. E1 şi E2 sunt de tip structurã sau uniune
3. E1 şi E2 sunt de tip pointer
4. unul dintre E1 sau E2 este de tip pointer la un obiect, iar celãlalt este
pointer de tip void
5. E1 este un pointer şi E2 este un pointer null constant.
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
E1 = 1
E1 = E1 + E2
sau *p ( un pointer), însã expresia E1 + E2 nu este o valoare-stângã
(exemplu: E1 + E2 =7).
Exemplu de atribuire cu conversie de tip:
int a, b;
float m, n;
a = m; // a [ m ]
// sau variabilei a i se atribuie o valoare aleatoare, dacã se
//depãşesc posibilitãţile de memorare
n = b; // b va fi reprezentat în virgulã mobilã
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
sintaxa :
- - operand ( prefix)
sau
operand - - ( postfix)
unde operandul trebuie sã fie de tip scalar ( aritmetic sau pointer) şi sã fie o
valoare-stângã modificabilã.
Pentru decrementare prefixatã, valoarea operandului scade cu 1, iar
valoarea expresiei este valoarea obţinutã dupã decrementare.
Pentru decrementare postfix, valoarea expresiei este valoarea dinainte de
aplicarea decrementãrii. Dupã decrementarea postfix, valoarea operandului
scade cu 1.
Exemplu :
int x = 10, y, z ;
y = x - - ; // y = x =10 şi x = x - 1 = 9
z = - -x ; // x =x - 1 = 9 - 1 = 8 şi z = x = 8
Operatorii aritmetici
- operatorii aditivi : + şi -
Sintaxa operatorilor unari + şi – se poate exprima astfel:
+ operand respectiv – operand
unde operandul trebuie sã fie de tip arithmetic.
Exemplu :
int x = 10, y, z ;
z = +x ; // z =10
y = -x; //y = -10
Sintaxa operatorilor binari + şi – respectã regula expresiilor combinate, cu
unul sau mai mulţi operatori:
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
operand_1 + operand_2 respectiv operand_1 - operand_2
unde operanzii trebuie sã fie de tip aritmetic sau unul dintre operanzi poate sã
fie pointer cãtre un anumit tip de obiecte.
Exemplu :
int x = 10, y = 100, z ;
z = x + y ; // z = 110
z = x - y; //z = -90
- operatorii multiplicativi: *, /, %
Sintaxa operatorilor multiplicativi:
operand1 * operand2 ( înmulţirea a douã numere)
operand1 / operand2 ( împãrţirea a douã numere, al doilea fiind nenul)
operand1 % operand2 ( restul împãrţirii a douã numere, al doilea fiind nenul)
unde operanzii trebuie sã fie de tip aritmetic, iar conversiile de tip sunt cele
uzuale. Operatorul / aplicat unor operanzi întregi furnizeazã un rezultat întreg
şi aplicat unor operanzi reali produce un rezultat real.
Exemplu :
int x = 10, y = 7, z ;
z = x * y ; // z = 70
z = x / y ; //z =1
z = x % y ; // z = 3
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Dacã ambii operanzi sunt aritmetici, rezultatul expresiei relaţionale este 1
( true) sau 0 ( false).
Când operanzii sunt pointeri, atunci expresia operand1 == operand2 are
ca rezultat 1 ( true), dacã ambii pointeri sunt NULL sau dacã pointerii se referã la
acelaşi obiect.
Operatorii logici
- negaţie logicã ( ! operand) - expresia ( ! operand) este echivalentã cu expresia
(operand ==0)
- şi logic (operand1 && operand2)
- sau logic (operand1 || operand2)
Operanzii trebuie sã fie de tip scalar. Sunt realizate conversiile aritmetice
uzuale pentru operanzi.
Operatorii && şi || sunt evaluaţi de la stânga la dreapta astfel:
• operand1 este evaluat primul: dacã operand1 este 0, atunci operand1 &&
operand2 este implicit 0 şi operand2 nu se mai evalueazã
• operand1 este evaluat primul: dacã operand1 este 1, atunci operand1 ||
operand2 este implicit 1 şi operand2 nu se mai evalueazã.
Exemplu : fie douã variabile x şi y de tip întreg, atunci expresiile logice
construite cu ajutorul operatorilor !, &&, || sunt evaluate în tabelul 5 :
x y !x x && y x || y
1 1 0 1 1
1 0 0 0 1
0 1 1 0 1
0 0 1 0 0
Tabelul 5.operatori logici
Operatorii pe biţi
• operatorii pe biţi sunt:
- negaţie pe biţi ( ~ operand)
- şi pe biţi (operand1 & operand2)
- sau pe biţi (operand1 | operand2)
- sau exclusiv pe biţi (operand1 ^ operand2)
• se aplicã operanzilor de tip int sau char, nu se aplicã valorilor de tip float,
double, long double
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Exemplu : fie douã variabile x şi y de tip întreg, atunci expresiile logice
construite cu ajutorul operatorilor !, &&, || sunt evaluate în tabelul 6 :
Operatorii shift
• operatorul shift stânga (variabilã << numãr) deplaseazã biţii variabilei cu un
numãr de poziţii la stânga; la deplasarea spre stânga, biţii liberi din dreapta
se completeazã cu 0 ( zero)
• operatorul shift dreapta (variabilã >> numãr) deplaseazã biţii variabilei cu
un numãr de poziţii la dreapta; la deplasarea spre dreapta, biţii liberi din
stânga se completeazã cu:
- 0 ( zero), dacã numãrul este fãrã semn
- 1 ( unu), dacã numãrul este negativ
• operaţiile de deplasare pe biţi la stânga şi dreapta sunt echivalente cu
înmulţirea, respectiv împãrţirea cu 2 la o putere egalã cu numãrul de biţi
deplasaţi:
x << n este echivalentã cu x * 2n
x >> n este echivalentã cu x / 2n
• exemplu: pentru x = 5, n =2
x << n = 5 << 2 = 0000 0101 << 2 = 0001 0100
0001 0100 = 0*20+ 0*21 + 1*22 + 0* 23+ 1*24 = 0 + 0 + 4 + 0 + 16 = 20
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
x * 2n = 5 * 22 = 20
Deci 5 << 2 = 0001 0100 = 20 = 5 * 22
• un exemplu de deplasare shift pe biţi pentru un numãr negativ:
pentru x = -6, n = 3
Se complementeazã cu 1:
-6(2) = ~6(2) + 1 = ~0000 0110 + 1 = 1111 1001 + 1 = 1111 1010
-6(2) >> 3 = 1111 1010 >> 3 ( se pierd ultimii trei biţi) = 1111 1111
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Capitolul 14
14.1. Clase
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Sintaxa utilizatã pentru declararea tipurilor class, struct şi union poate fi
exprimatã astfel:
<cuvânt_cheie> [ <identificator>] [ : <lista_clase_bazã>]
{
tip1 lista_membri_1;
tip2 lista_membri_2;
..................
} [ listã_variabile];
unde <cuvânt_cheie> este unul dintre cuvintele cheie class, struct sau union;
<identificator> reprezintã numele tipului de date definit ( class, struct sau
union);
<lista_clase_bazã> - lista claselor de bazã din care derivã aceastã clasã, fiind
opţionalã;
lista_membri_1, lista_membri_2, . . . sunt liste de date şi funcţii membre;
tip1, tip2, . . . desemneazã tipurile de date ale elementelor membre.
Un exemplu de clasã definitã pentru reprezentarea numerelor raţionale
poate fi urmãtorul:
class rational
{
int p, q;
};
rational a, *b = &a;
p
Exemplu: Sã se defineascã o clasã pentru numere raţionale , unde p, q
q
∈ Z ( clasa conţine date private şi metode publice pentru iniţializarea şi afişarea
numãrãtorului şi numitorului unei fracţii).
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
#include<stdio.h>
#include<conio.h>
class rational
{
int p, q;
public:
void fractie( int x, int y)
{
p = x;
q = y;
}
int numarator()
{
return p;
}
int numitor()
{
return q;
}
}a;
void main(void)
{
clrscr();
a.fractie(7,8);
printf("\n fractia: %d / %d ", a.numarator(), a.numitor());
getche();
}
#include<stdio.h>
#include<conio.h>
int i = 10;
void main()
{
int i = 15;
clrscr();
printf("\n variabila globala ( din exteriorul functiei main) i = %i",::i);
printf("\n variabila locala (din main) i = %i",i);
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
getch();
}
#include<stdio.h>
#include<conio.h>
class rational
{
int p, q;
public:
void fractie( int, int);
int numarator();
int numitor();
}a;
void main(void)
{
clrscr();
a.fractie(20,42);
printf("\n fractia: %d / %d ", a.numarator(), a.numitor());
getche();
}
void rational::fractie( int x, int y)
{ p = x;
q = y;
}
int rational::numarator()
{ return p;
}
int rational::numitor()
{ return q;
}
Constructori şi destructori
Constructorul generat implicit este o metodã specialã ataşatã în mod
implicit unei clase, pentru declararea obiectelor. Astfel, se alocã spaţiul de
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
memorie necesar obiectelor declarate. O clasã poate avea mai mulţi constructori,
cu restricţia ca metodele constructor sã difere prin numãrul şi tipul parametrilor
formali. Existã un tip special de constructor numit constructor de copiere care
atribuie datele unui obiect altui obiect.
Destructorul este o metodã specialã ataşatã unei clase, ce realizeazã
operatia inversã alocãrii obiectelor, adicã eliberarea memoriei. Numele
destructorului este acelaşi cu numele clasei, dar este precedat de caracterul ~. O
clasã are un singur destructor. Destructorul nu are parametri formali, el fiind
apelat implicit atunci când existenţa unui obiect înceteazã.
Funcţiile prieten sunt funcţiile care nu aparţin unei clase, dar pot accesa
datele private ale acesteia. Pentru a ataşa unei clase o funcţie prieten, se
introduce în interiorul definiţiei clasei prototipul funcţiei prieten, precedat de
cuvântul cheie “friend”, iar definiţia funcţiei se efectueazã în exteriorul clasei.
14.2. Moştenire
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
mostenire protected
- membrii private → private
mostenire protected
- membrii protected şi public → protected
Moştenirea de tip public:
mostenire public
- membrii private → private
mostenire public
- membrii protected → protected
mostenire public
- membrii public → public.
Moştenirea multiplã presupune crearea unor clase derivate din mai multe
clase de bazã. În aceste cazuri, constructorii se apeleazã în ordinea in care sunt
scrise clasele în liste de moştenire a clasei derivate.
#include<stdio.h>
#include<conio.h>
int i, j, n, m, x, y, k, sw;
class graf
{
public:
int a[10][10]; //matrice de adiacenta a muchiilor
int e[10][10]; // matrice de existenta a lanturilor
void citire();
void tiparire();
void Roy_Warshall();
};
class graf1 : public graf
{
public:
int conex();
int vf_izolate();
void vf_gr_max();
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
}a;
void graf::citire()
{
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
a[i][j] = e[i][j] = 0;
printf("\n Dati muchiile grafului: ");
for(i = 1; i <= m; i++)
{
printf("\n muchia %d \n",i);
scanf("%d %d",&x, &y);
e[x][y] = e[y][x] = 1;
a[x][y] = a[y][x] = 1;
}
}
void graf::tiparire()
{
printf("\n Matricea de adiacenta\n");
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; j++)
printf(" %d ",a[i][j]);
printf("\n");
}
printf("\n Matricea de existenta a lanturilor\n");
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; j++)
printf(" %d ", e[i][j]);
printf("\n");
}
}
void graf::Roy_Warshall()
{
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
if(e[i][j] == 1)
for(k = 1; k <= n; k++)
if(e[i][k] < e[j][k])
e[i][k] = e[k][i] = e[j][k];
// matrice simetrica fata de diagonala principala
}
int graf1::conex()
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
{
sw = 1;
for(i =1; i <=n; i++)
for(j=1; j <= n; j++)
if (e[i][j] == 0)
sw = 0;
return sw;
}
int graf1::vf_izolate()
{
for(i = 1; i<=n; i++)
{
sw = 1;
for(j = 1; j <= n; j++)
if (e[i][j] == 1)
sw = 0;
if (sw == 1)
{ printf("\n %d varf izolat", i);
return sw;
}
}
return 0;
}
void graf1::vf_gr_max()
{
int max, poz;
for(i = 1; i<=n; i++)
{
a[i][n+1] = 0;
for(j = 1; j <= n; j++)
if (a[i][j]) a[i][n+1]++;
}
max = a[1][n+1]; poz = 1;
for ( i = 2; i <= n; i++)
if(a[i][n+1] > max)
{ poz = i;
max = a[i][n+1];
}
printf("\n varful de grad maxim este %d si are gradul %d",poz, max);
}
void main(void)
{
clrscr();
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
printf("\n nr de varfuri n = "); scanf("%d", &n);
printf("\n numarul de muchii: "); scanf("%d",&m);
a.citire();
a.Roy_Warshall();
a.tiparire();
if (a.conex() == 0) printf ("\n graful nu este conex");
else printf("\n graf conex");
if (a.vf_izolate() == 0)
printf("\n nu exista varfuri izolate");
a.vf_gr_max();
getche();
}
• Test 2:
Pentru graful din figura 8.2., se
pot introduce datele:
- numãrul de vârfuri n = 3
- numãrul de muchii m = 3
- muchia 1: 1 2
- muchia 2: 1 3 Fig. 8.2. Test 2
- muchia 3: 2 3
Rezultate: graf conex
nu exista varfuri izolate
varful de grad maxim este 1 si are gradul 2
• Test 3:
Pentru graful din figura 8.3., se
pot introduce datele:
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
- numãrul de vârfuri n = 5
- numãrul de muchii m = 4
- muchia 1: 1 2
- muchia 2: 1 3
- muchia 3: 1 4 Fig. 8.3. Test 3
- muchia 4: 2 4
Rezultate: graful nu este conex
5 varf izolat
varful de grad maxim este 1 si are gradul 3
• Test 4:
Pentru graful din figura 8.4., se
pot introduce datele:
- numãrul de vârfuri n = 6
- numãrul de muchii m = 6
- muchia 1: 1 2
- muchia 2: 1 4 Fig. 8.4. Test 4
- muchia 3: 2 5
- muchia 4: 3 5
- muchia 5: 3 6
- muchia 6: 5 6
Rezultate: graf conex
nu exista varfuri izolate
varful de grad maxim este 5 si are gradul 3
14.3. Supraîncãrcare
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
unde operator <identificator> defineşte o nouã acţiune asociatã unui operator
prin supraîncãrcare.
Supraîncãrcarea operatorilor +, *, -
Exemplul 1): Supraîncãrcarea operatorilor + şi * poate fi evidenţiatã în
programul de calculare a sumei şi produsului a douã matrice. Se vor folosi douã
clase:
• o clasã care memoreazã informaţii despre elementele matricelor şi metode
pentru operaţiile de citire şi scriere;
• a doua clasã derivatã din prima clasã, care sã defineascã supraîncãrcarea
operatorilor + şi *.
#include<stdio.h>
#include<conio.h>
class matrice1
{
public:
int inf[12][12];
void citire();
void tiparire();
};
class matrice2 : public matrice1
{
public:
matrice2 operator+(matrice2);
matrice2 operator*(matrice2);
}a, b, c;
int i, j, n, s, k;
void matrice1::citire()
{
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
{
printf("\n inf[%d][%d]= ",i,j);
scanf("%d", &inf[i][j]);
}
}
void matrice1::tiparire()
{
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
printf(" %d ",inf[i][j]);
printf("\n ");
}
}
matrice2 matrice2::operator+(matrice2 a)
{
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
c.inf[i][j] = inf[i][j] + a.inf[i][j];
return(c);
}
matrice2 matrice2::operator*( matrice2 a)
{
for(i = 0; i < n; i++)
for(j = 0; j < n; j++)
{
s = 0;
for(k = 0; k < n; k++)
s += inf[i][k] * a.inf[k][j];
c.inf[i][j] = s;
}
return(c);
}
void main(void)
{
clrscr();
printf("\n nr de linii/coloane n = "); scanf("%d", &n);
printf("\n dati matricea A:\n "); a.citire();
printf("\n dati matricea B:\n "); b.citire();
printf("\n matricea A este:\n "); a.tiparire();
printf("\n matricea B este:\n "); b.tiparire();
printf("\n matricea suma A + B:\n ");
c = a + b;
c.tiparire();
printf("\n matricea produs A * B:\n ");
c = a * b;
c.tiparire();
getche();
}
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Rezultatele compilãrii programului:
6 4 19 4
matricea suma A + B = , matricea produs A * B =
10 5 43 10
1 0 2 1 2 1
Test 2: n = 3, A = 3 4 1 , B = 7 0 3
5 1 2 4 1 5
Rezultatele compilãrii programului:
2 2 3
matricea suma A + B = 10 4 4 ,
9 2 7
9 4 11
matricea produs A * B = 35 7 20 .
20 12 18
#include<iostream.h>
#include<conio.h>
char ch;
class multime
{
public:
int inf[10], n;
void citire();
void afisare();
};
class multime1 : public virtual multime
{
public:
multime1 operator*(multime1);
multime1 operator+(multime1);
multime1 operator-(multime1);
void operator=(multime1);
}a, b, c;
int i, j, n, x, sw;
void multime::afisare()
{
if(!n)
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
cout<<"multime vida";
for(i=1; i<=n;i++)
cout<<inf[i]<<" ";
}
void multime::citire()
{
if (n <= 0 )
return;
cout<<endl<<"elementele multimii: ";
cout<<"\n inf[1]= ";
cin>>inf[1];
i = 1;
while( i < n)
{
cout<<"\n inf["<<i+1<<"]= ";
cin>>x;
sw = 1;
for(j = 1; j <= i; j++)
if(inf[j] == x)
sw = 0;
if(sw)
{
i++;
inf[i] = x;
}
}
}
multime1 multime1::operator*(multime1 b)
{
sw = 0;
for(i = 1; i <= n;i++)
for(j = 1; j <= b.n;j++)
if(inf[i] == b.inf[j])
{
sw++;
c.inf[sw] = inf[i];
}
if(sw == 0)
cout<<"\n multime vida";
c.n = sw;
return(c);
}
void multime1::operator=(multime1 b)
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
{
for(i = 1; i <= b.n;i++)
inf[i] = b.inf[i];
n = b.n;
}
multime1 multime1::operator-(multime1 a)
{
x = 0;
for(i = 1; i <= n;i++)
{
sw = 0;
for(j = 1; j <= a.n;j++)
if(inf[i] == a.inf[j])
sw = 1;
if(!sw)
c.inf[++x] = inf[i];
}
c.n = x;
return(c);
}
multime1 multime1::operator+(multime1 a)
{
x = 0;
for(i = 1; i <= n;i++)
{
sw = 0;
for(j = 1; j <= a.n;j++)
if(inf[i] == a.inf[j])
sw = 1;
if(sw == 0) c.inf[++x] = inf[i];
}
for(i = 1; i <= a.n;i++)
c.inf[++x] = a.inf[i];
c.n = x;
return(c);
}
void main(void)
{
clrscr();
cout<<endl<<"dati numarul de elemente ale multimii A: ";
cin>>a.n;
a.citire();
cout<<endl<<"dati numarul de elemente ale multimii B: ";
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
cin>>b.n;
b.citire();
cout<<endl<<"\n multimea A: ";
a.afisare();
cout<<endl<<"\n multimea B: ";
b.afisare();
c = a;
cout<<endl<<"\n atribuire: C = A = ";
c.afisare();
c = a - b;
cout<<endl<<"\n diferenta: C = A - B = ";
c.afisare();
c = a * b;
cout<<endl<<"\n intersectia: A * B = ";
c.afisare();
c = a + b;
cout<<endl<<"\n reuniune: A + B = ";
c.afisare();
getche();
}
Supraîncãrcarea operatorilor [ ], ( ) şi =
#include<stdio.h>
#include<conio.h>
int i, n, s, p;
class vector
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
{
int nr[100];
public:
int& operator[](int);
void citire();
void tiparire();
};
int& vector::operator[](int i)
{ return nr[i];
}
void vector::citire()
{
for(i = 0; i < n; i++)
{
printf("\n nr[%d] = ",i);
scanf("%d",&nr[i]);
}
}
void vector::tiparire()
{
printf("\n Vectorul\n");
for(i = 0; i < n; i++)
printf("%d ",nr[i]);
}
void main(void)
{
vector a;
clrscr();
printf("\n ne elemente ale vectorului n = ");
scanf("%d", &n);
printf("\n dati vectorul: ");
a.citire();
a.tiparire();
s = 0;
for(i = 0; i < n; i++)
s+= a.operator[](i);
printf("\n suma elementelor = %d", s);
p = 1;
for(i = 0; i < n; i++)
p *= a.operator[](i);
printf("\n produsul elementelor (metoda 1) = %d", p);
p = 1;
for(i = 0; i < n; i++)
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
p *= a[i];
printf("\n produsul elementelor (metoda 2) = %d", p);
getche();
}
Observaţii:
• în program, s-au utilizat notaţiile echivalente:
a.operator[ ] (i) ⇔ a[i]
• metoda operator[ ] declaratã astfel:
int& operator[](int);
returneazã valoarea membrului privat nr. Pentru tipul datelor returnate, se
foloseşte int& (lvalue required).
#include<stdio.h>
#include<conio.h>
int i, j, n;
class matrice
{
public:
int inf[10][10];
int& operator()(int, int);
void citire();
}a;
int& matrice::operator()(int i, int j)
{
return inf[i][j];
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
}
void matrice::citire()
{
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
{
printf("\n inf[%d][%d]= ",i,j);
scanf("%d",&inf[i][j]);
}
}
void main(void)
{
clrscr();
printf("\n nr de varfuri n = "); scanf("%d", &n);
a.citire();
printf("\n Matricea\n");
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; j++)
printf(" %d ",a.operator()(i,j));
printf("\n");
}
printf("\n Matricea transpusa\n");
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; j++)
printf(" %d ",a(j,i));
printf("\n");
}
getche();
}
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
int nr[10][10];
public:
int operator=(matrice);
} a, b;
În programul urmãtor, se propune verificarea egalitǎţii a douǎ matrice,
folosind supraîncãrcarea operatorului =.
#include<stdio.h>
#include<conio.h>
int i, j, n;
class vector
{
public:
int inf[10], n;
int operator=(vector);
void citire();
void afisare();
}a, b;
int vector::operator=(vector b)
{
int sw;
sw = 1;
if(b.n != n)
sw = 0;
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
if (inf[i] != b.inf[i])
sw = 0;
return sw;
}
void vector::citire()
{
for(i = 1; i <= n; i++)
{
printf("\n inf[%d]= ",i);
scanf("%d",&inf[i]);
}
}
void vector::afisare()
{
for(i = 1; i <= n; i++)
printf(" %d ",inf[i]);
}
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
void main(void)
{
clrscr();
printf("\n nr de elemente ale vectorului A: n = ");
scanf("%d", &a.n);
a.citire();
printf("\n nr de elemente ale vectorului B: n = ");
scanf("%d", &b.n);
b.citire();
printf("\n Vectorul A\n");
a.afisare();
printf("\n Vectorul B\n");
b.afisare();
if( a = b) printf("\n vectorii au elementele egale");
if(!a.operator=(b)) printf("\n nu exista egalitate");
getche();
}
Supraîncãrcarea funcţiilor
Funcţiile pot fi supraîncǎrcate, adicǎ pot exista douǎ sau mai multe funcţii
cu acelaşi nume în clase derivate. Existǎ o restricţie, în sensul cǎ funcţiile trebuie
sǎ difere prin numǎrul şi tipul parametrilor formali.
#include<stdio.h>
#include<conio.h>
class A
{
public:
int i;
void afisare()
{
printf("\n clasa de baza A: i = %d",i);
}
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
};
class B : public A
{
public:
int i;
void afisare()
{
printf("\n clasa derivata B: i = %d",i);
}
}y;
void main(void)
{
clrscr();
y.A::i = 99;
y.A::afisare();
y.i = 10;
y.afisare();
getche();
}
#include<iostream.h>
#include<math.h>
#include<conio.h>
class radical
{
public:
float sqrt(int);
}x;
float radical::sqrt(int a)
{
return(::sqrt(a));
}
int n;
char c;
void main(void)
{
clrscr();
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
do
{
do
{
cout<<endl<<"dati numarul n:";
cin>>n;
}
while(n<=0);
cout<<endl<<x.sqrt(n);
cout<<endl<<"mai dati un numar? (d/n)";
cin>>c;
}
while(c!='n' && c!='N');
}
14.4. Polimorfism
#include<iostream.h>
#include<conio.h>
#include<stdio.h>
void afisare (int);
void afisare(char[]);
void main(void)
{
int nr;
char sir[20];
clrscr();
cout<<"\n dati un numar: ";
cin>>nr;
cout<<"\n dati un sir de caractere ";
gets(sir);
afisare(nr);
afisare(sir);
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
getche();
}
void afisare (int nr)
{
cout<<"\n Numarul este: "<<nr;
}
void afisare( char sir[])
{
puts("\n Sirul este: ");
puts(sir);
}
Legãtura staticã
Dacã decizia asupra versiunii care se executã la apelul unei funcţii
supraîncãrcate este luatã în momentul compilãrii, atunci spunem cã funcţia
realizeazã o legãturã staticã.
#include<iostream.h>
#include<conio.h>
class punct
{
public:
float aria()
{
return 0;
}
}ob1;
class patrat: public punct
{
float l;
public:
setare(float x)
{
if(x>=0)
l = x;
else l =x;
}
float aria()
{
return l * l;
}
}ob2;
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
void main(void)
{
punct *p;
patrat *q;
int nr;
clrscr();
cout<<"\n dati latura patratului: ";
cin>>nr;
ob2.setare(nr);
cout<<"\n obiectul 1: "<<ob1.aria();
cout<<"\n obiectul 2: "<<ob2.aria();
p = &ob1;
cout<<"\n pointerul p la ob1 (din clasa punct): "<<p->aria();
q = &ob2;
cout<<"\n pointerul q la ob2 (din clasa patrat): "<<q->aria() ;
getche();
}
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
Avantajele folosirii claselor virtuale
• flexibilitate crescutǎ în reutilizarea şi dezvoltarea claselor existente;
• funcţiile deja concepute pot fi adaptate unor clase noi, fãrã a fi necesarã
modificarea lor.
Un dezavantaj al utilizãrii funcţiilor virtuale constã în creşterea
consumului de memorie şi a timpului de executie, prin utilizarea tabelului de
funcţii virtuale.
#include<stdio.h>
#include<conio.h>
class forme
{
public:
virtual float aria()=0;
virtual float perimetrul() = 0;
}*a;
class patrat : public forme
{
float l;
public:
patrat(float l);
float aria();
float perimetrul();
};
patrat::patrat(float x)
{
l = x;
}
float patrat::aria()
{
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
return l*l;
}
float patrat::perimetrul()
{
return(4*l);
}
void main(void)
{
float x;
clrscr();
do
{
printf("\n dati latura patratului: ");
scanf("%f",&x);
}
while(x<=0);
patrat p(x);
a = &p;
printf("\n aria = %.2f",a->aria());
printf("\n perimetrul = %.2f", a->perimetrul());
getche();
}
Exemplul 2): Sã se defineascǎ douǎ clase, prima clasǎ de bazǎ, iar a doua
clasǎ, derivatǎ din clasa de bazǎ, care sǎ redefineascǎ o funcţie virtualǎ pentru afişarea
unui mesaj. Sǎ se dfineascǎ pointeri cǎtre cele douǎ clase şi sǎ se evidenţieze
legǎtura dinamicǎ.
#include<iostream.h>
#include<conio.h>
class B
{
public:
virtual void afisare();
};
class D : public B
{
public:
virtual void afisare();
};
void B::afisare()
{
cout<<"\n apel functie din clasa de baza B";
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
}
void D::afisare()
{
cout<<"\n apel functie din clasa derivata D";
}
void main(void)
{
clrscr();
B *p = new B;
p->afisare();
delete p;
D *q = new D;
q->afisare();
delete q;
//legatura dinamica
B *p1;
D p2;
p1 = (B*) &p2;
cout<<"\n legatura dinamica";
p1->afisare();
getche();
}
#include<iostream.h>
#include<conio.h>
int i, j, n, s, nr;
char ch;
class tablou
{
public:
virtual void citire() = 0;
virtual void scriere() = 0;
virtual int suma() = 0;
};
class vector: public tablou
{
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
int n, inf[12];
public:
vector(int);
void citire();
void scriere();
int suma();
};
vector::vector( int nr)
{
n = nr;
}
void vector::citire()
{
for(i=1;i<=n;i++)
{
cout<<"\n inf["<<i<<"]=";
cin>>inf[i];
}
}
void vector::scriere()
{
for(i=1; i<=n; i++)
cout<<inf[i]<<" ";
}
int vector::suma()
{
s = 0;
for(i=1; i<=n; i++)
s+=inf[i];
return s;
}
void main(void)
{
clrscr();
do
{
cout<<endl<<"numarul de elemente ale vectorului: ";
cin>>n;
}
while(n<=0);
vector v(n);
cout<<endl<<"dati elementele vectorului: ";
v.citire();
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
cout<<endl<<"vectorul: ";
v.scriere();
cout<<endl<<"suma elementelor vectorului: "<<v.suma();
getche();
}
#include<iostream.h>
#include<conio.h>
#include<ctype.h>
class lista
{
public:
int nr;
lista* urm;
}*p, *pr, *ul;
int s, nr;
char ch;
class tablou
{
public:
virtual void citire() = 0;
virtual void scriere() = 0;
virtual int suma() = 0;
};
class lista1: public tablou
{
lista *prim, *ultim;
public:
void citire();
void scriere();
int suma();
lista1 operator+(lista1);
}l1, l2, l3;
void lista1::citire()
{
ultim = prim = NULL;
do
{
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
if(ultim ==NULL)
{
ultim = new lista;
cout<<endl<<"Dati nr: ";
cin>>nr;
ultim->nr = nr;
ultim->urm = NULL;
prim = ultim;
}
else
{
p = new lista;
cout<<endl<<"Dati urmatorul element: ";
cin>>nr;
p->nr = nr;
p->urm = NULL;
ultim->urm = p;
ultim = p;
}
cout<<"mai introduceti elemente?(d/n)";
ch = getche();
}while(toupper(ch)!='N');
}
void lista1::scriere()
{
if(prim == NULL)
cout<<"\n lista vida";
else
for(p = prim; p; p = p->urm)
cout<<" "<<p->nr;
}
lista1 lista1::operator+(lista1 l2)
{
pr = prim;
ul = ultim;
ul->urm = l2.prim;
ul= l2.ultim;
l3.prim = pr;
l3.ultim = ul;
return(l3);
}
int lista1::suma()
{
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
s=0;
for(p=prim;p;p=p->urm)
s+=p->nr;
return s;
}
void main(void)
{
clrscr();
lista1 l1, l2;
cout<<endl<<" dati lista l1: ";
l1.citire();
cout<<"\n\n lista 1: ";
l1.scriere();
cout<<"\n\n suma elementelor listei l1 = "<<l1.suma();
cout<<"\n\ndati lista l2: ";
l2.citire();
cout<<"\n\n lista l2: ";
l2.scriere();
cout<<"\n\n l1 + l2 = ";
l3 = l1 + l2;
l3.scriere();
getche();
}
Probleme propuse
9. Sǎ se scrie un program C++ care sǎ redefineascã operatorii de atribuire simplã
şi compusã, ca funcţii membru pentru urmãtoarele clase:
a. numere complexe
b. şiruri de caractere
= ( atribuire)
+= ( concatenarea şirurilor, cu pãstrarea rezultatului în şirul curent)
-= ( ştergerea unui subşir dintr-un şir)
c. liste dublu înlãnţuite
= atribuire simplã ( copierea unei liste în altã listã)
+= atribuire compusã ( adãugarea unui element la o listã şi
concatenarea cu o altã listã)
d. arbori binari
+= inserarea unui element
-+ ştergerea unui element.
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
BIBLIOGRAFIE
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010
14. Tudor N. L., Contribuţii privind optimizarea tehnicilor de accesare a
obiectelor din baze de date relaţionale – tezã de doctorat, Universitatea
POLITEHNICA Bucureşti, 2009
15. Tudor S., Bazele programãrii în C++, Editura L&S INFOMAT, 1997
16. Tudor S., Tehnici de programare, Editura Teora, 1996
17. Williams M., Bazele Visual C++ 4, Editura Teora, 1997
18. Wirth N., Systematic Programming: An Introduction, Prentice Hall, 1972
19. *** Borland C++, versiunea 3.1, Help, 1990
Tudor L., Bazele programãrii în limbajul C++, Editura MATRIX ROM, Bucureşti, ISBN 978-973-755-644-8, 2010