Documente Academic
Documente Profesional
Documente Cultură
haideti sa incepem cu un program c++ simplu, care afiseaza un mesaj. acest program
utilizeaza facilitatea cout a lui c++ pentru a produce o iesire de tip caracter. codul sursa
contine mai multe comentarii adresate cititorului; aceste linii incep cu //, iar compilatorul
le ignora. c++ este sensibil la tipul literelor; adica face deosebire intre majuscule si litere
mici. aceasta inseamna ca trebuie sa fiti atenti si sa utilizati acelasi tip de litere.
nota de compatibilitate
daca utilizati un compilator mai vechi, este posibil sa fiti nevoit sa folositi #include
<iostream.h> in loc de #include <iostream>; in acest caz va trebui sa eliminati si linia
using namespace std;
unele medii bazate pe ferestre ruleaza programul intr-o fereastra separata pe care o inchid
automat la terminarea programului. puteti face ca fereastra sa ramana deschisa pana la
actionarea unei taste, prin introducerea inaintea instructiunii de returnare a urmatoarei
linii de cod: cin.get();
intrati si iesiri in c
daca ati mai programat in c, veti avea un mic soc cand veti vedea cout in loc de printf().
de fapt c++ poate utiliza printf(), scanf() si toate celelalte functii de intrare si iesire c
standard in cazut in care ati inclus fisierul c uzual stdio.h.
haideti sa privim mai detaliat aceste elemente. functia main() este un loc bun de pornire,
deoarece unele dintre caracteristicile care preceda functia main(),*censored*ar fi
directiva de preprocesor, sunt mai usor de inteles dupa ce vedeti ce face main().
functia main()
dupa ce am inlaturat toate dichisurile, programul exemplu are urmatoarea structura
fundamentala:
int main()
{
instructiuni
return 0;
}
aceste linii indica faptul ca aveti o functie numita main() si descriu comportamentul
acestei functii. impreuna, ele constituie o definitie de functie. aceasta definitie are doua
parti: prima linie, int main(), care este numita antetul functiei si o portiune inchisa dintre
acolade { si }, care este corpul functiei. antetul functiei este o capsula care contine
rezumatul interfetei dintre functie si restul programului, iar corpul functiei reprezinta
instructiunileadresate calculatorului cu privire la comportamentul functiei. in c++ fiecare
actiune completa se numeste instructiune. fiecare instructiune trebuie sa se incheie cu
caracterul punct si virgula (;), deci nu omiteti aceste caractere. ultima instructiune in
main(), numite instructiune de returnare, incheie functia.
#include <iostream>
using namespace std;
in cazul in care compilatorul dumneavoastra nu este multumit de aceste doua linii (de
exemplu se plange ca nu poate gasi fisierul iostream), incercati in locul lor urmatoarea
linie:
comentariile in c++
zona de nume
daca folositi iostream in loc de iostream.h, atunci trebuie sa folositi urmatoarea directiva
de zona de nume, pentru ca definitiile din iostream sa fie disponibile in programul
dumneavoastra:
using namespace std;
aceasta este directiva using. facilitatea zona de nume este o caracteristica noua in c++
care are ca scop simplificarea scrierii programelor in care se combina cod existent de la
mai multi furnizor. o problema potentiala este ca puteti folosi doua pachete de cod care au
amandoua o functie cu acelasi nume, sa zicem leet(). daca folositi functia leet(),
compilatorul nu va sti care versiune trebuie sa fie apelata. facilitatea zona de nume
permite unui furnizor sa isi impacheteze software-ul intr-o unitate numita zona de nume,
asa incat pot folosi numele acestei unitati pentru a indica exact produsul pe care doriti sa
il folositi precum si producatorul acestuia. deci agressor poate sa isi plasese definitiile
intr-o zona de nume numita agressor. atunci numele complet al functiei proprii
agressor::leet().
in acest spirit, clasele, functiile si variabilele care sunt componente standard ale
compilatoarelor c++ sunt plasate acum intr-o zona de nume numita std. aceasta se aplica
doar pentru fisierele antet fara .h. de exemplu, variabila cout folosita pentru iesiri si
definita in iostream are de fapt numele std::cout.
cout si printf()
daca v-ati obisnuit cu c si cu printf(), poate ca veti considera ca cout arata ciudat. poate
veti prefera chiar sa nu renuntati la greu castigata maiestrie obtinuta de dumneavoastra in
utilizarea lui printf(). dar cout nu este cu nimic mai ciudat in aspect decat printf(), cu
toate specificatiile sale de conversie. iar un lucru important este acela ca cout are avantaje
semnificative. aptitudinea sa de a recunoaste tipurile de date demonstreaza o proiectare
inteligenta, care nu permite aparitia greselilor. de asemene, este si extensibil. adica, puteti
redefini operatorul << astfel incat cout sa poata recunoaste si afisa tipurile de date noi,
definite de dumneavoastra. si daca va place controlul fin furnizat de printf(), puteti obtine
aceleasi efecte prin utilizarile mai avansate ale lui cout.
utilizarea cin
privind aceasta instructiune puteti vedea de fapt fluxul de informatie de la cin spre
variabila. evident exista o descriere putin mai formala a acestui proces. la
fel*censored*iesirea este considerata de catre c++ un flux de caractere care iese din
program, si intrarea este considerata un flux de caractere care intra in program. fisierul
iostream defineste obiectul cin ca fiind cel care reprezinta acest flux. pentru iesire,
operatorul << insereaza caractere in fluxul de iesire. pentru intrare cin foloseste
operatorul >> pentru a extrage caractere din fluxul de intrare. in mod obisnuit, la dreapta
operatorului specificati o variabila care va primi informatia extrasa. (simbolurile << si >>
au fost alese pentru a sugera in mod vizual directia in care se deplaseaza informatia.).
putina clasa
ati aflat deja destule despre cin si cout pentru a se justifica o scurta prelegere despre
obiecte. si anume, veti invata ceva mai multe despre notiunea e clasa. clasa este unul
dintre conceptele de baza pentru programarea orientata spre obiecte in c++. o clasa este
un tip de data definit de catre utilizator. pentru a defini o clasa, descrieti ce gen de
informatii poate reprezenta si ce gen de actiuni puteti realiza cu acea data. o clasa se afla
in aceasi relatie fata de un obiect, in care se alfa un tip de data fata de o variabila. adica,
definitia unei clase descrie un formular de date si modul in care acestea pot fi utilizate, in
timp ce un obiect este o entitate creata astfel incat sa corespunda specificatiilor
formularului. sau, in termeni non-informatici, daca o clasa este analoga unei
categorii*censored*ar fi actori celebri, atunci un obiect ar fi analogul unui anumit
exemplu din acea categorie,*censored*ar fi broscoiul vasile. pentru a extinde aceasta
analogie, reprezentarea unei clase de actori ar include definitiile actiunilor posibile relativ
la aceasta clasa,*censored*ar fi citirea unui rol, exprimarea durerii, simularea maniei,
primirea unui premiu si altele. daca ati mai avut contact cu diferite terminologii ale oop,
poate ca va va fi de ajutor sa aflati ca clasele din c++ corespund termenului tip de obiect
sau unei instante de variabila. acum haideti sa discutam mai concret. reamintiti-va de
aceasta declaratie a unei variabile:
int agressor;
aceasta creeaza o variabila particulara (agressor) care are proprietatile tipului int. adica,
agressor poate stoca un intreg si poate fi utilizat in anumite moduri de exemplu, pentru
adunare sau pentru scadere. acum, ganditi-va la cout. el este un obiect creat pentru a avea
proprietatile clasei ostream,
definitia clasei ostream (o alta componenta a fisierului iostream) descrie genul de date
reprezentat de un obiect ostream si operatiile pe care le puteti efectua cu ele,*censored*ar
fi inserarea unui numar sau a unui sir intr-un flux de iesire. in mod asemanator, cin este
un obiect cu proprietatile clasei istream, definita de asemenea in iostream.
ati invatat ca aceste clase sunt tipuri definite de utilizator, dar dumneavoastra, ca
utilizator, in mod sigur ca nu ati proiectat clasele ostream si istream.
asa*censored*functiile pot intra in biblioteci de functii, la fel si clasele pot intra in
biblioteci de clase. aceasta este situatia claselor ostream si istream. din punct de vedere
tehnic, ele nu sunt incorporate in limbajul c++, dar sunt exemple de clase care vin
impreuna cu limbajul. definitiile clasei sunt trecute in fisierul iostream si nu sunt
incorporate in compilator. daca doriti, puteti chiar sa modificati aceste definitii ale clasei,
cu toate ca aceasta nu este o idee buna. (mai precis, este o idee cu adevarat groaznica.)
familia de clase iostream si familia inrudita fstream (sau i/o cu fisiere) sunt singurele
seturi de definitii de lcase furnizate odata cu primele implementari c++.
totusi, comitetul ansi/iso c++ a mai adaugat la standard cateva biblioteci de clase. de
asemenea majoritatea implementarilor furnizeaza, ca parte a pachetului, definitii de clase
aditionale. intr-adevar, c++ isi datoreaza atractia in mare parte datorita existentei unor
biblioteci de clase extinse si utile, suportand programare unix, windows si macintosh.
descrierea clasei specifica toate operatiile care pot fi realizate asupra obiectelor acelei
clase. pentru a realiza o astfel de operatie permisa asupra unui anumit obiect, trimiteti
obiectului un mesaj. de exemplu, daca doriti ca obiectul cout sa afiseze un sir, atunci ii
trimiteti un mesaj prin care ii spuneti de fapt obiectule !! afiseaza asta !. c++ furnizeaza
doua moduri de a trmite mesaje. primul, numit utilizare a metodei de clasa, este in mod
esential un apel de functie, ca si cele pe care le-ati vazut deja. al doilea mod, utilizat cu
cin si cout, presupune redefinirea unui operator. astfel instructiunea
pentru a trimite mesajul pentru afisare lui cout, utilizeaza operatorul << redefinit. in
aceasta situatie, mesajul contine si un argument, sirul care trebuie afisat.
functii
deoarece functiile sunt modulele din care sunt alcatuite programele c++, si deoarece sunt
esentiale pentru definitiile oop ale c++, ar trebuie sa va familiarizati pe deplin cu acestea.
deoarece unele aspecte ale functiilor sunt subiecte avansate, discutia principala despre
functii va fi intr-un tutorial ulterior. totusi, daca faceti cunostinta acum cu unele
caracteristici elementare ale functiilor, mai tarziu veti lucra mai usor si veti avea deja
experienta.
functiile c++ sunt de doua tipuri: cele care returneaza o valoare si cele care nu returneaza
nimic. in bibliotecile de functii standard din c++ puteti gasi exemple din ambele tipuri si
puteti crea propriile dumneavoastra functii de orice tip. haideti sa studiem o functie din
biblioteca, functie care returneaza o valoare, si apoi vom examina propriile
dumneavoastra functii simple.
utilizarea unei functii care returneaza o valoare
o functie care returneaza o valoare furnizeaza o valoare pe care o puteti atribui unei
variabile. de exemplu, biblioteca standard c/c++ contine o functie numita sqrt(), care
returneaza radacina patrata a unui numar. sa presupunem ca doriti sa calculati radacina
patrata a lui 6,25 si sa o atribuiti variabilei x. in programul dumneavoastra puteti
introduce urmatoarea instructiune:
expresia sqrt(6.25) invoca, sau apeleaza functia sqrt(). expresia sqrt(6.25) se numeste apel
de functie, functia invocata se numeste functie apelata, iar functia care contine apelul de
functie se numeste functie apelanta. valoarea dintre paranteze este informatia trimisa
functiei; se spune ca este transferata functiei. o valoare trimisa unei functii in acest mod
se numeste argument sau parametru. functia sqrt() calculeaza raspunsul, care va fi 2,5 si
trimite aceasta valoare inapoi functiei apelante; valoarea trimisa inapoi se numeste
valoarea returnata a functiei. considerati valoarea returnata ca fiind ceea ce inlocuieste in
instructiune apelul functiei dupa ce functia isi termina lucrul. astfel, acest exemplu
atribuie valoarea returnata, variabilei x. pe scurt, un argument este informatia trimisa
functiei, iar valoarea returnata este valoarea trimisa inapoi de catre functie.
practic, asta-i tot, exceptie facand faptul ca inainte de a utiliza o functie, compilatorul c++
trebuie sa stie ce tip de argumente foloseste functia si care este tipul valorii returnate.
adica, functia returneaza un intreg ? un caracter ? un numar cu parte zecimala ? sau
altceva ? daca aceasta informatie lipseste, compilatorul nu va sti*censored*sa
interpreteze valoarea returnata. modul c++ pentru comunicarea acestei informatii este
utilizarea unei instructiuni prototip de functie.
prototipul unei functii este pentru functia ceeea ce este pentru variabile declararea
variabilei spune ce tipuri sunt folosite. de exemplu, biblioteca c++ defineste functia
sqrt() astfel incat sa ia ca argument un numar (eventual) cu o parte fractionara (cum ar fi
6,25) si sa returneze un numar de acelasi tip. unele limbaje considera astfel de numere ca
fiind numere reale, dar numerele utilizate de c++ pentru acest tip este double. prototipul
functiei sqrt(0 arata astfel:
double sqrt(double); // prototipul functiei
primul double specifica faptul ca sqrt() returneaza o valoare de tip double. double intre
paranteze specifica faptul ca sqrt() necesita un argument double. deci, acest prototip
descrie sqrt() chiar asa*censored*este utilizat in urmatoarea expresie:
x = sqrt(6.25);
cel de al doilea mod este mai bun deoarece spre deosebire de dumneavoastra fisierul antet
va obtine mai mult ca sigur prototipul corect. fiecare functie din biblioteca c++ are un
prototip in unul sau mai multe fisiere antet. trebuie doar sa verificati descrierea functiilor
din manual dumneavoastra sau din asistenta online, daca o aveti, iar descrierea va va
spune care fisier antet sa il utilizati. de exemplu, descrierea functiei sqrt() ar trebui sa
spuna sa utilizati fisierul antet cmath. (din nou, poate ca va fi nevoie sa utilizati un antet
mai vechi, math.h, care functioneaza atat in programele c cat si in cele c++.)
deoarece sqrt() lucreaza cu valori de tip double, exemplul creaza variabile de acest tip.
observati ca declarati o variabila de tip double, utilizand aceasi forma, sau sintaxa, ca si
cand declarati o variabila de tip int;
numetip numevariabila;
observati ca cin stie sa converteasca la tipul double informatia din fluxul de intrare, iar
cout stie*censored*sa insereze tipul double in fluxul de iesire. dupa*censored*am mai
spus, aceste obiecte sunt inteligente.
variante de functii
unele functii necesita mai mult de un singur element de informatie. aceste functii
utilizeaza mai multe argumente separate prin virgula. de exemple, functia matematica
pow() preia doua argumente si returneaza o valoare egala cu primul argument ridicat la
puterea data de cel de al doilea argument. ea are prototipul:
daca, de exemplu, doriti sa obtineti 5 la puterea a 8-a, veti utiliza functia astfel:
alte functii nu necesita argumente. de exemplu, una dintre bibliotecile c (cea asociata
fisierului antet cstdlib sau stdlib.h) contine functia rand(), care nu are argumente si
returneaza un numar intreg aleator. prototipul ei arata astfel:
cuvantul cheie void indica explicit ca functia nu preia argumente. daca nu treceti void si
lasati parantezele goale c++ va interpreta acest lucru ca pe o declaratie implicita ca nu
exista argumente. aceasta functie o puteti utiliza astfel:
observati ca, spre deosebire de unele limbaje de programare, in apelul functiei trebuie sa
utilizati parantezele chiar daca nu exista argumente. de asemenea, exista functii care nu
retruneaza nici o valoare. de exemplu, sa presupunem ca ati scris o functie care afiseaza
un numar in formatul monetar. puteti sa trimiteti ca argument, de exemplu 23,5, iar ea va
afisa pe ecran 23,50 dolari. deoarece aceasta functie trimte o valoare pe ecran in loc sa
trimita programului apelant, ea nu va returna o valoare. in prototip, acest lucru il indicati
prin utilizarea cuvantului cheie void pentru tipul returnat:
deoarece nu returneaza nici o valoare, nu puteti utiliza functia ca parte a unei instructiuni
de atribuire sau ca parte a altei expresii. in schimb, aveti o instructiune pura de apel de
functie
unele limbaje rezerva termenul functie pentru functii care retruneaza valori, iar pentru
cele care nu returneaza nici o valoare utilizeaza termenii de procedura sau subrutina, dar
c++ asemenea lui c, utilizeaza termenul de functie pentru ambele variante.
biblioteca c standard furnizeaza peste 140 de functii predefinite. daca una dintre ele
corespunde cerintelor dumneavoastra, atunci utilizati-o. dar, deseori, trebuie sa le scrieti
personal, mai ales atunci cand proiectati clase. oricum, este mult mai distractiv sa
proiectati propriile dumneavoastre functii, deci haideti sa examinam acest proces. ati
utilizat deja mai multe functii definite de utilizator si toate erau numite main(). fiecare
program c++ trebuie sa aiba o functie main() pe care utilizatorul trebuie sa o defineasca.
sa presupunem ca doriti sa adaugati o a doua functie definita de utilizator. ca si in cazul
unei functii de biblioteca, puteti apela o functie definita de utilizator utilizand numele ei.
si, tot la fel ca in cazul functiilor de biblioteca, trebuie sa furnizati un prototip al functiei
inainte de utilizarea acesteia, lucru pe care il realizati de obicei prin plasarea prototipului
inainte de definitia lui main(). elementul de noutate este acela ca pentru functia noua
trebuie sa furnizati codul sursa. cea mai usoara metoda o reprezinta plasarea codului in
acelasi fisier, dupa codul lui main().
sintaxa functiei
definita functiei agressor() urmeaza aceeasi regula generala ca si definitia lui main(). in
primul rand avem un antet de functie. apoi, intre acolade avem corpul functiei. regula de
definire a unei functii o puteti generaliza astfel:
tip numele_functiei(lista_argumente)
{
instructiuni
}
observati ca liniile de cod care definesc functia agressor() urmeaza dupa acolada inchisa a
lui main(). c++, asemenea lui c si spre deosebire de pascal, nu va permite sa inglobati
definitia unei functii in interiorul alteia. definitia fiecarei functii este independenta de
toate celelalte; toate functiile sunt egale intre ele.
anteturi de functii
void agressor(int n)
cuvantul void specifica faptul ca agressor() nu returneaza nici o valoare. deci, apelul lui
agressor() nu va produce un numar pe care in main() sa il puteti atribui unei variabile.
primul apel de functie arata astfel:
agressor(1337);
atribuie valoarea 1337 variabilei n definite in antetul lui agressor(). cand instructiunea
cout din corpul functiei utilizeaza pe n, ea utilizeaza valoarea transmisa in apelul de
functie. din aceasta cauza, agressor(1337) afiseaza valoarea 1337 in iesirea sa. haideti sa
reanalizam antetul functiei main():
int main()
cuvantul int specifica faptul ca main() returneaza o valoare intreaga. parantezele goale
(care optional pot contine void)specifica faptul ca main() nu are argumente. functiile care
returneaza valori trebuie sa utilizeze cuvantul cheie return pentru a furniza valori de
returnat si pentru a incheia functia. din aceasta cauza la sfarsitul lui main() utilizam
urmatoarea instructiune:
return 0;
aceasta instructiune este logica; main() trebuie sa returneze o valoare de tip int, iar
dumnavoastra o faceti sa returneze intregul 0. dar poate va intrebati cui returnati
valoarea ? de fapt, in nici unul din programele dumneavoastra nu ati vazut nici un apel de
functie main():
in main(), programul utilizeaza cin pentru a furniza o valoare pentru variabila de tip
intreg stone. aceasta valoare este transmisa ca argument functiei stoneinlb() si este
atribuita in acea functie variabilei sts. apoi stoneinlb() utilizeaza return pentru a returna
lui main() valoarea lui 14 * sts. aceasta ilustreaza faptul ca sunteti limitat doar la
utilizarea unui simplu numar dupa return. aici, prin utilizarea unei expresii mai complexe
evitati necazurile crearii unei variabile noi careia sa ii atribuiti valoarea inainte de a o
returna. programul calculeaza valoarea acelei expesii si returneaza valoarea rezultata.
daca returnarea valorii unei expresii va deranjeaza, puteti urma calea cea mai lunga:
fiecare versiune produce acelasi rezultat, dar a doua are nevoie de mai mult timp pentru
aceasta.
dupa*censored*se vede in aceste exemple, prototipul functiei descrie interfata functiei-
adica, modul in care functia interactioneaza cu restul programului. lista de argumente
arata ce tip de informatii intra in functie, iar tipul functiei arata tipul valorii returnate.
uneori, programatorii descriu functiile ca fiind cutii negre specificate prin fluxul de
informatie care intra si iese din ele. acest punct de vedere este descris perfect de catre
prototipul functiei.
desi functia stoneinlb() este scurta si simpla, ea contine o gama larga de caracteristici
functionale:
- are un antet si un corp.
- accepta un argument
- returneaza o valoare
- necesita un prototip
ganditi-va la stoneinlb() ca la o forma standard pentru proiectarea functiilor.