Introducere in ANSI C

++

Introducere
Initial, aceasta lucrare a fost conceputa avand ca instrument de lucru mediul de programare Borland C++ 3.1, varianta de DOS. Aparitia standardelor ANSI pentru C si C++ si in primul rand introducerea suportului pentru acest standard in majoritatea compilatoarelor (gcc, g++, bcc32 etc.), a dus la faptul ca unele dintre sursele existente sa nu mai fie viabile. Capitolele au fost modificate in asa fel incat un utilizator familiarizat cu mediul BC++ 3.1 sa poate face intr-un mod accesibil trecerea de la acest mediu spre variantele free oferite pe piata cu suport ANSI C++. Lucrarea a fost editata in intregime sub programul OpenOffice Writer, oferit in (probabil) toate distributiile gratuite de Linux. In acest caz, sistemul pe care s-a lucrat este SUSE 9.3. Am folosit pentru editarea programelor sursa utilitarul Kate, avand optiunile de editare specifice C++ activate, pentru compilare compilatorul g++, iar pentru depanare Kdbg, o interfata pentru gdb, depanatorul GNU. Urmatoarele volume vor contine:
– – –

Prezentarea bilbiotecii standard ANSI C++ Programare orientate obiect in ANSI C++ STD (Standard Template Library)

-1-

Introducere in ANSI C++

Capitolul 1 – Primul program
1.1 Structura generala a unui program C++
In general, structura surselor C++ ce apar in lucrare este urmatoarea:
// Comentariu (enuntul problemei) # directive_preprocesor prototipuri_functii; declaratii_variabile globale; int main(){ declaratii_variabile_locale; instructiuni; } definire_functii

Sursele C++ reprezinta fisiere text care contin codul pe care dorim sa il rulam pe calculator. Scrierea acestora se poate face in orice editor de text care permite salvarea intr-un format text „curat”, fara detalii de formatare cum ar fi cele introduse de catre un procesor de text (MS Word, OpenOffice Write etc.). Textul sursa va fi salvat sub un nume sugestiv si cu extensia cpp. Pentru a putea fi rulat, textul sursa trebuie sa fie „tradus” intr-o forma executabila de catre calculator. Fara a intra in amanunte, sursa trebuie compilata, apoi link-editata, obtinand un program executabil. In Figura 1.1 dam o schema simplificata a acestui proces.

-2-

Introducere in ANSI C++

Compilare Linkeditare

nume.cpp

nume.exe

Figura 1.1 – Trecerea de la textul sursa la fisierul executabil

1.2 Hi man!
Ca prim program vom implementa urmatoarea problema: P1. Realizati un program C++ care afiseaza mesajul „Hi man!” pe ecran. Vom rezolva problama in trei variante, una specifica C, a doua folosind mediul Borland C++ 3.1 si a treia varianta respectand standardul ANSI C++.
// P1_1. Realizati un program C++ care afiseaza mesajul „Hi man!” pe ecran.

#include <stdio.h> int main(){ printf("Hi man!");
}

// linia 1 // linia 2 // linia 3 // linia 4

Limbajele C si C++ nu dispun de catre instructiuni de intrare/iesire. Pentru a putea citi valori de la tastatura sau pentru afisa pe ecran vom folosi biblioteci care „imbogatesc” limbajul cu diferite functii utile. In acest caz, linia 1 include biblioteca standard stdio.h (standard input/output). Orice program C++ contine o functie numita main, functie cu care incepe executia programului. Linia 2 contine antetul acestei functii. Sfarsitul liniei 2 contine '{', care reprezinta inceputul unui bloc, terminat in linia 4. Intre acolade sunt scrise instructiunile programului, in acest caz linia 3, linie pe care apelam functia printf, functie care realizeaza afisarea mesajului dorit pe ecran.

-3-

Introducere in ANSI C++ In varianta urmatoare vom folosi biblioteca iostream, introdusa in C++ si care implementeaza asa numitele fluxuri de intrare/iesire.
#include <iostream.h> int main(){ cout << "Hi man!"; }
// linia 1 // linia 2 // linia 3 // linia 4

Diferentele fata de primul exemplu le constatam in linia 1, unde am inclus o alta biblioteca ce ne ofera acees la operatiile de intrare iesire, respectiv in linia 3, unde, pentru afisare folosim o altfel de constructie. Cei obisnuiti cu compilatoarele mai vechi, cum ar fi bcc.exe, compilatoriul care vine cu mediul Borland C++ 3.1, vor ramane surprinsi ca sursa de mai sus nu functioneaza (iar daca main ar fi returnat void, am fi avut doua erori!). Varianta care respecta standardul ANSI C++ este urmatoarea:
#include <iostream> int main(){ std::cout << "Hi man!"; }
// linia 1 // linia 2 // linia 3 // linia 4

Observam lipsa extensiei „.h” din linia 1, respectiv specificarea spatiului de nume std in linia 3.

1.3 Compilarea si rularea programului
1.3.1 In mediul Borland C++ 3.1
In cazul in care avem pornit mediul, putem rula programul prin apasarea combinatiei Ctrl+F9. Mediul va a apela automat compilatorul, apoi linkeditorul, va genera fisierul executabil, apoi il va rula. Pentru vizualizarea efectiva a rezultatului, apasam Alt+F5 pentru vizualizarea iesirii.

-4-

> bcc p01. obtinem la acest pas fisierul p01.cpp.Introducere in ANSI C++ In cazul in care am editat sursa intr-un alt editor. dar in acest mod simplificam explicatiile) pas 2. . -5- . Copiem sursa in directorul c:/borlandc/bin (pas facultativ. care poate fi lansat in executie prin comanda . pentru a rula aplicatia dorita vom realiza manual trecerea spre fisierul executabil. .obj > p01. pas 4.exe) (este rulat programul) 1.cpp va genera executabilul Hi_Man.out .3. Daca dorim specificarea unui alt nume de fisier executibail.. de exemplu notepad.exe (obtinem p01. comanda de compilare va contine optiunea -o./a. .. si obtinem fisierul executabil a.out.cpp (in cazul in care sursa a fost corecta. De exemplu g++ -o Hi_Man p01./Hi_Man . din directorul in care avem textul sursa.2 Folosind compilatorul g++ Rulam comanda g++ p01.. iar rularea se va face prin . > tlink p01. in felul urmator: pas 1.obj) pas 3.

in sensul ca executia pasilor algoritmului are loc fara nici un efort creator. iar data de iesire va fi S. In acest caz. P1. respectiv x-4=0 reprezinta probleme.1. conform Figurii 2.1 – Forma generala a unui algoritm Pentru a evidentia pasii de urmat vom lua ca exemplu urmatoarea problema. Vorbim de clase de probleme in urmatorul sens: daca 2x+3=0. respectiv ce anume se cere. Inainte de a incepe rezolvarea problemei trebuie sa ne fie clar care sunt datele initiale de la care se pleca. datele de intrare sunt reprezentate de catre a si b. nu gandim!”.Introducere in ANSI C++ Capitolul 2 – Notiuni de baza 2. Realizati un algoritm care calculeaza suma a doua valori. -6- . care respecta datele problemei (adica S=a+b). ax+b=0 va reprezenta clasa de probleme ce formeaza ecuatia de gradul I. Un algoritm este caracterizat prin sintagma „noi muncim. Date de intrare Rezolvarea problemei Date de iesire Figura 2. in cadrul unui algoritm avem trei sectiuni distincte: date e intrare.1 Notiunea de algoritm Numim algoritm o succesiune de pasi care rezolva o clasa de probleme. rezolvarea efectiva a problemei si date de iesire. In general.

. putem realiza aceste operatii. In cazul descrierii algoritmului in cuvinte. functii1 din cadrul bibliotecii iostream.. cel mai probabil rezolvarea nu va fi corecta. Compilatoarele C++ actuale vin cu bilbioteca standard. Limbajul C++ nu ofera instructiuni de intrare/iesire. 2. Daca nu sunt clare care sunt datele de intrare. deoarece compilatorul trebuie sa ”inteleaga” ceea ce dorim sa facem. sau vom rezolva o alta problema decat cea ceruta. << ultima_chestie.. pentru simplitatea in utilizare. dar in acest moment ce sa zic. In cazul in care dorim implementarea algoritmului intr-un limbaj de programare. prin care. respectiv am afisat rezultatul. asteptati volumele viitorre ale lucrarii pentru explicatii suplimentare (merge si asa . sau vezi [1]. trebuiesc respectate o serie de reguli clare.b) citeste a si b Rezolvarea problemei S=a+b Date de iesire (S) afiseaza S Intelegerea clara a enuntului unei probleme este vitala in rezolvarea acesteia. sau: cout << ceva << altceva << . Pentru afisare vom folosi constructii de forma: cout << ce_vrem_sa_afisam. 1 De fapt sunt obiecte.2 Citirea si afisarea datelor In subcapitolul anterior am citit datele de intrare ale algoritmului. acest lucru a fost realizat prin simpla enuntare a operatiei de executat (scrie S). In schimb avem la dispozitie biblioteca de functii standard. respectiv cele de iesire ale unui algoritm. [3]. -7- . Am ales..)). in cazul nostru C++.Introducere in ANSI C++ Algortimul este: Date de intrare (a.

h> in rest programul ramand nechimbat. -8- . Afisati textul "text de test!" pe ecran. cout << " te" << "st!"..1 inlocuiti #include <iostream> using namespace std. } Linia a doua din sursa va face ca folosirea specificarii spatiului de nume std  (std::cout) sa nu fie obligatorie.Introducere in ANSI C++ P2. Afisarea textului 'text de test!' pe ecran. In cazul in care folositi mediul Borland C++ 3.. Exemple de citire vom da mai tarziu. >> vn . //afisarea unui text cout << " de". cu #include <iostream. sau: cin >> v1 >> v1 >> . // P2_1. Pentru citire vom folosi constructii de forma: cin >> in_ce_citim. #include <iostream> using namespace std. dupa introducerea notiunii de variabila. int main(){ cout << "text".

0 123.456 . Datele cu care lucreaza algoritmii au ca si corespondent in C++ constantele si variabilele.100. Algorimii lucreaza cu date.numar intreg cu semn .poate fi folosit si pentru a memora numere intregi mici .100.001 3. Variabile si constante.1 – Tipurile de baza in C++ char int float double bool -9- .intervalul acoperit de acest tip poate diferi de la un calculator la altul .in memoria calculatorului.1: Tip void Constante 'A' 'B' 'a' '+' '3' 3 123 -1020 3. datele de lucru au fost a.indica absenta informatiei .tip care apare in ANSI C++ .folosit pentru memorarea numerelor reale . Fiecare constanta sau variabila din C++ are asociata un tip.Introducere in ANSI C++ 2.b si S.numere reale .0 123.il folosim pentru numere foarte mari sau pentru o precizie mai mare dupa virgula .defineste un caracter .1 Tabelul 2. In exemplul cu suma. stocarea unui caracter se face folosind codul lui ASCII .456 . Tipurile fundamentale ale C++ sunt prezentate in Tabelul 2.nu este recunoscut in Borland C++ 3.001 10 true false Observatii .3 Tipuri de date.este memorat in format cu virgula mobila (float) in simpla precizie .

folositi pentru a scimba domeniul valorilor pe are le poate pastra o variabila. v2. vom folosi si constante de tip sir de caractere.10 - . Folosirea cuvantului cheie const inainte de declaratia unei variabile va spune compilatorului ca valoarea acesteia nu poate fi modificata in cadrul programului.forteaza existenta semnului . inainte de a folosi o variabila.prin disparitia semnului.2 – Modificatorii de tip short long Tipurile de date sunt folosite pentru a defini variabilele cu care dorim sa lucram in program. Pe langa constantele prezentate in Tabelul 2. declaratia devenind: tip nume=valoare. reprezentand succesiuni de caractere cuprinse intre ghilimele..Introducere in ANSI C++ Pe langa aceste tipuri de baza. C++ permite initializarea variabilei.. Exemplu de siruri de caractere pot fi: ”ABC”. In C++. ”Sunt un sir de caractere!”. C++ ofera asa numitii modificatori de tip.2: Modificator signed unsigned Efect . aceasta trebuie declarata.mareste intervalul de reprezentare Tabelul 2. Prin variabila intelegem o entitate capabila sa-si modifice valoarea. ”1+2=3”. . Forma generala a unei declaratii este: tip nume. este dublat numarul de valori pozitive de memorat .1. In momentul declaratiei..daca dorim doar memorarea a valori pozitive intr-o variabila . prezentati in Tabelul 2.reduce intervalul de reprezentare . . vn. sau: tip v1.

 daca vreau): ­21. "Sunt intregul mare: " << l << endl. #include <iostream> using namespace std.Introducere in ANSI C++ const tip  nume=valoare.344. In urma executiei sa va afisa pe ecran: Sunt caracterul: A Sunt intregul: ­123 Sunt intregul mare: 12356789 Sunt intregul fara semn: 98 Sunt intregul mare fara semn: 12345678 Sunt numarul real: 3. respectiv unsigned  int reprezinta aceeasi declaratie. long int l=12356789. cout cout cout cout cout cout cout } << << << << << << << // // // // // // // tip caracter intreg "obisnuit" intreg "mare" intreg pozitiv intreg mare fara semn numar real alt numar real "Sunt caracterul: " << c << endl. Pentru exemplificare fie urmatoarea problema: P3.14 Numar real (da' mai mare.11 - . unsigned long int U=12345678. deci unsigned. int i=-123. "Numar real (da' mai mare.14. initializati-le si apoi afisati valoarile pe ecran. "Sunt intregul fara semn: " << u << endl. daca vreau): "<<d<< endl. Pentru a determina cantitatea de spatiu ocupata de catre fiecare tip de data. "Sunt intregul: " << i << endl. acesta va fi aplicat pe tipul int. "Sunt intregul mare fara semn: " << U << endl. operator care returneaza numarul de octeti ocupati . int main(){ char c='A'. float f=3. introducem operatorul sizeof. "Sunt numarul real: " << f << endl. Definiti cel putin 5 variabile de tipuri diferite.344 Pentru „cosmetizarea” afisarii am folosit cout << endl pentru a trece la rand nou. In cazul in care lipseste tipul in cadrul declaratiei si punem doar modificatorul. unsigned int u=98. double d=-21.

cin >>b. S=a+b. int main(){ int a. int main(){ int i=123. << "Un intreg ocupa " << sizeof(i) << " octeti" << endl. cin >>a.S. Verificati cat ocupa in memoria calculatorului dumneavoastra diverse tipuri de date. } // declararea variabilelor // citirea datelor de intrare // calcularea sumei //afisarea rezultatului . #include <iostream> using namespace std. Se citesc doua anumere intregi. Afisati pe ecran suma lor. O posibila implementare este: // P2_4.Introducere in ANSI C++ in memoria calculatorului. Programul va afisa: Un caracter ocupa 1 octet Un intreg ocupa 4 octeti Tipul float ocupa 4 octeti Tipul double ocupa 8 octeti Rezultatele pot sa difere de la calculator la calculator. #include <iostream> using namespace std. cout cout cout cout } << "Un caracter ocupa "<<sizeof(char)<<" octet" << endl. In acest moment avem toate datele pentru a implementa algoritmul cerut in problema 1 (cea de la inceputul capitolului). <<"Tipul float ocupa "<<sizeof(float)<<" octeti"<< endl. cout << S. <<"Tipul double ocupa "<<sizeof(double)<<" octeti".b.12 - . P4.

realizand o interfata prietenoasa cu utilizatorul. executia va afisa ceva de forma: a=3 b=5 c=2 E=2*(3­5)+2=­2 . cout << "c=". avand in fata doar un cursor care clipeste.b. } In acest moment.c. Calculati valoare expresiei 2*(a-b)+c. cin >>a. Tratand analog si cea de a doua citire. se executa instructiunea cin>>a. dupa declaratii. cout << endl. cin >>b. int main(){ int a. //afisarea rezultatului cout << b << ")+" << c << "=" << E. Acest lucru se realizeaza prin scrierea unei valori urmata de apasarea tastei Enter.  iar programul se opreste din executie in asteptarea unei valori introduse de la tastatura. o „cosmetizare” fiind bine venita: P5. O posibila rulare a aplicatiei va arata de forma: 3 5 8 Observam ca varianta prezentata nu arata deloc bine. cin >>c. #include <iostream> using namespace std. E=2*(a-b)+c. Motivul este cel ca.Introducere in ANSI C++ La rularea aplicatiei avem impresia ca ea s-a blocat.13 - . obtinem in final afisarea sumei valorilor introduse. cout << "a=". In acest moment variabila a preia valoarea introdusa.E. // declararea variabilelor // trecem la rand nou // scriem un mesaj ajutator // citim prima variabila // analog pentru celelalte // date de intrare // calcularea expresiei cout << "E=2*(" << a << "-". cout << "b=". apoi se trece la urmatoarea instructiune.

cum ar fi trecerea la rand nou sau tab-ul.echivalent cu endl .trecere la rand nou .nnn reprezinta un cod ASCII in baza 8 Tabelul 2. Tabelul 2. Secventa escape \n Efect .backspace .un caracter ' (apostrof) .Introducere in ANSI C++ 2. sau in cadrul unor siruri de caractere.3 – Secvente escape \t \' \\ \” \b \a \nnn '\n' Secventele escape pot aparea sub forma de caractere de sine statatoare.sunet de alerta .3 da o serie de secvente escape uzuale.un caracter ” (ghilimea) . fiecare secventa fiind interpretata ca un singur caracter special. cum ar fi ” abc\n\”abc\” ”.tab orizontal . Urmatoarele doua surse rezolva aceeasi problema: . de forma sau '\\'.4 Secvente escape Secventele escape sunt succesiuni de caractere care incep cu caracterul '\'. Secventele escape sunt folosite pentru a introduce entitati imposibil de afisat in alt mod.14 - .un caracter \ (backslash) .

" $ " << endl. " $$$ " << endl. $ $$$ \n \n $$$ \n $$$$$ \n" << endl.15 - . int main(){ cout << " cout << " }    $   $$$  $$$$$   $$$    $ << << << << << " $ " << endl. . #include <iostream> using namespace std. " $$$$$ " << endl. $ " << endl.Introducere in ANSI C++ P6. " $$$ " << endl. int main(){ cout cout cout cout cout }    $   $$$  $$$$$   $$$    $ #include <iostream> using namespace std. Afisati un romb din caracterul '$' pe ecran.

Introducere in ANSI C++ 2. cout << "Sunt tot variabila a:" << copie_a << endl. int &porecla=a. si mi se spune:" << porecla << endl. // variabila intreaga a // un alt nume pentru a // tot a cout << "Sunt variabila a:" << a << endl.16 - . Exemplu de lucru cu referinte. tip &porecla=a. Din momentul definirii unei referinte. Forma generala este: tip a. int main(){ int a=123. variabila initiala va putea fi accesata atat cu numele ei cat si cu alias-ul. int &copie_a=a. Folosirea referintelor reluata in Capitolul 8.5 Referinte (alias-uri) C/C++ permite definirea unor alias-uri ale variabilelor. cout << "Sunt a. #include <iostream> using namespace std. referitor la functii. si mi se spune:123 . P7. } Sunt variabila a:123 Sunt tot variabila a:123 Sunt a.

Pp2.  Acum voi face beep de 3 ori. Calculati si afisati. apoi afisati-le in ordine inversa. . sunt un backslash. Eu.b. Pp4.b) = (a+3)/2 +b E(a.d) = (a+b)/2 + (d­c)/3 Pp5. dupa ce am 'sarit' un tab.Introducere in ANSI C++ 2. Pp3.c) = (a+b+c)/3 F(a. Citirea si afisarea sa fie prietenoasa cu utilizatorul. Folositi secvente escape pentru a afisa pe ecran: Ma numesc ”ghilimea” si nu arat asa '.c. cate unul pe un rand.6 Probleme propuse Pp1. urmatoarele expresii: M(a.17 - .b. adica \. in acelasi program si intr-o varianta prietenoasa cu utilizatorul. Calculati media aritmetica a doua valori intregi citite de la tastatura. Cititi de la tastatura trei numere intregi. Afisati pe ecran un bradulet folosind caracterul '*'.

cout << "\nf=" << f. // realul f ia valoarea 3. Modul in care limbajul realizeaza atribuirea este urmatorul: Pas 1.14 Interesant este faptul ca in C/C++. cout << "\nc=" << c. i=3. // caracterul c ia valoarea 'C' (65) f=2+1. int main(){ int i. // intregul i ia valoarea 3 c='A'+2. Este evaluata valoarea expresiei din dreapta (daca variabila din stanga apare in cadrul expresiei. Exemple de atribuiri simple #include <iostream> using namespace std. operatori si apeluri de functii evaluabila la o valoare unica. va fi folosita valoarea curenta) Pas 2.14 cout << "\ni=" << i.Introducere in ANSI C++ Capitolul 3 – Expresii C++ Numim expresie valida in C++ orice succesiune corecta de variabile.1 Atribuirea Forma generala a operatiei de atribuire este: variabila = expresie. atribuirea este o expresie.18 - . Valoarea . Valoarea calculata este atribuita variabilei din stanga P1. 3. spre deosebire de alte limbaje. constante. deci pe locul in care folosim atribuirea apare o valoare.14. char c. } La rulare vom avea: i=3 c=C f=3. float f.

daca avem atribuirea a=3. pe locul atribuirii apare valoarea 3. int a. Pas 2..// a si b vor lua valoarea 10 (i nu se modifica) cout << "\ni=" << i. int main(){ int i. cout << "\nb=" << b. Initial avem a = expresie. Putem folosi acest fapt pentru a realiza atribuiri multiple. // in partea dreapta i are valoare 3. Se evalueaza expresie: . unde expresie este b=i+2. cout << "Rezultatul atribuirii i=3 este:" << (i=3). P2.b.expresie returneaza valoarea 10 Pas 3. apoi devine 8 a=b=i+2. } Se va afisa: Rezultatul atribuirii i=3 este:3 i=8 a=10 b=10 Pentru expresia a=b=i+2 avem urmatoarea ordine a operatiilor: Pas 1. = variabilan = expresie. de forma urmatoare: variabila1 = variabila2 = . Deci. cout << "\na=" << a.19 - .. i=i+5.variabila b ia valoarea i+2 (10 in exemplul nostru) . Alte exemple de atribuiri #include <iostream> using namespace std. variabila a ia valoarea 10 .Introducere in ANSI C++ returnata de catre oparatia de atribuire este valoarea expresiei din dreapta.

long etc. In urmatoare doua exemple vom evidentia cele doua cazuri de conversie implicita.2 Conversii de tip Este posibil ca tipul expresiei sa nu fie identic cu tipul variabilei unde memoram rezultatul. cout << "\ni=" << i. iar variabila este reprezentata pe un numar egal sau mai mare de octeti decat rezultatul expresiei. in unele cazuri. float f=97. cout << "\nf=" << f.20 - .Introducere in ANSI C++ 3. char c='A'. } i=65 c=A f=12345 . double etc. P3.14. In general. char.) sau de tip real (float. caz in care este realizata o conversie implicita de tip si.). conversia de tip este realizata fara probleme daca variabila si expresia sunt ambele de tip intreg (int. cout << "\nc=" << c. i=c. Conversie implicita de tip. fara pierdere de informatie #include <iostream> using namespace std. f=i. vom avea un avertisment la compilare. int main(){ int i=12345.

avem: p04. C si C++ permit conversii explicite de tip.14 Observatie: c contine caracterul '9'. nu valoarea intreaga 9.cpp: In function `int main()': p04.Introducere in ANSI C++ P4.21 - . float f=97. cout << "\nc=" << c. cout << "\nf=" << f.cpp:11: warning: converting to `int' from `float' La rulare: i=97 c=9 f=97. cout << "\ni=" << i.14. cu pierdere de informatie #include <iostream> using namespace std. de forma: (tip) expresie tip(expresie) sau: . c=i. i=f. } La compilare. Conversie implicita de tip. char c='A'. int main(){ int i=12345.

Se citeste un caracter. Afisati codul ASCII corespunzator caracterului citit #include <iostream> using namespace std. << "Dati caracterul:".Introducere in ANSI C++ P5. cout << "\nf=" << int(f). << "Caracterul \'" << c. int main(){ int i=12345. cout << "\ni=" << float(i+3).14.22 - . } i=12348 c=a f=97 O aplicatie directa a conversiei explicite de tip este: P6. float f=97. cin >>c. int main(){ char cout cout cout } c. Conversia explicita de tip #include <iostream> using namespace std. cout << "\nc=" << (char) 97. Doua posibile rulari ale aplicatiei: Dati caracterul:a Caracterul 'a' are codul ASCII 97 Dati caracterul:9 Caracterul '9' are codul ASCII 57 . << "\' are codul ASCII " << int(c).

 '*'.Introducere in ANSI C++ 3.5. dat de operandul '%'  (modulo). in functie de operator: operator operand operand1 operator operand2 sau Operatorii uzuali folositi in cadrul expresiilor aritmetice si care se comporta asa cum ne asteptam sunt '+'. // operatorul unar a=2*i. cout << i << "/" << a << "=" << i/a << "\n".5 In cazul in care dorim ca raportul a doua expresii de tip intreg sa dea o valoare reala vom folosi conversia explicita de tip. de forma: float(operator_intreg1) / (operator_intreg2) In acest context. dar 7.23 - . Urmatoare problema da exemple de folosire a impartirii: P7. daca cel putin unul dintre operanzi este de tip real. float f. 7/2 are valoarea 3. rezultatul este real. Astfel. este realizata impartirea intreaga. Operatorul modulo nu poate fi aplicat tipurilor reale. // impartire intrega cout << i << "/" << f << "=" << i/f. // impartire reala }  ­123 123/246=0 123/246=0. // operatorul binar * f=a./2 sau float(7)/2 au valoarea 3. Daca ambii operanzi sunt intregi. cout << -i <<"\n". Impartirea reala si intreaga.a. Operatorul '/' (impartirea) reactioneaza in mod diferit in functie de tipul operanzilor. int main(){ int i=123. . Expresii aritmetice. #include <iostream> using namespace std. '­'.3 Expresii aritmetice Forma generala este. In acest ultim caz are sens sa vorbim despre restul impartirii.

valoarea variabilei este incrementata. specifici C si C++. . cout i/=10. cout } << << << << i i i i << << << << "\t". 125     100     200     20       Alti operatori. i+=2. sunt cei de incrementare si decrementare: variabila++ ++variabila variabila­­ variabila­­ Operatorul ++ realizeaza incrementarea variabilei pe care este aplicat. in timp ce in cazul prefix. in timp ce –­ realizeaza decrementarea. adica este similar atribuirii variabila=variabila+1. Diferenta intre cele doua forme (sufix sau prefix). operatori ce vor avea forma generala:  variabila op= expresie unde op poate fi orice operator aritmetic prezentat anterior. "\t". apoi aceasta este incrementata. cout i-=25. int main(){ int i=123.Introducere in ANSI C++ Exista o serie de operatori de atribuire speciali (forma scurta a atribuirii). cout i*=2. "\t". Atribuirea este echivalenta cu:  variabila = variabila op expresie P8. Forma scurta a atribuirii #include <iostream> using namespace std. "\t".24 - . consta in faptul ca. valoarea variabilei este folosita neschimbata in expresia din care face parte. in cazul sufix. apoi este folosita in expresia din care face parte. adica variabila=variabila­1.

a.25 - . asa cum arata si exemplul urmator. } 126     125     125      3. P10. i++.// atribuim lui a valoarea lui i. Incrementarea si decrementarea #include <iostream> using namespace std. int main(){ int i=123. iar orice valoare diferita de 0 (de obicei valoarea 1) este interpretata ca adevarat. b=false. compilatoarele mai vechi (bcc) nu suporta acest tip.b. apoi incrementam i cout << i << "\t" << a << "\t"<< b << "\t". cout << "true=" << b << "\n".// incrementam i. In orice caz.Introducere in ANSI C++ P9. b=true. // daca nu apare intr-o expresie este similar cu ++i. a=++i.4 Expresii logice Sunt acele expresii in care rezultatul este interpretat ca adevarat sau fals. cout << "false=" << b. } true=1 false=0 . Valoarea expresiilor logice #include <iostream> using namespace std. regula care se respecta este faptul ca valoarea 0 inseamna fals din punct de vedere logic. int main(){ bool b. apoi il atribuim lui a b=i++. Daca in ANSI C++ avem definit un tip specific (bool).

2.5] adica x<2 Tabelul 3. Diferite expresii logice pot fi reunite folosind operatorii logici din Tabelul 3. !(x>=2). (x<2)||(x>5).5] adica x∉[2. operator reprezentand atribuirea.Introducere in ANSI C++ Un caz particular de expresii logice il reprezinta expresiile relationale.1 – Operatorii relationali Observam ca testarea egalitatii a doua expresii nu se face folosind '='. Operator && || ! Semnificatie si logic sau logic negatie logica Exemplu (x>=2)&&(x<=5).26 - . expresii in care sunt comparate doua valori. Operatorii relationali sunt dati in tabelul urmator: Operator < > <= >= != == Semnificatie mai mic mai mare mai mic sau egal mai mare sau egal diferit egal 3<5 Exemplu (4+1) > (2*2) 2<=3 3>=3 2!=3 3==3 Tabelul 3. adica x∈[2.2 – Operatorii logici .

3. cout << "b=". Se citesc trei valori intregi de la tastatura. cin >>i. cout << "Dati valoarea:".Introducere in ANSI C++ P11.b] a=2 b=5 apartine intervalului:1 nu apartine intervalului:0 Observam ca valoarea de adevar a afirmatiilor este data sub forma 0-fals si 1adevarat.b. altfel returneaza expresie3. cin >> b. cin >> a.b]\na=". In unele cazuri particulare poate fi un inlocuitor pentru instructiunea if.27 - . expresia returneaza expresie2. Verificati unde se gaseste prima valoare citita in raport cu intervalul determinat de ultimele doua valori. } Dati intervalul [a. cout << "apartine intervalului:" << (i>=a)&&(i<=b)). int main(){ int i. cout << "Dati intervalul [a. cout << "\nnu apartine intervalului:" << (i<a)||(i>b).a. .5 Operatorul conditional Are forma generala: expresie1?expresie2:expresie3 Daca expresie1 este evaluata la adevarat. #include <iostream> using namespace std.

Calculati expresia max(a. E = (x!=0) ? 1. afisand valoarea 0 in caz contrar. apoi afisati rezultatul pe ecran. #include <iostream> using namespace std. . Interschimbati cele doua valori.2)=5 >>a. #include <iostream> using namespace std." << b << ")=" << max. cin max = (a>b) ? a : cout << "max(" << } a=5 b=2 max(5. } x=2 1/2 = 0. unde a si b sunt valori reale citite de la tastatura. Calculati expresia E(x)=1/x daca e posibil. P14. int main(){ int x.b). cout << "a=". a << ". b. float E. Se citesc doua valori intregi de la tastatura.Introducere in ANSI C++ P12. cin >>x.28 - . cout << "1/" << x << " = " << E./x : 0. cout << "x=".5 P13.b. int main(){ float a.max. >>b. cin cout << "b=".

P15. t=a. desi in unele cazuri pare sa functioneze !!! #include <iostream> using namespace std.t. Necesitatea folosirii parantezelor. cin >> a. } a=2 b=5 ­­ dupa interschimbare ­­ a=5     b=2 Ordinea de efectuare a operatiilor in cazul unei expresii complexe este data de prioritatea operatorilor. b=t. int main(){ int a.5]:1 . } a=8 8 apartine intervalului [2. cout << "a=" << a << "\t" << "b=" << b . rez=(2<=a<=5). Acest program NU va verifica apartenenta valorii a intervalului [1. folositi parantezele.[5] etc. cout << "a=".29 - .5]:" << rez . a=b.rez. Tabele cu prioritatea operatorilor gasiti in [1].b.Introducere in ANSI C++ #include <iostream> using namespace std. cout << "b=".5]. De cate ori nu stiti exact ordinea in care se vor executa diferite operatii intr-o expresie.dupa interschimbare --\n". cout << "a=". cout << a << " apartine intervalului [1. // rez=((2<=a)&&(a<=5)). int main(){ int a. cout << "-. cin >>b. cin >>a. respectiv de folosirea parantezelor.

a+=1. adica 1 in context C/C++. expresie2. int main(){ int a. expresien  Expresiile sunt evaluate de la deapta la stanga.6 Operatorul virgula Are forma generala: expresie1 .t. deci primul lucru evaluat este 2<=a. Rezolvarea corecta este cea data in comentariu. cin >> a. P16. valoarea returnata la final fiind valoarea si tipul dat de expresien. b=(a+=1.. // b=a++ cout << a << " " << b << "\n".b. // b=++a cout << a << " " << b << "\n". 3.Introducere in ANSI C++ Observam ca la conditia care pare "8 apartine lui [2. cout << "a=". Urmeaza apoi comparatia 1<=5.5]" rezultatul este adevarat (1). Simulati operatorii de preincrementare si postincrementare folosind operatorul virgula (b=a++ si b=++a). #include <iostream> using namespace std.. b=(t=a. deci rezultatul final este adevarat.t). Motivul este urmatorul: Expresia 2<=a<=5 este evaluata de la stanga la dreapta. . adevarat pentru a=8..a).30 - . } a=3 4 3 5 5 .

3 – Operatori logici pe biti Exemplele din tabel sunt date pentru x de tip intreg. in afara celui mai putin semnificativ x|1 | sau pe biti – seteaza bitul cel mai putin semnificativ x^0 – x^x – valoare ^ ~ >> << sau exclusiv negatie pe biti deplasare la dreapta deplasare la stanga complementeaza toti bitii nula pentru orice x toti bitii ~x – complementeaza x<<2 x>>3 – similar cu x*=2 – similar cu x/=3 Tabelul 3. .7 Operatori care actioneaza la nivel de bit Tabelul 3.Introducere in ANSI C++ 3.3 da operatorii pe biti acceptati in C/C++: Operator & Semnificatie si pe biti x&1 Exemplu – reseteaza toti bitii.31 - .

. valori intregi strict pozitive.32 - . Se citeste un numar real x. Folosind operatorul conditional. Se citeste un numar real x de la tastatura. Se citesc trei numere intregi de la tastatura. Afisati rezultatul expresiei E(a.7). determinati minimul a doua valori intregi citite de la tastatura. de la tastatura. calculati si afisati rezultatul expresiei E(a)=max(min(a.b)=(a-b)/(a+b). Pp2. Pp3.|a-7|). Se citesc doua numere a si b de la tastatura. Pp6. Pp4.8 Probleme propuse Pp1. Pp7. Folosind conversii de tip. adica valoarea care nu este nici minimul. Afisati valoarea "din mijloc". nici maximul celor trei valori date. Se citeste un numar real de la tastatura.Introducere in ANSI C++ 3. strict pozitiv. afisati partea fractionara a numarului. Pp5. Se citesc trei numere intregi de la tastatura. Afisati pe ecran suma celor mai mici doua valori. Folosind operatorul conditional. Calculati si afisati rezultatul expresiei (x-1)/x2 .

33 - . Se citeste un numar intreg de la tastaura.1 Instructiunea if Exista doua forme ale instructiunii if: if (expresie) instructiune In acest caz. expresia poate fi de orice tip. .Introducere in ANSI C++ Capitolul 4 – Instructiuni conditionale Daca dorim executia unor instructiuni doar daca o conditie este adevarata sau daca dorim ramificarea executiei programului. if (expresie) instructiune1 else instructiune2 Daca expresie este evaluata la adevarat se executa instructiune1. } a=123 123 este pozitiv. dar. folosim instructiuni conditionale. if (a>0) cout << a << " este pozitiv. cin >> a. 4.". int main(){ int a.". daca expresie este evaluata la adevarat (o valoare nenula). cout << "a=". #include <iostream> using namespace std. if (a==0) cout << a << " este nul. P1. if (a<0) cout << a << " este negativ.". pozitiv sau negativ. In urmatoarele exemple vom arata diverse moduri de a realiza comparatii in C. altfel se executa instructiune2. datorita conventiilor C referitoare la notiunile de adevarat si fals. atunci se executa instructiunea care urmeaza. inclusiv expresii aritmetice sau atribuiri. Verificati daca acesta este nul. De obicei expresia dintre paranteze este o expresie logica.

va fi evaluata in felul urmator: . adica corespunde valorii false. P2. cout << "a=". se realizeaza prin simpla scriere a expresiei intre parantezele if-ului.daca a este diferit de zero. Se citeste un numar intreg de la tastaura. In general.daca a este nul. verificarea unei expresii daca este adevarata sau falsa. int main(){ int a. se executa cea de a doua ramura. #include <iostream> using namespace std. cin >> a. Conditia "ciudata" din if. Verificati daca acesta este nul sau nu. deci se va executa prima ramura a if-ului . else cout << a << " este nul. atunci.Introducere in ANSI C++ sau: a=0 0 este nul. de forma: if (expresie) Nu este nevoie sa scriem varianta echivalenta: if (expresie != 0) if (expresie != false) sau . reprezinta true.34 - . conform conventiilor C.". Sa vedem putin ce se intampla in acest caz. } a=123 123 este nenul.". if (a) cout << a << " este nenul.

ca o singura instructiune. int main(){ int a. Daca dorim executia a mai multe instructiuni pe o ramura a instructiunii if.. . } a=2 b=3 operatia:+ 2+3=5 In problema 3. In legatura cu sugestii privind indentarea codului studiati Anexa 3. cout << "b=". vom grupa aceste instructiuni intr-un bloc (instructiune compusa).Introducere in ANSI C++ P3. observam ca instructiunea de pe ramura fals a primului if este o alta instructiune if. else if (op=='-') cout << a << '-' << b << '=' << a-b. cin >> b. else cout << "Operatiei neimplementata!". acestea vor fi tratate in mod unitar. Se citesc de la tastaura doua numere intregi si un caracter reprezentand operatiile matematice '+'. Vom denumi acest caz ca imbricarea instructiunii if si vom folosi alinierea else cu if-ul corespunzator pentru a imbunatatii lizibilitatea programului.35 - . #include <iostream> using namespace std. '-'. Afisati valoarea corespunzatoare aplicarii operatiei date asupra intregilor cititi. cin >> op. if (op=='+') cout << a << '+' << b << '=' << a+b. cout << "a=". Vom numi bloc zona cuprinsa intre acolade ({.. cout << "operatia:". In cazul scrierii instructiunilor intr-un bloc.}).b. char op. cin >> a.

Calculati maximul si minimul valorilor. cout << "a=". trebuie acordata o atentie deosebita corespondentei if­else dorite. } // "ajustam" minimul si maximul in functie de a treia valoare if (c>max) max=c."<<b<<". max=b. Fiecare else va fi in corespondenta cu primul if  care se gaseste inaintea lui in textul sursa cu proprietatea ca nu ii corespunde nici un else si nu este inclus in instructiunea if care il precede. max=a. cout << "b=".b. cin >> a.Introducere in ANSI C++ P4.3.min. #include <iostream> using namespace std. if. cout << "min("<<a<<"."<<b<<".3. } else{ min=a. int max. cout << "\nmax("<<a<<".1)=3 Datorita faptului ca putem avea mai multe nivele de imbricare a instructiunilor unele avand else si altele nu. // calculam minimul si maximul primelor doua valori if (a>b){ min=b."<<c<<")="<<min. Mai mult. cout << "c=". o aliniere corecta nu va tine locul de bloc. Se citesc de la tastaura trei numere intregi. if (c<min) min=c. cin >> b. . int main(){ int a.36 - ."<<c<<")="<<max. cin >> c.1)=1 max(2. } a=2 b=3 c=1 min(2.c.

. cout << "a=". cout << "a=". //[1] cout << "Nu mai da eroare . compilatorul va interpreta if-ul ca fiind fara else (pe ramura true se executa o singura instructiune). cin >> a. pare ca pe ramura true vor fi executate cele doua instructiuni. if (a<3){ cout << "E mai mic ca trei\n". #include <iostream> using namespace std. deci nu va gasi corespondet pentru else. int main(){ int a. } a=2 E mai mic ca trei Nu mai da eroare ... Varianta corecta a problemei 5.". //[2] } else cout << "E mai mare ca trei". if (a<3) cout << "E mai mic ca trei\n". #include <iostream> using namespace std. //[2] else cout << "E mai mare ca trei". P6. int main(){ int a. datorita imbricarii.cpp:12: error: syntax error before `else' Desi.cpp: In function `int main()': p05.Introducere in ANSI C++ P5. iar else isi gaseste corespondent. Linia [2] din cod ar trebui aliniata cu instruciunea if.) Acum liniile [1] si [2] sunt grupate intr-un bloc. Exemple de erori de compilare la surse care par corecte. } p05.) ".37 - . afisarea fiind executata in afara acestuia. deci pe ramura true se executa o singura instructiune. //[1] cout << "Pacat doar ca nu va merge niciodata. cin >> a.

apoi sa folosim acea variabila ca o conditie in cadrul instructiunii if.d. else cout << "Numerele citite nu sunt in ordine crescatoare". int main(){ int a. Daca da. . P8.Introducere in ANSI C++ In multe probleme. } Introduceti patru numere intregi: 2 4 5 8 Numerele citite sunt in ordine crescatoare Putem folosi o variabila booleana pentru a memora rezultatul unor exepresii logice complexe.c. P7. #include <iostream> using namespace std. cout << "Introduceti patru numere intregi:\n". folosirea expresiilor logice compuse reprezinta o alegere evidenta. afisati ratia. Determinati daca patru numere intregi formeaza o progresie aritmetica. cin >> a >> b >> c >> d. Determinati daca patru numere intregi citite de la tastatura sunt in ordine crescatoare sau nu.38 - . Acelasi efect il putem obtine folosind o variabila de tip intreg in locul celei booleene.b. if ((a<=b) && (b<=c) && (c<=d)) cout << "Numerele citite sunt in ordine crescatoare".

0 0   inrest .Introducere in ANSI C++ #include <iostream> using namespace std. // verificam daca primele trei formeaza o progresie progresie = progresie && (2*c==b+d). cout << "Introduceti patru numere intregi:\n". cu ratia: 2 Un caz uzual in care apare folosirea conditiei multiple este verificarea apartenentei unui numar unui interval dat. cin >> a >> b >> c >> d.39 - . cout << "aritmetica. cu ratia: " << b-a. } Introduceti patru numere intregi: 2 4 6 8 Numerele citite sunt in progresie aritmetica. int main(){ int a.b. P9. bool progresie.. // acum urmatoarele. } else cout << "Nu avem o progresie aritmetica". progresie = (2*b==a+c).20 ] f  x =−x pentru x ∈−20. if (progresie){ cout << "Numerele citite sunt in progresie\n".. Calculati urmatoarea functie: x pentru x∈[10.d.c.

F. . Executia instructiunii are loc in urmatorul mod: . 4. } x=3 f(3)=0 Nu este recomandata verificarea egalitatii intre doua numere reale. cin >> x. } Optiunea default este optionala. In acest caz solutia oferita de catre instructiunile if imbricate poate fi greoaie. instructiunea switch fiind mai eleganta. if ((x>=10)&&(x<=20)) F=x. unde eps este o valoare mica. este posibil ca rezultatele calculelor sa nu fie exacte.2 Instructiunea switch In unele aplicatii dorim sa comparam valoarea unei variabile sau a unei expresii cu mai multe valori sau expresii constante. cout << "x=". In acest caz se recomanda folosirea unor conditii de forma abs(a­b) < eps. else if ((x>-20)&&(x<0)) F=-x.Introducere in ANSI C++ #include <iostream> using namespace std. .  case constantan:  instructiuni.40 - . Forma generala a instructiunii switch este: switch (expresie){ case constanta1:  instructiuni. . default: instructiune. Datorita erorilor de calcul. int main(){ int x. case constanta2:  instructiuni. else F=0. cout << "f(" << x << ")=" << F.

} else {cout << "Impartire la zero!". . apoi se compara. } . Daca acest caracter este ‘+’.daca este realizata egalitatea. break. apoi afisati rezultatul pe ecran. se executa setul de instructiuni ce urmeaza .Introducere in ANSI C++ .h> using namespace std.} default:cout << "Operator necunoscut!". R=a-b. cout << "b=". . ‘*’ sau ‘/’. ‘-’. break. break. default: instructiune. char op. case constanta2:  instructiuni. } cout << a << op << b << "=" << R. int main(){ int a. break. cin >>op. cin >>b. return(1). realizati operatia respectiva intre intregiii de intrare. forma generala devine: switch (expresie){ case constanta1:  instructiuni. R=a*b.  case constantan:  instructiuni. return(1).41 - . cin >>a. Se citesc de la tastatura doua numere intregi si un caracter. se foloseste instructiunea break Cum de obicei se intampla acest lucru. #include <iostream> #include <math. . if (b!=0) { R=float(a)/b. cout << "a=". float R. cout << "operator:". switch (op){ case '+': case '-': case '*': case '/': R=a+b. break. pe rand cu fiecare constanta .b. } P10. break.daca dupa executarea unei secvente dorim iesirea din switch.se evalueaza expresie.

int main(){ int prima_zi.5 P11. cout << "Ziua corespunzatoare datei de 1 a lunii:". zi. cin >>prima_zi. case 1: cout <<"marti". case 4: cout <<"vineri". cout << "Data corespunde unei zi de ". break. switch(zi){ case 0: cout <<"luni". Afisati ce zi din saptamana va avea o alta data a lunii respective. zi=(zi+prima_zi-1)%7. break. case 5: cout <<"SAMBATA". etc). 2 – pentru marti. break. cin >> zi. break.Introducere in ANSI C++ a=2 b=4 operator:/ 2/4=0. Se citeste de la tastatura ziua din saptamana corespunzatoare date de 1 ale unei luni (1 – pentru luni. break. } } Ziua corespunzatoare datei de 1 a lunii:0 Data de verificat:14 Data corespunde unei zi de DUMINICA .42 - . case 6: cout <<"DUMINICA". cout << "Data de verificat:". break. break. case 2: cout <<"miercuri". #include <iostream> using namespace std. case 3: cout <<"joi".

afisati mesajul "We have a problem!". Pp6. a si b citite de la tastatura. Se citesc patru numere intregi de la tastatura.3 Probleme propuse Pp1. y = xy pentru x0 x∗y pentru x≥0 Pp3. . Se citeste x intreg. Se citesc 3 numere intregi de la tastatura. Calculati: f  x . Pp2. Rezolvati ecuatia de gradul 1. Folosind instructiunea switch. Sa se calculeze ultima cifra a lui 2x. afisati numele unei luni cu numarul de ordine citit de la tastatura. Daca nu. Pp8. Daca toate nuemerele citite sunt pozitive. Pp5. afisati-le in ordine crescatoare. Afisati valorile distincte citite. Dati un exemplu de problema in care expresia conditionala nu poate tine locul instructiunii if. Sa se determine ultimele doua cifre ale produsului a*b. Pp7.43 - .Introducere in ANSI C++ 4. Pp4.

Expresia poate fi de orice tip.1 Instructiunea while Forma generala a instruciunii while: while (expresie) instructiune. se executa instructiune.daca rezultatul este false (0).b variabile intregi citite de la tastatura aceasta metoda nu poate fi folosita..b].Introducere in ANSI C++ Capitolul 5 – Instructiuni repetitive Daca dorim executia unor instructiuni de mai multe ori. sunt de preferat expresii logice.44 - . Daca se doreste executarea unui grup de instructiuni se va folosi un bloc care sa formeze corpul instructiunii while. in functie de o conditie. cout << 1 << 2 << 3 << . La afisarea valorilor dintr-un interval [a. dar. do­while si for. o rezolvare de forma: . inclusiv expresii aritmetice sau atribuiri. . ca si la instruciunea if. a. poate fi utilizata doar daca intervalul dat este mic si definit de catre constante. Executia instructiunii: .se evalueaza expresie ..daca rezultatul este true (diferit de 0). apoi se revine la primul pas . In acest caz. se continua executia cu instructiunea urmatoare Poate cea mai simpla problema care se poate rezolva folosind structuri repetitive este afisarea valorilor intregi din [1. folosim instructiunile repetitive.10].. 5.. Acestea sunt while.

valori mai mici sau egale citesc cu n n valori echidistante din intervalul [a. . i++.. #include <iostream> using namespace std. i=1. b . .b] 1 0 1 0 1 ..n valori ... Afisati numerele de la 1 la 10 pe ecran. while (i<=10){ cout << i<< " ". } }  citesc1 2 3 4 5 6 7 8 9 10  P2. Afisati urmatoarele serii de numere pe ecran (a. a..45 - . a+1. int main(){ int i.b... a<b) • • • • 1 2 4 8 .n sunt intregi citite de la tastatura.Introducere in ANSI C++ P1.

} cout << endl. while (i<=n){ cout << i%2 << " ". cin >>b. i=2*i. while (k<=b){ cout << k << " ". i=1.5 6 6. i=a. } } n=10 a=2 b=7 1 2 4 8 2 3 4 5 6 7 2 2. cout << "a=". cout << "b=". cout << "n=". while (i<=b){ cout << i << " ".a.k. i++.n. while (i<=n){ cout << i<< " ".5 3 3. cin >>n. } cout << endl. i++.5 4 4.5 5 5. } cout << endl. int main(){ int i.b.5 7 1 0 1 0 1 0 1 0 1 0  . i=1. k=a. k=k+pas. pas=float(b-a)/n. cin >>a. float pas.46 - .Introducere in ANSI C++ #include <iostream> using namespace std.

In acest caz vomverondela folosi intructiunea vida . P3. (while fara corp) #include <iostream> using namespace std. cout << "n=".47 - . Afisati cel mai mare numar multiplu de 10 mai mic ca numarul citit. in cazul instructiunii do. while ((n--)%10!=0).Introducere in ANSI C++ In unele cazuri corpul instructiunii while poate sa fie vid.daca rezultatul este false (0) se incheie instructiunea si se continua programul . Diferenta dintre while si do-while este aceea ca. Se citeste un numar intreg de la tastatura. Modul de executie al instructiunii: . while (expresie). cout << n+1.while instructiunea se executa cel putin o data. } n=123 120 // while cu corp vid 5.2 Instructiunea do-while Forma generala a instruciunii do ­ while: do  instructiune. chiar si in cazul in care expresie este falsa la prima iteratie. .se evalueaza expresie .daca rezultatul este true (diferit de 0) se revine la primul pas .  Observatiile de la instructiunea while raman valabile si pentru aceasta instructiune. int main(){ int n. cin >>n.se executa instructiune .

do{ cout << c << " . }while(c<=c2). c1=c2. Figura 5.c. "Mutati" virgula pe toate pozitiile interioare posibile in cadrul numarului initial. }  A C A ­ 65 B ­ 66 C ­ 67 P5.c2.     while (expresie). if (c1>c2){t=c1." << int(c) << endl. cin >> c1 >> c2.48 - .1 P4.t. Se citeste de la tastatura un numar real cu 3 zecimale. cate un numar pe un rand. c++. Afisati pe ecran rezultatul. c2=t. int main(){ char c1. .Introducere in ANSI C++ Urmatoarele secvente de instructiuni sunt echivalente:   if (expresie)       do      instructiune. Afisati pe ecran caracterele si codurilor lor ASCII din intervalul dat de catre caracterele citite.} c=c1.    while (expresie)  instructiune. Se citesc de la tastatura doua caractere. #include <iostream> using namespace std.

89 12. cond_de_oprire . de obicei: for(init. n=n/10. } n=12. Instructiunea for este instructiunea ce implementeaza in C ciclul cu numar cunoscut de pasi (desi vom vedea ca nu este limitata la acest tip de cicluri).2789 5. cin >> n.49 - .9 127. sau. int main(){ float n.cat timp expresie este adevarata ..789 1. Modul de executie al instructiunii: . reinit) instructiune.3 Instructiunea for In general instructiunile while si do-while poarta numele de cicluri cu numar necunoscut de pasi. expr2. expr3) instructiune.se executa init .Introducere in ANSI C++ #include <iostream> using namespace std. cout << "n=". Forma generala a instruciunii for: for(expr1. n=n*100. } while(n>1). do{ cout << n << endl.789 1278.

i.i++){ cout << p << " ".i++) cout << i << " ".se executa instructiune ..Introducere in ANSI C++ . in ordine crescatoare puterile lui 2 mai mici decat n primele n puteri ale lui 2 #include <iostream> using namespace std. cout << endl. a<b): – – – – – 1. -1. for(i=1. 1. for(i=a. cout << endl.. int main(){ int n.3.n sunt intregi citite de la tastatura.i<=b..i<=10.i>=-n. p=2*p.b. pentru parcurgerea seriilor de numere. Afisati urmatoarele serii de numere pe ecran (a.50 - .i++) cout << i << " ".10 n. cout << endl. . for(i=1. . 2.. for(i=n. in principal.p.se executa reinit Instructiunea for este folosita. n-1. 0.a...b. for(i=1.i=2*i) cout << i << " ".b]... -n valorile intregi din intervalul [a. cout << endl.i<=n. cin >> n >> a >> b.i--) cout << i << " ".. P6. p=1.i<=n..2. -2. } } 5 3 8 1 2 3 4 5 6 7 8 9 10 .

in total n valori #include <iostream> using namespace std. b=1. int main(){ int n. cin >> n. Afisati. cout << endl.. folosind trei metode diferite urmatoarea serie de numere pe ecran: 1 0 1 0 1 0 .. instructiunea for devine echivalenta ca functionalitate cu bucla while.i<=n. for(i=1. if (n%2==1) cout << 1. In figura 5.b.. for(i=1.51 - .i++){ cout << b << " ".i<=n.i++) cout << i%2 << " ".i. b=!b. for(i=1.i<=n/2. } } n=7 1 0 1 0 1 0 1 1 0 1 0 1 0 1 1 0 1 0 1 0 1  Cum partea de reinitializare din cadrul buclei for contine orice expresie. cout << "n=". cout << endl.Introducere in ANSI C++ 5 4 3 2 1 0 ­1 ­2 ­3 ­4 ­5 3 4 5 6 7 8 1 2 4 1 2 4 8 16  P7.2 este data echivalenta dintre instructiunile for si while: . nu numai incrementare/decrementare.i++) cout << 1 << " " << 0 << " ".

p. urmatoarea bucla fiind bucla infinita: for(. Afisati tabela cu codurile ASCII.. for(i=1.p=1.       expr3. toate partile din for sunt optionale. .p*=2) cout << p << " "..2 Folosirea expresiei virgula reprezinta o varianta prin care putem controla mai multe variabile in cadrul aceleiasi bucle for.expr3)       instructiune. eventual de tipuri diferite.). cout << "n=".j--) cout << i << " " << j << " ". cate 10 pe un rand.expr2.j.52 - . P8.i++. In plus. cout << endl. i++. in cadrul instructiunii for. cin >> n. for(i=1. 9 1 1 2 4 8 . in total n valori #include <iostream> using namespace std.j=9... i<=n. P10. } n=5 1 9 2 8 3 7 4 6 5 5 6 4 7 3 8 2 9 1 1 2 4 8 16  Putem folosi.i. . int main(){ int n.Introducere in ANSI C++   expr1. Afisati urmatoarele serii de numere pe ecran: • • 1 9 2 8 3 7 ..   }  for(expr1. i<10 . Figura 5.   while (expr2){  instructiune. mai multi contori.

.4 break si continue In cazul care se doreste iesirea din bucla curenta imediat. } } .... in cazul in care avem mai multe bucle imbricate..... fluxul executiei din cadrul buclei curente este intrerupt..53 - ..... <­60    =­61    >­62    ?­63    @­64    A­65    B­66    C­67    D­68    E­69 F­70    G­71    H­72    I­73    J­74    K­75    L­76    M­77    N­78    O­79 . Analog instructiunii break.. dar executie revine la conditia de oprire din bucla. . eventual in functie de o alta conditie decat cea din bucla...c<255. folosim instructiunea break. Tot pentru controlul fluxului de executie putem folosi instructiunea continue.... Sintaxa: break.... if (c%10==9) cout << endl.. De obicei vom folosi instructiunea break pentru a nu complica conditia din bucla. iesirea facandu-se in bucla imediat superioara. int main(){ unsigned char c. 5. Sintaxa: continue. for(c=0. Instructiunea break va cauza iesirea doar din cadrul buclei curente..c++){ cout << c << "-" << int(c) << "\t"...Introducere in ANSI C++ #include <iostream> using namespace std..

1  . bool prim.i>=-10..d<=i/2. Afisati pe ecran urmatoarele numere. cout.17 ­0. 1/9. int main(){ int n.33 0.12 0.14 ­0.1 0. #include <iostream> using namespace std. } } n=20 1 2 3 5 7 11 13 17 19  P12.. Afisati pe ecran numerele prime mai mici decat n.Introducere in ANSI C++ P11. 1/-2.14 0.25 ­0.d.17 0. } } 0. int main(){ int i. .i--){ if (i==0) continue.54 - .11 0. cout << 1.11 ­0.} if (prim) cout << i << " ". 1/8.12 ­0. 1/-1. 1/-10 #include <iostream> using namespace std.i++){ prim=true. break. for(d=2.precision(2).2 0.d++) if (i%d==0){prim=false.25 0..i<=n.5 ­0.5 1 ­1 ­0.2  ­0. ./i << " ". for(i=10. for(i=1. cout << "n=". cu doua zecimale exacte: • 1/10.i.33 ­0. cin >>n. 1/1..

afisati pe ecran numerele intregi din intervalul [a.55 - . iar depanarea este mai facila. i++. i=a. Chiar daca este o instructiune pusa la dispozitie in cadrul limbajului C. Definirea etichetei se face in felul urmator: eticheta: iar utilizarea instructiunii goto: goto eticheta. salt: cout << i << " ".Introducere in ANSI C++ 5. folosirea instructiunilor if. } // se revine la eticheta salt P13. cin >> a >> b. folosirea acesteia nu este recomandata.b. if (i<=b) goto salt. identificata printr-o eticheta se poate realiza prin instructiunea goto.a. #include <iostream> using namespace std.b]. int main(){ int i. Folosind instructiunea goto. 3 6 3 4 5 6  . if­else si while  putand realiza acelasi lucru.5 instructiunea goto Trecerea fluxului de executie la o pozitie oarecare.

Introducere in ANSI C++ 5.1 Probleme pe cifrele unui numar Acest gen de probleme prelucreaza numerele intregi la nivel ce cifre componente.  foloseste(c). n=n/10.56 - . de obicei.6. } unde foloseste(c) este o secventa de instructiuni dependenta de enuntul problemei. rezolvarea este.3 De aici obtinem urmatoarele: c= n% 10 – calculul ultimei cifre n=n/10 – eliminarea ultimei cifre Si mai departe. .6 Probleme tip In acest subcapitol vom prezenta o serie de algoritmi ce vor fi rezolvati folosind instruciuni repetitive. parcurgerea unui numar intreg pozitiv. cam asa". 5. cifra cu cifra: while (n>0){ // cat timp mai avem cifre c= n% 10. Accesul la cifrele unui numar este dat de Figura 5. Vom prezenta o serie de "scheme generale" de rezolvari de algoritmi. Aceste scheme sunt reguli de forma: "daca o problema suna asa.3 n 1234 10 1230 123 4 n%10 n/10 Figura 5.

Ultima instructiune for (cea comentata) rezolva acceasi problema intr-o varianta compacta. cout << c << endl. cin >> n.. cate o cifra pe un rand. int main(){ int n. cout << "n=".57 - .n/=10) cout << n%10 << endl.c. n=n/10. P14. #include <iostream> using namespace std. . while(n>0){ c=n%10. Afisati cifrele unui numar. } // } n=1942 2 4 9 1 for(.n>0.n=n/10) foloseste(n%10).n.Introducere in ANSI C++ O alta varianta este cea folosind instructiunea for: for(.

• • Verificati daca este prim descompuneti-l in factori primi .d. #include <iostream> using namespace std. // selectam divizorii P15.d<=n. cout << "n=". cin >> n.d<=n. parcurgerea divizorilor unui numar intreg pozitiv n: for(d=1. deci: n%d==0  ­ verificarea daca d|n Plecand de la aceasta conditie. Afisati divizorii unui numar intreg pozitiv citit de la tastatura.6. Se citeste de la tastatura un numar intreg pozitiv.d++) if (n%d==0) cout << d << " ". } n=120 1 2 3 4 5 6 8 10 12 15 20 24 30 40 60 120 P16.58 - . for(d=1.2 Probleme de divizibilitate Un numar n este divizibil cu numar d daca restul impartirii lui n la d este zero.d++) // dintre toti divizorii posibili if (n%d==0) foloseste(d). int main(){ int n.Introducere in ANSI C++ 5.

prim=true.d. n=n/d. } if (prim) cout << n << " este prim\n".b). cout << "n=". Calculati cmmdc(a. bool prim. for(d=2.b) si cmmmc(a. } else d++. d=2.d++) if (n%d==0){ prim=false. while(n>1) if (n%d==0){ cout << d << " ". cin >> n.59 - . } n=120 120 nu este prim 2 2 2 3 5 P17.Introducere in ANSI C++ #include <iostream> using namespace std. Se citesc doua numere intregi pozitive de la tastatura. int main(){ int n.d<=n/2. . break. else cout << n << " nu este prim\n".

produse. aa=a.Introducere in ANSI C++ #include <iostream> using namespace std.cmmdc.60 - .36)=72 5. } cmmdc=aa.b. bb=r. cmmmc=(a*b)/cmmdc. numarari Avem urmatoarele scheme generale: Suma: S=0 Pentru toate valorile X de insumat S=S+X Produsul: P=1 Pentru toate valorile X de inmultit P=P*X . aa=bb. cout << "cmmmc(" <<a <<"." << b <<")=" << cmmmc.bb. cout << "cmmdc(" <<a <<". while(bb!=0){ r=aa%bb. int main(){ int a." << b <<")=" << cmmdc << endl.6. bb=b.aa.3 Sume.r. } 24 36 cmmdc(24.36)=12 cmmmc(24. cin >> a >> b.cmmmc.

fact. i++) S+=1.i=a. Calculati: • • • Suma numerelor pare din interval a! S=1/a+1/(a+1)+ . Se citeste un numar intreg pozitiv de la tastatura. for(fact=1.i++) Sm+=i. for(S=0. i<=a. i++) fact*=i./i. Calculati: • • • Suma cifrelor numarului Produsul cifrelor pare Prima cifra a numarului .18654 P19. Se citesc doua numere intregi a si b (a<b). i<=b .i=1. cin >> a >> b.61 - .. 1/b (in cazul impartirii la 0 termenul nu apare) #include <iostream> using namespace std. int main(){ int a.Introducere in ANSI C++ Numarari (contorizari): ct=0 Pentru toate valorile X de parcurs if (conditie(X)) ct++ P18.i=a. cout << Sm << " " << fact << " " << S. float S.b. for(Sm=0.. i<=b.i. } 4 11 60 24 1.Sm.

if (c%2==0) P*=c. n .ct.S.n/=10){ c=n%10. } 12141 9 8 1 3 P20. S+=c.n>=10. Se citeste un numar intreg pozitiv n de la tastatura.ct=0. nn=n. int main(){ int n.n/=10) if (n%10 == pc) ct++. cin >> n. for(n=nn.Introducere in ANSI C++ • De cate ori apare prima cifra in numar #include <iostream> using namespace std. cout << S << " " << P << " " << pc << " " << ct.n/=10).P=1. for(S=0. n . Calculati: • • Suma divizorilor numarului Cate numere prime mai mici ca n exista .62 - .pc.c.P. pc=n.nn. } for(n=nn.

d<=i/2. } cout << ct. int main(){ int n.d<=n. cin >> n.Avem: Maxime: max = ­infinit Pentru toate valorile X de parcurs if (X>max) max=X Minime: min = infinit Pentru toate valorile X de parcurs if (X<min) min=X .4 Maxime si minime Calcularea valorile minime sau maxime dintr-o serie de valori reprezinta o problema des intalnita in practica. bool prim.Introducere in ANSI C++ #include <iostream> using namespace std.i++){ prim=true. for(i=2.ct.S.63 - . ct=0. } n=10 18 4 5.i. if (prim) ct++.d++) if (n%d==0) S+=d.d++) if (i%d==0) prim=false. cout << S << " ".d. S=0.6.i<n. for(d=2. cout << "n=". for(d=1.

c.h ofera in acest sens o serie de constante predefinite utile. cout << S << " " << P << " " << pc << " " << ct.P.ct. cum ar fi MAXINT. -MAXINT. infinit reprezinta valoarea minima pe care o poate lua X si depinde de tipul de date cu care lucram. for(S=0.S. n . nn=n. Calculati: • • Cifra maxima a numarului De cate ori apara cifra minima #include <iostream> using namespace std. for(n=nn.P=1.n>=10. Utilizatorul.5 Citirea mai multor numere de la tastatura In cazul in care dorim prelucrarea a mai multe numere citite. n . P21. cin >> n. introduce numarul de valori ce vor fi citite ulterior: . int main(){ int n. MAXFLOAT etc. ca prima faza. if (c%2==0) P*=c.n/=10){ c=n%10. } for(n=nn.n/=10). pc=n. Biblioteca values. Se citeste un numar intreg pozitiv de la tastatura. S+=c.6.n/=10) if (n%10 == pc) ct++.nn.64 - . } 25221 12 8 2 3 5. avem urmatoarele rezolvari: a.pc.ct=0.Introducere in ANSI C++ In aceste scheme.

} // numarul de valori de citit // de n ori // citim numarul // il utilizam conform enuntului b. P=P*x. } // citim valoare // cat timp conditia e respectata // il utilizam conform enuntului // citim numarul P22. for(i=1. max=-MAXINT. if (x>max) max=x. } 5 1 1 5 2 1 5 10 . Calculati: • • maximul produsul #include <iostream> #include <values. foloseste(X).i++){ cin >> X. Se cunoaste o conditie cat timp se vor citi valori: cin >> X. while (cond(X)){ foloseste(X). P=1.max. cin >> n. } cout << max << " " << P.x. int main(){ int n.i.65 - . for(i=1. cin >> X. Se citeste un numar n.i<=n.i++){ cin >> x.P.i<=n. apoi n valori reale de la tastatura.h> using namespace std.Introducere in ANSI C++ cin >> n.

} 2 3 1 4 6 1 1 1 6 1 12 0 30 1 apare de 5 ori 5. cout << min << " apare de " << ct_min << " ori"..h> using namespace std. if (x==min) ct_min++.Introducere in ANSI C++ P23. Afisati pe ecran: a: 1 1 2 1 2 3 . ct_min=0.n b: 1 2 2 3 3 3 .ct_min. while (x!=0){ if (x%2==0) S=S+x.i. ct_min=1...min. cin >> x..6 Generarea unor serii complexe de numere P24. else if (x<min){ min=x. } cout << S << endl. n n . } cin >> x..S.n . Se citeste n (intreg pozitiv). Se citesc numere intregi pana la intalnirea valorii 0. 1 2.66 - . Calculati: • • Suma valorilor pare Minimul si de cate ori apare acesta #include <iostream> #include <values.. int main(){ int x.. min=MAXINT.. S=0.6.

k++){ for(i=1.. 12345 23456 34567 45678 5 6 7 8 9 (n=5) .... sub forma data: 1 121 12321 .. 1 ....... cout << " ".. } cout << endl.i<=k..6 – numarul urmat de divizori .i++) cout << i << " ".......k. for(k=1..... cin >>n. int main(){ int n.. 1 1:1 2:1...i++) cout << k << " ".. Afisati pe ecran.. cout << " ".2 . 6: 1.i<=k.. } } 5 1  1 2  1 2 3  1 2 3 4  1 2 3 4 5 1  2 2  3 3 3  4 4 4 4  5 5 5 5 5  P25...67 - .i.2. for(k=1.......k++){ for(i=1.....3. Se citeste n (intreg pozitiv).k<=n..Introducere in ANSI C++ #include <iostream> using namespace std.k<=n.

cout << endl. cout << endl.k<=n.Introducere in ANSI C++ #include <iostream> using namespace std. for(k=1. for(i=1.3 4: 1.4 ­­­­­­­­­­­­­ 2 3 4 5 3 4 5 6 4 5 6 7 5 6 7 8 . for(i=k-1.i<=k. cout << k << endl.k.2 3: 1. } cout << "-------------" << endl. int main(){ int n.i++) cout << i+k << " ". cin >>n. for(k=1. } cout << "-------------" <<endl.d++) if (k%d==0) cout << d << ".d.i--) cout << i << " ".i>=1.i<=n. for(d=1. } } 4       1     1 2 1   1 2 3 2 1 1 2 3 4 3 2 1 ­­­­­­­­­­­­­ 1: 1 2: 1.d<=k/2.i<=n-k. for(k=1.k<=n.k++){ for(i=1.68 - .k++){ for(i=1.i.i++) cout << " ".2.k<=n.i++) cout << i << " ".".k++){ cout << k << ": ".

n ......n.. Afisati: – – cel mai mare si cel mai mic numar prim suma numerelor care au cifrele in ordine crescatoare .7 Probleme propuse Pp1.. apoi n numere intregi de la tastatura.. Se citesc numere intregi de la tastatura pana la intalnirea unui numar negativ. Afisati pe ecran tabla inmultirii pana la 10. Pp5...... Se citeste de la tastatura un numar intreg n.. Afisati numarul citit care are cei mai multi divizori..1.. +n! S = 12 + 42 + 72 + . indiferent de cate ori apar.n 10101 01010 10101 01010 1 0 1 0 1 (n=5) Pp7... Calculati valoarea urmatoarele expresii. Afisati pe ecran urmatoarele serii de numere. Pp8..3 .2 3:3. Refaceti solutiile propuse ale problemelor rezolvate in acest capitol. Se citeste numarul intreg pozitiv n de la tastatura. Determinati daca cele doua numere sunt formate din aceleasi cifre. + (3n-2)2 Pp3. folosind pentru fiecare expresie un alt tip de instructiune repetitiva: E = n + n/2 + n/3 + .Introducere in ANSI C++ 5. Calculati ultima cifra a expresiei E= ab.... a si b valori intregi pozitive citite de la tastatura..69 - . Pp6. + 1 P = 1! + 2! + . Se citeste n intreg.... astfel incat sa folositi alt tip de instructiune repetitiva fata de cea utilizata in rezolvarea initiala (de exemplu in loc de for folositi while).. Se citesc doua numere intregi de la tastatura..n.. Pp2..... pastrand formatul: 1 212 32123 ... n:n. Pp4...3.. n 1:1 2:2.. De exemplu 123 si 11321 sunt formate din aceleasi cifre.......

// vector de intregi partial initializat float X[]={3. devine evidenta necesitatea folosirii unor tipuri de date complexe. " << sizeof(B) << " octeti". Exemple de declarari/initializari de vectori si cat ocupa acestia in memorie. << sizeof(X)/sizeof(int)<< " valori". iar acest lucru devine un impediment major in momentul in care.v2. 5. " << sizeof(X) << " octeti".. Un vector (tablou unidimensiunal) este o structura de date care poate stoca mai multe valori de acelasi tip.. sub forma urmatoare: tip nume[dimensiune] sau unde vi au un tip convertibil la tip sau tip nume[dimensiune]={v1.. 2. avem nevoie de stocarea si realizarea de diferite operatii pe 100 de numere intregi.. 6.Introducere in ANSI C++ Capitolul 6 – Vectori (matrici) In momentul in care complexitatea programelor creste. int main(){ int A[100].70 - .// vector de reali complet initializat cout cout cout cout } Vectorul A ocupa 400 octeti Vectorul B ocupa 40 octeti << << << << "Vectorul "Vectorul "Vectorul "Vectorul A B X X ocupa ocupa ocupa are " " << sizeof(A) << " octeti". unde vi au un tip convertibil la tip P1. sa zicem. daca dorim utilizarea unui vector acesta trebuie sa fie declarat. // vector de intregi neinitilalizat int B[10]={1. #include <iostream> using namespace std. tip nume[]={v1.4}.vn}.5}. . C++ ofera mai multe moduri de a declara/initializa un vector. Folosirea variabilelor simple permite stocarea unei singure valori....3.vn}..1 Declararea si initializarea Exact ca si in cazul variabilelor simple.2.14.

Accesul la elementele unui vector se face folosind indici. in final. 9 A[9] Figura 6. In functie de compilator.. In acest caz se aloca in memorie un numar de 10 intregi. iar in cazul in care nu avem specificata dimensiunea aceasta este data de numarul de valori cu care initializam vectorul.Introducere in ANSI C++ Vectorul X ocupa 12 octeti Vectorul X are 3 valori Observam ca specificarea dimensiunii va duce la alocarea unui spatiu de memorie suficient pentru a pastra toate valorile din vector.2 . ultimul element valid va fi A[9]. in rest nu stim ce valori exista in vector. avem urmatoarele atribuiri: A[0]=5.71 - .. A[9]=A[1]+A[2]+A[3]. si. au valori cunoscute. In memorie situatia va asemanatoare cu cea descrisa in figura 6. primele patru valori fiind initializate. vom avea urmatoarea situatie (Figura 6.. ? A[9] Figura 6.4}.3. al doilea A[1]. Daca. Primele patru elemente.1 Observam ca primul element este A[0]. cele initializate.. Fie urmatorea declaratie de vector: int A[10]={1.1: 1 A[0] 2 A[1] 3 4 ? .2): 5 A[0] 2 A[1] 3 4 ? .2. in continuare. s-ar putea ca ele sa fie initializate cu valoare 0. dar este mai bine sa nu contam pe acest fapt.

. adica o valoare din multimea {0. Citirea unui element va fi de forma: cin >> A[i]. exista posibilitatea de a accesa vectorul elemente cu element prin intermediul unor indici constanti. cout << "Dati elementele vectorului A:".daca numarul de elemente din vector difera de la rulare la rulare Pentru a rezolva aceste situatii. cout << A[2] << " " << A[1] << " " << A[0]. In cazul in care dorim sa realizam citirea si afisarea unui vector. vom folosi o variabila ca indice. Se citesc cinci valori ale unui vectori de intregi. unde i va parcurge indicii vectorului.. } Dati elementele vectorului A:2 4 1 3 5 A: 5 3 1 4 2 Aceasta abordare nu acopera urmatoarele cazuri: . Accesul la elementele vectorului se va face folosind o notatie de forma A[i]. int main(){ int A[5]..daca avem un numar mare de elemente in vector . unde i va fi o valoare intrega ce reprezinta un indice valid in vector.Introducere in ANSI C++ 6. Afisati vectorul in ordine inversa.n-1}. #include <iostream> using namespace std. asa cum se observa in problema urmatoare: P2. in loc sa accesam valorile din vector folosind indici constanti...1.72 - .2 Citirea si scrierea vectorilor Vom prezenta in continuare primele operatii pe vectori. cout << "A: " << A[4] << " " << A[3] << " ". cin >> A[0] >> A[1] >> A[2] >> A[3] >> A[4].

#include <iostream> using namespace std. element cu element for(i=0.i--) cout << A[i] << " ".// vectorul si lungimea curenta (0<= n <=100) cin >>n.i<n.i++) cout << A[i] << " ". P4. element cu element . lungime limitata doar de modul in care am declarat vectorul. atunci cand ne referim la un vector.i<n. for(i=0. De acum inainte. (varianta 2) #include <iostream> using namespace std. for(i=4.n). unde A este vectorul. Se citeste un vector de la tastatura.i++) cin >> A[i]. Se citesc cinci valori ale unui vectori de intregi.i>=0. Afisati vectorul pe ecran.i<5. cout << "A: ". pentru a creste flexibilitatea programului.n.i++) cin >> A[i]. int main(){ int A[5]. cout << "Dati elementele vectorului A:". for(i=0. int i.i.Introducere in ANSI C++ P3. // citim lungimea vectorului // apoi vectorul. Afisati vectorul in ordine inversa. ne vom referi la o pereche de forma (A.73 - . vom da posibilitatea utilizatorului sa foloseasca vectori de lungime variabila. iar n este lungimea actuala a acestuia. } 4 3 4 1 2 3 4 1 2 // afisarea. int main(){ int A[100]. } Dati elementele vectorului A:3 4 5 6 7 A: 7 6 5 4 3 In general.

cin >> A[i]. cout << "n=". for(i=0. } n=3 A[0]=7 A[1]=15 A[2]=9 A=(7. folosind o varianta de citire/scriere user-friendly. int main(){ int A[100].n.i<n.i++) foloseste(A[i]). .i<n-1.i++){ cout << "A[" << i << "]=". (varianta cosmetizata) #include <iostream> using namespace std.". pe calculator. Se citeste un vector de la tastatura.i++) cout << A[i] << ". int i. for(i=0. cout << A[n-1] << ")". Modul in care folosim elementele vectorului depinde de la problema la problema.9) In general recomand folosirea variantei simple daca lucram programul „pe foaie”. urmatoarea schema generala: for(i=0.i<n. Dupa cum observam in ultimele exemple. Afisati vectorul pe ecran. accesul la elementele vectorului (A. cin >>n. orice varianta practica. } cout << "A=(".n) respecta.Introducere in ANSI C++ Aspectul „sec” al aplicatiei este remediat in exemplul urmator: P5. in general.74 - .15.

. int i.0 D: 0. In problema urmatoare exploatam relatia dintre indicele si valoarea memorata pe pozitia respectiva: P6.75 - .i++) for(i=0.. B[i]= (i%2==0)? 0:i...2. cin >>n. for(i=0. cout << "n=".B[100].Introducere in ANSI C++ 6. Generati si afisati pe ecran urmatorii vectori de lungime n.i<n.C[100]. D[i]=i%2..1.i<n. " ".4. #include <iostream> using namespace std.i++) cout cout cout cout } n=10 A:1 2 3 4 5 6 7 8 9 10 B:0 1 0 3 0 5 0 7 0 9 C:9 8 7 6 5 4 3 2 1 0 D:0 1 0 1 0 1 0 1 0 1  << << << << A[i]=i+1.i<n.0.i<n. for(i=0.D[100].1.n.. for(i=0.n-2..4.i++) cout << D[i] << .i<n.i<n.i++) for(i=0. " "..6.. C[i]=n-1-i. . A: 1. for(i=0.2.3 Generari de vectori Uneori elementele vectorilor nu vor fi valori citite de la tastatura ci valori construite in functie de enunt.i++) for(i=0.. "A:".1.i++) cout << B[i] << "\nC:". for(i=0.3. Se citeste de la tastatura un numar intreg 1<=n<=100.. ".i<n. " ".. 2. int main(){ int A[100].i++) cout << A[i] << " "\nB:".0.i<n. B: 0. C: n-1.0.i++) cout << C[i] << "\nD:". Urmatoarele exemple ilustreaza cateva cazuri mai des intalnite in practica.0.

i++) cout << D[i] << .. Se citeste de la tastatura un numar intreg 1<=n<=20.. C[i]=2*C[i-1].i++) D[0]=0. for(i=0. for(i=0.Introducere in ANSI C++ Generarea recursiva a vectorilor este o varianta intuitiva de rezolvare.76 - . B: 1. #include <iostream> using namespace std.i<n.i++) cout << B[i] << "\nC:". daca enuntul problemei permite folosirea unei relatii prin care construim un element in functie de cele deja generate.B[20].i<n.i++) cout << A[i] << " "\nB:". B[i]= B[i-1]+B[i-2].i++) B[0]=B[1]=1.1. " ". cout << "n=". " ".8. cin >>n. A: 1.1.i<n. P7.i<n. for(i=2..4.i++) C[0]=1.i<n. for(i=1.0..i.i<n. "A:". int main(){ int A[20].i<n.3. for(i=1. Generati recursiv.2.2.. " ".2.i++) cout cout cout cout } n=10 A:1 2 3 4 5 6 7 8 9 10 B:1 1 2 3 5 8 13 21 34 55 C:1 2 4 8 16 32 64 128 256 512 D:0 1 0 1 0 1 0 1 0 1  << << << << A[i]=A[i-1]+1. D: 0. ". for(i=1..D[20]...8.16. C: 1. apoi afisati pe ecran urmatorii vectori de lungime n. long C[20].4. A[0]=1. for(i=0.1. D[i]=!D[i-1].i<n.n.i++) cout << C[i] << "\nD:"...0..3..5. for(i=0.

Adunand la aceasta valoare a. maximul valorilor din vector . 6. cout << "n=". cin >>n. Generati un vector de lungime citita de la tastatura. a<b.i<n. P8. } n=10 a=30 b=40 A:36 40 36 32 31 34 30 36 33 31 Functia rand().4 Cateva probleme simple Vom da mai departe cateva probleme simple cu vectori.a. stdlib.i++) cout << A[i] << " ".77 - .b.b-a]. va returna un numar de tip long int pseudo-aleator. int i.n. for(i=0.i<n. produsul elementelor pare din vector c. for(i=0. probleme intalnite des in practica.b]. cout << "A:". cout << "b=". suma valorilor din vector b.i++) A[i]=a + rand()%(b-a+1). in cazul acesta [0. continand valori aleatoare in intervalul [a. cout << "a=". Afisati: a. Operatia modulo va face ca valoarea aleatoare „sa cada” in intervalul ales de noi. cin >>a. definita intr-o biblioteca standard ANSI C++. vom obtine valoarea aleatoare in intervalul dorit. Se citeste un vector de la tastatura. int main(){ int A[100]. P9.Introducere in ANSI C++ Generarea de valori aleatoare in vectori poate fi utila daca dorim testarea unor algoritmi pe vectori si dorim sa evitam introducerea de valori de la tastatura. cin >>b. numere pozitive. #include <iostream> using namespace std.

.Introducere in ANSI C++ d.78 - .P=1. +A[2n-2]/A[2n-1] F=max(A[0]) + max(A[0]. Calculati si afisati pe ecran: E=A[0]/A[1]+A[2]/A[3]+ . n citit de la tastatura.. cout << "n=". if (A[i]%2==0) P=P*A[i]... int main(){ int A[100]. for(i=0.max(A[0]. for(i=0.n. int S.A[1]..A[2n-1]) .. cout << "\nProdusul valorilor pare: " << P.i<n. } n=6 1 ­1 2 ­2 3 ­3 Suma: 0 Produsul valorilor pare: ­4 Maximul: 3 minimul valorilor pozitive: 1 P10. cin >>n.. Generati un vector aleator de 2n elemente din [1.10].i++) cin >> A[i].i. minimul valorilor pozitive #include <iostream> using namespace std.P..i++){ S=S+A[i].i<n.A[1]) + . S=0. n<10. } cout << "Suma: " << S.

i<2*n. int F. simetric . for(i=0. max=-MAXINT. } n=2 Vectorul:4 7 8 6 E: 1.90476 F: 27 P11.Introducere in ANSI C++ #include <iostream> #include <values.79 - . Verificati daca un vector citit de la tastatura este sau nu: a. in rest fiecare element de obtine insumand cele doua valori anterioare) c.i++) cout << A[i] << " ".i. F=0. for(i=0.max. float E. for(i=0.i++){ if(A[i]>max) max=A[i]. sortat crescator b. for(i=0. cin >>n.i<2*n. cout << "\nF: " << F.n.h> using namespace std.i<2*n-1. cout << "\nE: " << E. F=F+max.i+=2) E = E + float(A[i])/A[i+1]. cout << "n=". int main(){ int A[20].i<2*n.i++) A[i]=1+rand()%10. este sir Fibonacci (primele doua vaori sunt 1. } cout << "Vectorul:". E=0.

sau: n=6 1 6 2 2 6 1 Vectorul dat nu este crescator. cin >>n.80 - .j.i++.i++) cin >> A[i]. for(i=0. bool cresc. cresc=true.j--) if (A[i]!=A[j]) sim=false. if (!sim) cout << "nu ". este Fibonacci.". for(i=0.j=n-1.n. este simetric. for(i=0. if ((A[0]==1)&&(A[1]==1)) fibo=true.i<n. nu este Fibonacci. int main(){ int A[100].i++) if (A[i]>A[i+1]) cresc=false. sim. ".i++) if (A[i]!=A[i-1]+A[i-2]) fibo=false. fibo. cout << "este Fibonacci.Introducere in ANSI C++ #include <iostream> using namespace std. if (!cresc) cout << "nu ".fibo && i<n-1.i<n-1. . nu este simetric. cout << "este simetric. cout << "este crescator. for(i=2. ". cout << "Vectorul dat ". if (!fibo) cout << "nu ".i. cout << "n=". sim=true.sim && i<j. } n=5 1 1 2 3 5 Vectorul dat este crescator.

for(i=0. cin >>n.j. [6]. este problema reasezarii elementelor in asa fel incat ele sa respecte o relatie de ordine (crescatoare).i<n-1. .. prin interschimbarea lui A[0] cu acele elemente dintre A[1]..i<n. P12. int main(){ int A[100].i++) cin >> A[i]. cout << "n=".81 - ..j++) if (A[j]<A[i]){ t=A[i]. Sortarea prin selectie #include <iostream> using namespace std.A[i+1]. A[j]=t.A[n-1] care sunt mai mici ca A[0].t..repetam algoritmul descris la pasul anterior pe cazul general.5 Sortarea si interclasarea Problema sortarii unui vector.j<n.i++) cout << A[i] << " ".A[2].A[n-1] . for(i=0..Introducere in ANSI C++ 6..n.la sfarsit toate valorile sunt pe pozitiile corecte . for(i=0.aducem pe prima pozitie elementul minim din vector. } cout << "Vectorul sortat: " . Prezentam in continuare trei metode de sortare consacrate. Problema este bine reprezentata in literatura de specialitate (vezi [1].. aducand pe pozitia A[i] minimul dintre A[i]. A[i]=A[j].i++) for(j=i+1.i. } n=5 2 4 5 1 3 Vectorul sortat: 1 2 3 4 5 Ideea „din spatele”algoritmului este urmatoarea: . [8]).i<n. [4].

82 - . for(i=0. elementul maxim a ajuns sigur pe ultima pozitie .i++) cout << A[i] << " ".i<n.t.k.i<n. for(i=0.comparam.i++) if (A[i]>A[i+1]){ t=A[i].i. din maxim n-1 treceri vor avea vectorul sortat crescator .repetari succesive ale algoritmului vor duce la deplasari ale elementelor mari spre sfarsit.k<=n-1. toate valorile succesive din vector . Bubble Sort #include <iostream> using namespace std. cin >>n.in urma primei treceri prin vector. } n=5 2 4 5 1 3 Vectorul sortat: 1 2 3 4 5 Ideea este urmatoarea: .Introducere in ANSI C++ P13.i<n-1. A[i+1]=t. A[i]=A[i+1]. atunci interschimbam elementele .i++) cin >> A[i].cum la fiecare trecere cel putin un element ajunge la locul corect. cout << "n=".n. for(k=1. pana la ocuparea pozitiei corecte . rand pe rand. int main(){ int A[100]. } cout << "Vectorul sortat: " .k++) for(i=0.daca elementul din stanga este mai mare ca cel din dreapta.

nu avem decat sa completam valorile.odata avut vectorul de contori. cout << "\nVectorul sortat: " .i++) A[i]=rand()%10.i++) cout << A[i] << " ". de cate ori trebuie in vectorul rezultat .k<10. int main(){ int A[100]. cu m cunoscut si nu foarte mare. for(i=0. for(i=0.Introducere in ANSI C++ P14.i<n. de la cea mai mica la cea mai mare. for(i=0. int ct[100].k.i++) cout << A[i] << " ". #include <iostream> using namespace std. Pentru problema noastra am considerat m=10. for(k=0.j<=ct[k].i++) ct[i]=0. cin >>n. Sortarea prin numarare Pentru a putea aplica sortarea prin numarare.m]. cout << "Vectorul initial: ".i<n. // completarea valorilor in vector i=0.n.83 - . se stie ca intervalul in care A[i] poare lua valori este de forma [0. } n=10 Vectorul initial: 3 6 7 5 3 5 6 2 9 1 Vectorul sortat: 1 2 3 3 5 5 6 6 7 9  Functionarea algoritmului: .i<n. for(i=0.j++) A[i++]=k. // contorizarea valorilor din vector for(i=0.numaram fiecare valoare de cate ori apare in vector .i++) ct[A[i]]++.j.i.i<10.i<n. cout << "n=".k++) for(j=1.

} A: 2 4 5 7 10 B: 1 4 5 7 9 12 16 C: 1 2 4 4 5 5 7 7 9 12 16 10  Vectorii au fost generati aleator. A[0]=2.i++) A[i]=A[i-1]+1+rand()%3. cout << "\nB: ". cout << "A: ". n=2+rand()%10. int main(){ int A[100].Introducere in ANSI C++ Interclasarea se definiste ca fiind algoritmul care. while ((i<n)&&(j<m)) if (A[i]<A[j]) C[k++]=A[i++]. .m.i<n. cout << "\nC: ". i=j=k=0.i<m+n.i. while(i<n) C[k++]=A[i++]. m=2+rand()%10.i++) cout << C[i] << " ". obtine un al treilea vector sortat continand elementele vectorilor initiali.i++) cout << B[i] << " ". P15. for(i=0.i++) B[i]=B[i-1]+1+rand()%4. while(j<m) C[k++]=B[j++]. else C[k++]=B[j++]. dar in ordine crescatoare. for(i=1.j.i<m.B[100]. int C[100]. B[0]=1.i<n.i<m. primind doi vectori sortati.84 - .for(i=0.k. for(i=1.i++) cout << A[i] << " ". Interclasarea vectorilor #include <iostream> using namespace std.for(i=0.n.

{3. numite de acum. Declararea unei matrici: tip nume[dimensiune1][dimensiune2]  sau. #include <iostream> using namespace std. cout << "A[10][10] ocupa " << sizeof(A) << " octeti". } A[10][10] ocupa 400 octeti B[4][3] ocupa 48 octeti 6. pe langa vectori. matrici bidimensionale si multidimensionale.[dimensiunen] Cele mai folosite.4}.. .3. Declarari de matrici. matrici.Introducere in ANSI C++ 6. int main(){ int A[10][10]. P16. pe langa matricile unidimensionale (vectorii). pentru o declaratie de forma int A[10][10] indicii corespunzatori sunt dati in Figura 6.2}. float B[4][3]={{1. tip nume[dimensiune1][dimensiune2]. Astfel. Cantitatea de memorie ocupata de matrici.6}}. valori ce vor fi completate in matrice pe linii.7 Citirea si afisarea matricilor Accesul la elementele unei matrici se face tot prin intermediul indicilor. Exista posibilitatea initializarii elementelor unei matrici.85 - . {5. dand un „vector de vectori” de valori. sunt matricile bidimensionale. din comoditate.6 Declararea matricilor Limbajul C++ permite. cout << "\nB[4][3] ocupa " << sizeof(B) << " octeti".. mai general.

. A[0][2] A[1][2] . cout << "n=". . for(i=0. cout << "m=".i<n...cin >>n.Introducere in ANSI C++ Coloana 0 Coloana 1 Coloana 9 Linia 0 Linia 1 A[0][0] A[1][0] .. } } n=2 m=2 A[0][0]=1 A[0][1]=2 .i++) for(j=0. cin >> A[i][j]..j++) cout << A[i][j] << " ".m...86 - .j<n. cout << endl.j. Linia 9 A[9][0] A[9][1] A[9][2] .i..n..... Afisati matricea.j++){ cout << "A[" << i<< "][" << j << "]=". A[0][9] A[1][9] . . } for(i=0..i<n.. A[0][1] A[1][1] . #include <iostream> using namespace std.cin >>m.3 P17. A[9][9] Figura 6. int main(){ int A[10][10]. Se citeste o matrice de la tastatura.i++){ for(j=0.j<n.

i++) cout<<A[i][j]<<" ". Primul indice reprezinta linia.8.8 Probleme cu matrici P18.87 - . cout << endl.i.i<n.j.i<n. iar al doilea coloana.2.m=3.j++){ for(i=0.Introducere in ANSI C++ A[1][0]=3 A[1][1]=4 1 2 3 4 Analog citirii vectorilor. } } 1 4 7 2 5 8 3 6 9 . for(j=0. {4.5. citirea efectiva a elementelor din matrice este precedata de specificarea numarului de linii si de coloane.j++) foloseste(A[i][j]).i++) for(j=0.6}. parcurgerea pe linii a unei matrici are loc astfel: for(i=0. Afisati pe coloane o matrice initializata din cod #include <iostream> using namespace std.j<n. int n=3.j<m. {7. 6.3}. int main(){ int A[10][10]={ {1.9}}. In general.

cout << "m=". v=1. B[10][10].j++){ A[i][j]=i+1. cout << endl.j++) cout << A[i][j] << " ".i++) for(j=0.j<n. C[10][10].v.i<n. } for(i=0. C[i][j]=v++.j++) cout << B[i][j] << " ".j++) cout << C[i][j] << " ".j<n. int main(){ int A[10][10].j<n. cout << "n=".j.i<n. cin >> m. cout << endl.i<n. B[i][j]=(i+j+1)%2.i<n.m. } for(i=0. cout << endl.j<n. for(i=0. } } 1   0   1   0 0   1   0   1 1   0   1   0 0   1   0   1 1   2   3   4   5   6   7   8   9   10  11  12   13  14  15  16   .i.Introducere in ANSI C++ P19.i++){ for(j=0. } for(i=0.88 - . int n.i++){ for(j=0.i++){ for(j=0. Generati si afisati urmatoarele matrici: 1   1   1   1 2   2   2   2 3   3   3   3 4   4   4   4 #include <iostream> using namespace std. cin >> n.

4 P20. else A[i][j]=4.i<n. } } .i++) for(j=0.89 - .i++){ for(j=0.i. vorbim despre diagonala principala si cea secundara. } for(i=0. if ((i==j)||(i+j==n-1)) A[i][j]=1.j++) cout << A[i][j] << " ". else if (i+j<n-1) A[i][j]=5. n. int main(){ int A[10][10]. cout << "n=".j.i<n. cin >> n. cout << endl.4: i+j<n-1 == i+ j n1 i>j i= =j i<j i+j>n-1 Figura 6. for(i=0.Introducere in ANSI C++ In cazul in care numarul de linii si cel de coloane este identic spunem despre matrice ca este patratica.j++){ if (i<j) if (i+j<n-1) A[i][j]=2. Relatia dintre indici raportata la diagonale este data in Figura 6.j<n.j<n. Completati o matrice sub forma: 1 5 5 5 5 1 2 1 5 5 1 4 2 2 1 1 4 4 2 2 1 1 4 4 2 1 3 3 1 4 1 3 3 3 3 1 #include <iostream> using namespace std. else A[i][j]=3. In acest caz.

int main(){ int A[10][10].j>=0.j<n. #include <iostream> using namespace std. } for(i=0. } } 0 2 4 5 0 0 9 1 1 2 3 4 1 5 7 0 . O matrice contine cifre pe primele n-1 linii. t=t/10. for(i=0. A[n-1][j]=t%10.Introducere in ANSI C++ P21.j<n.i++){ for(j=0.i<n-1.i<n.i.i++) for(j=0. n.j--){ for(i=0.j.90 - . completati pe ultima linie suma numerelor zecimale de pe liniile date. t=0. cout << endl.j++) cin >> A[i][j].t.i<n-1. cin >> n. cout << "n=".i++) t+=A[i][j].j++) cout << A[i][j] << " ". Considerand fiecare rand al matricii ca fiind numarul in baza 10 corespunzator. for(j=n-1.

Se citeste o matrice de la tastaura..1 satisfac proprietatea ceruta. afisand mesaje sugestive pe ecran. Pp6..100]. Generati un vector continand valori din [1.3 si b:1. Determinati daca cei doi vectori sunt formate din aceleasi valori. Calculati: S=a[0]*a[1]+a[1]*a[2] + . (tribonacci :)) Pp2.. Verificati daca elementele de pe diagonale sunt in ordine crescatoare sau descrescatoare. Generati un vector continand n valori intregi in intervalul [-100.2.9 Probleme propuse Pp1.91 - . b: 1 2 3 5 7 11 . Un vector contine cifre.. indiferent de ordine si cate ori apar.. O matrice contine valori in intervalul [1.. + a[n-2]*a[n-1] E = suma valorilor cu indice prim F = produsul ultimelor cifre Pp3. (primele n numere prime) c: 1 1 1 3 5 9 17 . ca linie sau coloana. in ordine descrescatoare. Care este cel mai mare numar de trei cifre care poate fi format din cifrele vectorului? Pp5.3. Verificati de cate ori regasim vectorul in matrice. Generati si afisati vectorii (n intreg citit de la tastatura): a: 1 0 2 0 3 0 . De exemplu a: 1.. Se citesc o matrice patratica de nxn si un vector de lungime n. Pp7. Pp8. Pp4. Mutati valorile pozitive la incepu si cele negative la sfarsitul vectorului (dintr-o singura parcurgere).1..2. Se citesc doi vectori de intregi de la tastatura. Se citeste un vector de la tastatura.100].100] care NU se regasesc in matrice.Introducere in ANSI C++ 6. .

.cn” Urmatorul stil de initializare nu este recomandat.. desi este suportat de catre compilator: char nume[dimensiune]={c1. #include <iostream> using namespace std. octeti\n". char nume[]=”c1c2. 7..cn”. octeti"..'z'}..// sir initializat X[]="abc". // initializare corecta Y[]={'x'. acestui tip structurat de date i s-a acordat o atentie deosebita..Introducere in ANSI C++ Capitolul 7 – Siruri de caractere Datorita gradului de utilizare.c2. int main(){ char char char char cout cout cout cout } Vectorul S ocupa 100 octeti Vectorul s ocupa 20 octeti Vectorul X ocupa 4 octeti Vectorul Y ocupa 4 octeti S[100].1 Declaratie si initializare Forma generala a declaratiei unui sir de caractere este: char nume[dimensiune] sau sau char nume[dimensiune]=”c1c2. // sir neinitilalizat s[20]="Ana are laptop". Exemple de declarari/initializari de siruri. plus o serie functii de uz general pe siruri de caractere definite in biblioteca standard. exista functii de citire/scriere specifice.'y'. // initializare nerecomandata << << << << "Vectorul "Vectorul "Vectorul "Vectorul S s X Y ocupa ocupa ocupa ocupa " " " " << << << << sizeof(S) sizeof(s) sizeof(X) sizeof(X) << << << << " " " " octeti\n".cn} P1..92 - .. octeti\n". .

Cum unui caracter ii este necesar un octet pentru a fi memorat. In general. In exemplul anterior observam ca.Introducere in ANSI C++ Vom exemplifica in constinuare modul de memorare a sirurilor de caractere in C. trebuie tinut cont de terminatorul NULL.1 Acelasi lucru se intampla atunci cand folosi constante de tip sir de caractere. Caracterul ‘\0’ este caracterul cu codul ASCII egal cu zero si este diferit de caracterul ‘0’. compilatorul adaugand automat terminatia NULL. . int main(){ cout << "Caracterul \'A\' ocupa " << sizeof('A') << " octeti\n". } Caracterul 'A' ocupa 1 octeti Sirul "A" ocupa 2 octeti Este necesara folosirea secventelor escape pentru afisarea ‘ si ”.93 - . deci practic trebuie sa declaram cu dimensiune cu 1 mai mare decat a sirului efectiv.. cout << "Sirul \"A\" ocupa " << sizeof("A") << " octeti\n".1: ‘ a’ X[0] ‘ b’ X[1] ‘ c’ ‘ \0’ ? . Diferenta dintre un caracter si sirul de caractere corespunzator. observam ca s-a alocat un octet in plus. in urma declaratiei char X[]=”abc”. Pentru exemplul de mai sus avem urmatoarea situatia dinfigura 7. Diferenta de reprezentare dintre un caracter si sirul de caractere identic este evidentiat de exemplul urmator. Motivul este cel ca in limbajul C este folosit terminatorul NULL pentru a marca sfarsitul unui sir de caractere. P2. #include <iostream> using namespace std. in cazul in care declaram o variabila de tip sir de caractere. Figura 7.. in memorie X ocupa 4 octeti.

2 Operatii de citire/scriere pe siruri de caractere Citirea si scrierea sirurilor de caractere este mult simplificata fata de citirea vectorilor.2 7.S2[100]. #include <iostream> using namespace std. Citirea/scierea sirurilor de caractere. cin. int main(){ char S1[100].Introducere in ANSI C++ Diferenta de reprezentare este evidentiata de Figura 7. cin >> S2.94 - . cout << "Introduceti un sir: ".2: ‘ A’ ‘ A’ ‘ \0’ Caracterul ‘ A’ Sirul de caractere “A” Figura 7.getline(S1. Urmatorul exemplu da diferite moduri de citire/scriere: P3. cout << "Al doilea sir introdus: " << S2. } Introduceti un sir: Ana are laptop Introduceti inca un sir: Ana are laptop Primul sir introdus: Ana are laptop Al doilea sir introdus: Ana . // citeste inclusiv spatiile cout << "Introduceti inca un sir: ". nu mai este necesara memorarea lungimii actuale (datorita terminatorului NULL) si nu trebuie sa citim caracter cu caracter. // citeste pana la primul caracter "alb" cout << "Primul sir introdus: " << S1 << "\n".100).

Observam conditia de oprire S[i]. foloseste caracterul curent”. In cuvinte. adaugarea terminatorului NULL este realizata in mod automat.Introducere in ANSI C++ Observam ca citirea nu trebuie facuta caracter cu caracter. folosind o constructie de forma cin >> S. Daca dorim citirea caracter cu caracter.  citirea se opreste la primul caracter „alb” (spatiu.getline(S. Alte scheme utile: Verificarea daca un caracter este sau nu cifra: If ((c>=’0’)&&(c<=’9’)) foloseste(c). Verificarea daca un caracter este sau nu litera mare: If ((c>=’A’)&&(c<=’Z’)) foloseste(c). 7. Daca S este un sir de caractere. dar trebuie sa avem grija de terminatorul NULL. Citirea intregului rand. tab. La citire. adica pana la apasarea tastei Enter se face folosind: cin.3 Accesul la caracterele unui sir Daca dorim parcurgerea unui sir de caractere.S[i].i++) foloseste(S[i]).95 - . functiile pe siruri de caractere tinand cont de acesta. flosim urmatoare schema generala: for(i=0. . echivalenta cu S[i]!=NULL. schema de mai sus ar fi: „de la primul caracter si pana la caracterul NULL.dimensiune). enter). unde dimensiune este numarul maxim de caractere care va fi citit. acest lucru este posibil (in stilul citirii vectorilor).

Inlocuiti literele mici cu litere mari si invers. int i. #include <iostream> using namespace std.ct. } cout << S. cin. cout << "Numarul de cuvinte:"<<ct. for(i=1. } Introduceti un sir: abcDEF123 ABCdef123 P5.getline(S.i++) if ( (S[i-1]==' ') && (S[i]!=' ') ) ct++.96 - .'a' + 'A'. } Introduceti un sir: Ana are laptop Numarul de cuvinte:3 . else ct=0.Introducere in ANSI C++ P4.'A' + 'a'. cout << "Introduceti un sir: ". int i. Se citeste un sir de caractere cantinand cuvinte separate de unul sau mai multe spatii. Afisati numarul de cuvinte.S[i]. int main(){ char S[100].i++){ if ( (S[i]>='a')&&(S[i]<='z') ) S[i] = S[i] . Se citeste un sir de caractere fara spatii. if (S[0]!=' ') ct=1. else if ( (S[i]>='A')&&(S[i]<='Z') ) S[i] = S[i] .100). for(i=0. cin >> S. cout << "Introduceti un sir: ". #include <iostream> using namespace std.S[i]. int main(){ char S[100].

S2) atoi(S) i=atoi("123") strchr(S.S2) if (strchr(S.c) strstr(S1. else     cout << "Diferite". strcmp(S1.baza) . Cele mai utilizate sunt date in Tabelul 7."123". strcat(S. 7. if (strcmp(S1.S2)==0)     cout << "Egale".c))    cout << "L­am gasit!" itoa(S.S2) Efect Returneaza lungimea sirului dat ca paramentru Copiaza S2 peste S1 Concaterneaza S2 la S2 Compara lexicografic sirurile date ca parametri.nr.10) itoa(S.Introducere in ANSI C++ In problema P5."C++"). numarul de cuvinte este determinat numarand cate succesiuni de forma spatiu-caracter avem in sir."Imi place "). primul cuvant fiind numarat separat daca sirul nu incepe cu spatiu.h sunt definite o serie de functii utile pe siruri de caractere . Returneaza 0 daca S1==S2 <0 daca S1<S2 >0 daca S1>S2 Returneaza numarul intreg corespunzator sirului dat Returneaza o valoare pozitiva daca un caracter (respectiv sir) apare intr-un sir.97 - ."abcd") strcpy(S.S2) strcat(S1. in baza baza Tabelul 7.1 Exemple strlen("trei") ­> 4 strcpy(S.1: Functie strlen(S) strcpy(S1.4 Functii specifice sirurilor de caractere In biblioteca standard string. 0 in caz contrar Depoziteaza in S sirul corespunzator numarului nr.

getline(S. cin. } Introduceti un sir: Ana are laptop Lungimea:14 Lungimea (strlen):14 Observam ca functia strlen nu contorizeaza si terminatorul NULL.98 - . cout << "Introduceti un sir: ". .// i va contine la sfarsit lungimea cout << "Lungimea:"<< i << "\n". astfel scazand eficienta algoritmului.Introducere in ANSI C++ Observatii: – itoa nu este implementata in standardul ANSI C++. #include <iostream> #include <string.i++) . rezolvand problemele date atat folosind functiile de bilbioteca cat si implementand din cod. Nu este recomandata parcurgerea unui sir de caractere sub forma for(i=0. P6. Se citeste un sir de caractere. Afisati lungimea acestuia. Mai departe dam implementari posibile ale acestor functii.S[i].. dar este suportata de multe compilatoare.i++). int main(){ char S[100].100).h> using namespace std. int i.. for(i=0.i<strlen(S). cout << "Lungimea (strlen):"<< strlen(S). apelul functie strlen parcurgand de fiecare data tot sirul.

99 - . int i.i++) X[i]=S[i]. cout << "X: :"<< X << "\n".cpp:23: error: invalid operands of types ‘char [100]’ and ‘char  [100]’ to binary ‘operator+ . Se citeste un sir de caractere. In implementarea urmatoare am comentat apelul functiei strcat. de forma: S1=S2. va da mesajul de eroare: p09. for(i=0. cum ar fi afisarea. Analog exemplelor anterioare.cpp:21: error: ISO C++ forbids assignment of arrays P8.X[100]. trebuie sa avem grija de terminator. cin. nu vor actiona dupa asteptari.getline(S. cout << "Y (strcpy):"<< Y.Y[100]. Copiati-l in alt sir.100). strcpy(Y. observam ca folosirea functiei de biblioteca simplifica mult programul. cout << "Introduceti un sir: ". X[i]='\0'.h> using namespace std. p07.S). O atribuire de forma: X=S1+S2. Concaternati doua siruri de caractere. } Introduceti un sir: Ana are laptop X:        :Ana are laptop Y (strcpy):Ana are laptop // copiere din cod In cazul in care facem copierea din cod. Atribuire directa intre doua siruri de caractere (posibila in alte limbaje). in caz contrar alte operatii pe sir.S[i]. va da un mesajul de eroaren1=atoi(S1). #include <iostream> #include <string. int main(){ char S[100].Introducere in ANSI C++ P7.

cout << S. strcpy(S. int main(){ char nume[100].100 - . int i. iar litera mare va fi considerata mai mica fata de litera mica corespunzatoare (conform codurilor ASCII).getline(nume. cout << "Introduceti numele: ".j. In acest caz se va tine cont de ordinea lor lexicografica (cea din dictionar).100).h> using namespace std. S[j]='\0'.nume). . cin."Salut "). j=strlen(S). Am comentat in acest caz varianta in care am rezolvat fara apelul functiei strcmp.S[100]. Se citesc doua siruri de caractere.nume[i]. } Introduceti numele: Ana Salut Ana Exista posibilitatea de a compara doua siruri de caractere.Verificati ordinea lor lexicografica. for(i=0. Urmatoare exemple sunt sugestive: "A" < "a" "unu" == "unu" "pom" < "pomisor" "trei" > "patru"  !!!! P9.Introducere in ANSI C++ #include <iostream> #include <string.i++) S[j++]=nume[i]. // strcat(S.

cout << "Introduceti numarul 1: ".h> using namespace std. else cout << " este mai mare ca ".Introducere in ANSI C++ #include <iostream> #include <string.S1[i] && S2[i] && S1[i]==S2[i]. cout << "\""<<S1<<"\"". n2=atoi(S2). cout << "Introduceti numarul 2: ".j. #include <iostream> #include <string. n1=atoi(S1).S2[100].i++).S2)<0) cout << " este mai mic ca ".10). cout << "Introduceti sirul 2: ". int main(){ char S1[100]. cin. else if (strcmp(S1..100).getline(S1. } Introduceti sirul 1: trei Introduceti sirul 2: patru "trei" este mai mare ca "patru" P10. cout << "\""<<S2<<"\"". cin. apoi afisati pe ecran rezultatul. cout << "Introduceti sirul 1: ".100).101 - .n2.h> using namespace std.10).. if (strcmp(S1. if (S1[i]==S1[i]) cout << "EGALE!" else if (S1[i]<S2[i]) cout << "S1<S2" else cout << "S1>S2".getline(S1. int main(){ char S1[10]. cin. } Introduceti numarul 1: 123 Introduceti numarul 2: 234 123 + 234 = 357 . Se citesc doua siruri de caractere reprezentand numere intregi. rez=n1+n2.getline(S2.S2[10].n1. // // // // for(i=0.S2)==0) cout << " este egal cu ". cout << S1 << " + " << S2 << " = " << rez. cin. Faceti suma lor. int rez.getline(S2. int i.

Introducere in ANSI C++ P11. Verificati daca un nume apare intr-un sir.
#include <iostream> #include <string.h> using namespace std; int main(){ char nume[10],S[100]; int rez,n1,n2; cout << "Introduceti numele: "; cin.getline(nume,10); cout << "Introduceti sirul: "; cin.getline(S,100); if (strstr(S,nume)) cout << "\"" << nume << "\" apare in sirul \"" << S << "\""; else cout << "\"" <<nume<< "\" nu apare in sirul \"" << S << "\""; } Introduceti numele: Radu Introduceti sirul: Toni Alina Radu Cristi "Radu" apare in sirul "Toni Alina Radu Cristi"

7.5 Matrici de caractere
Utilizarea unui numar mare de siruri de caractere intr-o aplicatie implica folosirea unui sir de siruri de caractere. Urmatoarele exemple arata definirea si initalizarea unei matrici de caractere:
char S[10][10]={"Ana", "are","laptop"};

"laptop",

Pentru exemplul de mai sus, S[0] este "Ana", iar S[3],...,S[9] sunt siruri vide.

S[1]

este "are",

S[2]

este

In general, fiecare rand al unei matrici de caractere reprezinta un sir de caractere.

- 102 -

Introducere in ANSI C++ P12. Se citesc doua siruri reprezentand zile ale saptamanii. Folosind o matrice de caractere initializata cu zilele saptamanii, afisati zilele curinse intre cele citite de la tastatura.

#include <iostream> #include <string.h> using namespace std; int main(){ char zile[7][10]={

"luni", "marti", "miercuri", "joi", "vineri", "sambata", "duminica" };

char z1[10],z2[10]; int poz1,poz2,i; cout << "Introduceti ziua 1: "; cin.getline(z1,10); cout << "Introduceti ziua 2: "; cin.getline(z2,10); poz1=poz2=-1; for(i=0;i<7;i++){ if (strcmp(z1,zile[i])==0) poz1=i; if (strcmp(z2,zile[i])==0) poz2=i; } cout << "-----------------------\n"; if ((poz1==-1)||(poz2==-1)) cout << "Zile incorecte!"; else for(i=poz1;i<=poz2;i++) cout << zile[i] << "\n"; }

Introduceti ziua 1: marti Introduceti ziua 2: joi ­­­­­­­­­­­­­­­­­­­­­­­ marti miercuri joi

- 103 -

Introducere in ANSI C++

7.6 Alte aplicatii
P13. Se citeste un sir de caractere de la tastatura. Afisati toate prefixele si sufixele acestuia.
#include <iostream> #include <string.h> using namespace std; int main(){ char cuvant[100]; char copie[100]; int i,j; cin >> cuvant; cout << "Prefixe:\n"; strcpy(copie,cuvant); for(i=strlen(cuvant);i>0;i--){ copie[i]='\0'; // "mutam" sfarsitul cuvantului la stanga cout << copie<< " "; } cout << "\nSufixe:\n"; for(i=0;cuvant[i];i++){ for(j=i;cuvant[j];j++) cout << cuvant[j]; cout << " "; } } abcdef Prefixe: abcdef abcde abcd abc ab a Sufixe: abcdef bcdef cdef def ef f 

- 104 -

Introducere in ANSI C++ P14. Se citesc de la tastatura siruri de caractere pana la intalnirea sirului "stop". Afisati cuvantul de lungime maxima.

#include <iostream> #include <string.h> using namespace std; int main(){ char S[100],Smax[100]; cin >> S; strcpy(Smax,S); while (strcmp("stop",S)){ if (strlen(S)>strlen(Smax)) strcpy(Smax,S); cin >>S; } cout << "Cuvantul cel lung: " << Smax; }

mic mare scurt lung stop Cuvantul cel lung: scurt

- 105 -

Care este numarul minim de operatii elementare astfel incat sa obtinem din sirul initial unul avand toate literele mici sau toate literele mari. cate unul pe un rand. pana la citirea cuvantului "gata". Se citesc de la tastatura doua siruri de caractere continand doar cifre. Afisati cuvintele conponente. . Pp3. Se citeste un sir S. In locuiti toate aparitiile cuvantului C1 din testul S cu cuvantul C2.Introducere in ANSI C++ 7. O matrice de caractere contine cate un cuvant pe un rand. Pp5. calculati suma lor in alt sir.7 Probleme propuse Pp1. Un sir de caractere contine doar litere mici si litere mari. apoi afisati-le pe ecran. Pp2. Afisati cel mai lung cuvant care contine doar vocale. Se citesc de la tastatura cuvinte (fara spatii). Sortati cuvintele lexicografic. Pp4. Pp6.106 - . Prin operatie elementara intelegem transformarea din litera mica in litera mare sau invers. C1 si C2. continand cuvinte separate de exact un spatiu si doua cuvinte. Se citeste de la tastatura un sir de caractere continand litere mici si spatii. Considerand sirurile ca fiind numere in baza 10.

Sintaxa permite declararea directa.nume_data . nume_structura devine un nou tip de data. neexistand posibilitatea definirii altor variabile de forma data. Accesul la elementele unei structuri se face folosind operatorul ‘. Atat nume_structura cat si lista_variabile sunt optionale. prin aceasta. Avem: struct nume_structura{ declaratii_de_variabile. In acest caz vom folosi in program doar variabilele definite. Variabilele definite in bloc repezinta datele ce dorim sa le grupam. 8. tip care poate fi folosit la declararea unor variabile.Introducere in ANSI C++ Capitolul 8 – Structuri si alte tipuri utilizator Dupa cum am vazut. } lista_variabile. In acest capitol vom urmarii gruparea informatiilor corelate de tipuri diferite. } lista_variabile. Daca lipseste nume_structura. In C++. nume_structura lista_variabile.1 Structuri Gruparea informatiilor corelate de tipuri diferite se face prin utilizarea structurilor.’: variabila. un vector grupeaza sub un nume mai multe valori de acelasi tip.107 - . dar pot lipsi ambele in acelasi timp. avem o structura omonima: struct { declaratii_de_variabile. in momentul definirii unei structuri a unor variabile de acel tip.

Initializarea unei structuri se face intr-o maniera analoaga initializarii vectorilor."Gheorghe".1 ilustreaza reprezentarea in memorie a unei structuri. float inaltime. #include <iostream> using namespace std. prenume.nume << " " << P. . Deci daca avem: nume_structura V1. } Gates Gheorghe 31 In memorie o variabila de tip structura ocupa o zona continua de memorie.V2. daca cele doua variabile sunt de acelasi tip. }. int varsta. Figura 8.varsta++. char prenume[20].varsta. atunci atribuirea V1=V2. P. struct persoana{ nume char[20]. // definirea structurii cerute struct persoana{ char nume[20].1 Tipurile de date definite prin cuvantul cheie struct pot fi transmise ca parametri sau pot fi returnate din functii. }.Introducere in ANSI C++ Exista posibilitatea de a face atribuiri intre doua variabile de tip structura. int varsta. Definiti o variabila initializata de tipul persoana. apoi afisati pe ecran. Definiti structura persoana. P1. nume varsta inaltime 20 bytes sizeof(int) bytes sizeof(int) bytes Figura 8. continand (nume. int main(){ persoana P={"Gates". este valida.prenume << " " << P.108 - . cout << P.30}. varsta). mariti varsta cu 1.

}.im << endl.im + x. P=produs(z1. cout << "S=" << S. T.S.23607 .complex).re << "+i*" << P. T. float im. m=modul(z1). #include <iostream> #include <math. } S=6+i*1 P=7+i*9 m=2. // z1= 1+2i si z2=5-i float m.re = x.re + y. produs si modul.z2).im).im + y.im*x.re. } complex produs(complex x.im*y. complex produs(complex. float modul(complex). cout << "P=" << P. return T. T.im = x.re*x.im.P.im. Definiti structura complex (re.x. S=suma(z1. int main(){ complex z1={1.re = x.re + x. complex y){ complex T.109 - . complex suma(complex.z2={5.re .im).re << "+i*" << S.im*y. cout << "m=" << m.im << endl.Introducere in ANSI C++ P2.re*y.re.re*y.z2). struct complex{ float re. } complex suma(complex x. T.2}. Implementati functiile suma.h> using namespace std.im = x.complex).-1}. complex y){ complex T. return T. } float modul(complex x){ return sqrt(x.

} for(i=0.j++) if (P[i]. for(i=0.datan.an.an.t. } } Ana  12 8 2003 Luci 21 5 1998 Tom  5 12 2000 Luci  21/5/1998 Tom  5/12/2000 Ana  12/8/2003 .i<nr. P[j]=t.luna.an).i++){ cin >> P[i].zi >> P[i].an > P[j].i<nr.i<nr-1. int j.nume << " " << P[i]. #include <iostream> using namespace std.nr=3.i++) for(j=i+1. cout << P[i].luna >> P[i]. } for(i=0. int main(){ persoana P[10].datan.Introducere in ANSI C++ Putem defini vectori de structuri sau structuri care contin alte structuri.datan. struct data{ int zi.j<nr. P[i]=P[j].nume.i++){ cout << P[i].datan.an << endl. }. unde data nasterii este o alta structura (zi.luna. Cititi de la tastatura 3 persoane. cin >> P[i]. apoi afisati-le in ordine crescatoare dupa anul nasterii.zi << "/". struct persoana{ char nume[20].luna << "/" << P[i]. Definiti structura persoana (nume. data datan.110 - .datan. P3.datan.datan.i. }. data_nasterii).datan.an){ t=P[i].

Introducere in ANSI C++ 8. Definiti o uniune constinand un intreg si un sir de 4 caractere. . Folositi uniunea pentru a modifica octetii din componenta intregului. cantitatea totala de memorie obtinandu-se adunand cantitatea de memorie necesara fiecarei variabile componente in parte. P4. } lista_variabile.111 - . in total uniunea ocupand cat ocupa cea mai mare (dinpunct de vedere al necesarului de memorie) variabila componenta.2 Uniuni Dupa cum am vazut. Sintaxa: union nume_structura{ declaratii_de_variabile. datele interne vor ocupa aceeasi zona de memorie. In cazul care grupam date folosind uniuni. in cazul structurilor se aloca memorie pentru fiecare variabila declarata in structura.

I. cout << "000Fh = " << I. cout << "F000h = " << I.c[1]=255. union intreg{ unsigned int i. } 0000h = 0 F000h = 4278190080 0F00h = 16711680 00F0h = 65280 000Fh = 255 . I.c[0]=255. char c[4].i << endl. cout << "0000h = " << I. I. I.112 - .i.i << endl.i << endl. int main(){ intreg I. I.c[2]=255. cout << "00F0h = " << I.c[3]=255. cout << "0F00h = " << I.Introducere in ANSI C++ #include <iostream> using namespace std.c[2]=0.i << endl.c[3]=0. I. I. I.c[1]=0.i=0. }.

P. F.r=5.y. }. int main(){ figura F.y=20.C.y <<") ".C.x=10.x=15.A.B.10.A.D. #include <iostream> using namespace std.y <<") ". triunghi T. Definiti o uniune prin care putem memora oricare dintre figurile geometrice urmatoare: cerc.C. F. int r.D.B.B. dreptunghi.r << endl.y=2." << F. F. }. dreptunghi D. F.P.D. }.A. // cerc cout << "Cerc:" << F.B.A.2)  (15.D.20)  . } Cerc:10.x <<".x <<"." << F.x=1.C.D. // dreptunghi F.P.B.P. union figura{ cerc C.5 Dreptunghi: (1.113 - . }.y=10. struct cerc{ punct P.C. struct triunghi{ punct A. triunghi.C. }. struct dreptunghi{ punct A.D.D." << F." << F.x <<". cout << "Dreptunghi: (" << F. F.B.y <<".D.Introducere in ANSI C++ P5. struct punct{ int x. F. cout << " (" << F.C.

}.Introducere in ANSI C++ 8. unsigned var2:nr_biti. unsigned an:7. int main(){ data D={29. cout << D... }.73}.zi << " " << D. P6.3 Campuri de biti C++ permite alocarea de variabile la nivel de bit.114 - . Definiti si utilizati un camp de biti pentru stocarea unei date calendaristice. }lista_variabile. } 29 4 73 Pentru acest exemplu avem urmatoare situatie in memorie: struct data{ unsigned zi:5. unsigned an:7. struct data{ unsigned zi:5. . zi 0 4 5 luna 8 9 an 15 Figura 8.an. #include <iostream> using namespace std.4. unsigned luna:4.2 . unsigned luna:4. Tipul variabilelor din campul de biti trebuie sa fie unsigned int.luna << " " << D. struct nume_structura{ unsigned var1:nr_biti.

putem defini tipuri enumerate: enum nume_enumerare {lista_nume}.4 Tipul enumerat Pentru o mai mare claritate. for(i=luni. vineri. else cout << "liber ". P7. numele dintre acolade vor fi asociate cu valori de la 0 din 1 in 1. marti. } void Mesaj(int S){ if ((S>=luni)&&(S<=vineri)) cout << "treaba ". Putem forta valorile dorite prin atribuiri. nume_enumerare devine un tip de data care poate fi folosit ulterior. int i. #include <iostream> using namespace std. i++) Mesaj(i).ct. Analog structurilor. enum saptamana {luni. Datele de tip enumerare sunt considerate de tip int. int main(){ saptamana S. joi. } treaba treaba treaba treaba treaba liber liber  . Implicit. miercuri. i<=duminica. sambata.115 - . void Mesaj(int).Introducere in ANSI C++ 8. duminica}. Definiti si utilizati o enumerare pentru lucrul cu zilele saptamanii.

else cout << "e ok!". enum calificative { insuficient=4. suficient=5. Definiti si utilizati o enumerare care asociaza notele si calificativele. cout << "Dati o nota:". excelent=10 }. } Dati o nota:8 e ok! .Introducere in ANSI C++ P8.116 - . #include <iostream> using namespace std. cin >> nota. else if (nota==excelent) cout << "perfect!". if (nota<=insuficient) cout << "mai incearca!". bine=7. int main(){ int nota. else if (nota<=suficient) cout << "la limita!".

117 - . apoi afisat pe ecran. scadere si inmultire. Afisati dreptunghiul cu aria maxima.Introducere in ANSI C++ 8. O structura contine numele si data nasterii unei persoane. Sortati crescator dupa varsta.zi. . Definiti un vector continand elemente de acest tip. luna. O structura contine coordonatele (intregi) stanga sus si dreapta jos ale unui dreptunghi. Se citeste de la tastatura un vector de elemente de tipul definit anterior. cititi de la tastatura 5 valori.5 Probleme propuse Pp1. Pp3. O structura contine numele si numarul de selectii ale unui jucator de fotbal. apoi afisati in ordine crescatoare dupa numarul de selectii. Se citeste o matrice de dreptunghiuri astfel definite. Definiti o structura de lucru cu numare rational si implementati operatiile de adunare. Pp2. Pp4. sub forma an.

este folosirea prototipurilor. parametri de intrare. Vom prezenta mai departe modul de utilizare a functiilor (prototip. fara a scrie rezolvarea. aceasta trebuie sa fie cunoscuta de catre compilator. valoare returnata. functie in care am scris tot codul dorit. Un prototip reprezinta pentru o functie ceva similar declaratiei de variabila pentru o variabila. folosita in acest material. O functie reprezinta o colectie de declaratii si instructiuni de sine statatoare care rezolva o anumita subproblema.1 Generalitati Forma generala a unui algoritm este urmatoarea: date de intrare Algoritm date de iesire Figura 9. apel) si vom clasifica functiile in functie de utilizarea lor. forma generala a unei functii este data de: date de intrare Functie date de iesire Figura 9. este evident ca in cazul problemelor complexe este necesare o impartire in module a programului.2 este: . Folosind un prototip vom descrie comportamentul functiei. parametri de iesire. Modularizarea poate fi realizata in C/C++ folosind functii.118 - .1 Cum o functie modeleaza un algoritm (subalgoritm).Introducere in ANSI C++ Capitolul 9 – Functii Daca pana acum am folosit la scrierea programelor noastre doar functia main. 9. Forma generala a unui prototip al unei functii asociata algoritmului general din figura 9. A doua modalitate. altfel spus. definire.2 Inainte de utilizarea unei functii. vom descrie datele de intrare si cele de iesire din functie. Acest lucru se poate realiza definind functia inainte de locul apelului.

119 - . Definirea functiei. pentru acest caz. Definirea unei functii este de forma functie = antet + bloc sau. tipul void poate sa lipseasca. Daca in loc de tip returnat nu scriem nimic. in cazul parametrilor. Apelul functiei. . Numele functie poate fi orice identificator valid. pe larg: tip_returnat nume_functie(lista_parametri){ declaratii si instructiuni } Apelul sau utilizarea efectiva a functie are loc sub forma: nume_functie(lista_parametri). Tipul returnat si lista parametrilor vor da catalogarea din subcapitolele urmatoare. sau Observam ca. Prototipurile aasociate acestui caz sunt de forma: void nume_functie(). 9. mai putin in ainteriorul altei functii.2 Functii care nu primesc si nu returneaza nimic Forma generala a unei astfel de functii este: Functie Figura 9.Introducere in ANSI C++ tip_returnat nume_functie(lista_parametri). Pe locul apelului va aparea o valoare de tip tip_returnat. void nume_functie(void).3 Specificam lipsa valorii returnate folosind tipul de date void. poate avea loc in orice zona a codului sursa. va fi de forma: nume_functie(). tipul returnat implicit este int.

In general acest tip de functii vor afisa ceva pe ecran. void Mesaj(void). int main(){ Mesaj(). variabile declarate in cadrul blocului functiei. P1. un bradulet pe ecran. apoi afisati. Realizati o functie care sterge ecranul prin trecerea la rand nou de 30 de ori. Faptul ca functia nu primeste date de intrare nu ne impiedica sa folosim o serie de variabile de lucru pentru rezolvarea problemei. cout << "* Bine ati venit! *" << endl. . cout << "*******************" << endl.120 - . #include <iostream> using namespace std.Introducere in ANSI C++ Parantezele de dupa numele functiei nu sunt optionale. folosind o alta functie. Realizati o functie care afiseaza un mesaj de intampinare pe ecran. } ******************* * Bine ati venit! * ******************* P2. } void Mesaj(){ cout << "*******************" << endl.

void Bradulet().i<=30. endl.Introducere in ANSI C++ #include <iostream> using namespace std. Bradulet(). iar apelul: . for(i=1. void Sterge(). } void Sterge(){ int i.121 - . endl. dar primesc date de intrare Analog cazului anterior acest ip de functii vor afisa de obicei rezultatele pe ecran. endl. 9. endl. Forma generala este: date de intrare Functie Figura 9. } void Bradulet(){ cout << " * " cout << " *** " cout << " ***** " cout << " ******* " cout << " | " }     *    ***   *****  *******     | << << << << << endl.3 Functii care nu returneaza nimic.i++) cout << endl. int main(){ Sterge().4 Prototipul: void nume_functie(lista_parametri).

Introducere in ANSI C++
nume_functie(lista_parametri);

Vom descrie pentru acest caz, pas cu pas, ce se intampla in cazul apelului unei functii. Fie urmatoare problema: P3. Realizati o functie care, primind ca parametri doua numere intregi a si b, afiseaza pe ecran valorile pare din intervalul [a,b].
#include <iostream> using namespace std; void afisare(int,int); int main(){ afisare(2,7); } // prototip

// apel

void afisare(int a, int b){ int i; for(i=a;i<=b;i+=2) cout << i; } 246

// antet

Se observa ca atunci cand scriem prototul functiei se specifica doar tipul parametrilor de intrare. La scrierea antetului vom da si numele parametrilor de intrare, nume prin care vor fi accesati acestia in blocul functiei. Stiva, o zona de memorie speciala in care sunt salvate, in momentul apelului o serie de informatii despre functia apelata, cum ar fi adresa de revenire, parametri si variabilele declarate in functie (variabile locale). Avem urmatorii pasi: Pas 1. Inainte de apel:
Pozitia in program Stiva

int main(){ afisare(2,7); } vf

Figura 9.5

- 122 -

Introducere in ANSI C++ Pas 2. Apelul (intrarea in functie)
Pozitia in program Stiva

int main(){ afisare(2,7); } void afisare(int a, int b){ int i; ... } vf ? 7 2 i b a

Figura 9.5 In momentul apelului, se aloca pe stiva variabilele ce reprezinta parametri de intrare si variabilele definite in functie. Parametri a si b ai functiei (numiti parametri formali) vor prelua valorile date la apel (parametri actuali). In cazul in care apelul are ca parametri expresii, acestea trebuie sa aiba un tip compatibil cu al parametrilor formali. In acest caz, are loc evaluarea expresiei, rezultatul fiind atribuit parametrului corespunzator. Acest tip de apel poarta numele de apel prin valoare. Pas 3. Inainte de revenire
Pozitia in program Stiva

int main(){ afisare(2,7); } void afisare(int a, int b){ int i; ... } vf 8 7 2 i b a

Figura 9.6

- 123 -

Introducere in ANSI C++ Observam modificarea valorii variabilei locale i, conform instructiunilor executate. Pas 4. Revenirea din functie
Pozitia in program Stiva

int main(){ afisare(2,7); } vf

Figura 9.7

La iesire din functie, stiva revine la nivelul anterior apelului, iar variabilele locale si parametri formali dispar. Programul continua cu prima instructiune de dupa apel. P4. Realizati o functie care afiseaza un bradulet pe ecran, cu dimensiunea data de un parametru.

- 124 -

Introducere in ANSI C++

#include <iostream> using namespace std; void Bradulet(int); void Spatii(int); void Stelute(int); int main(){ Bradulet(3); Bradulet(5); } void Spatii(int n){ int i; for(i=1;i<=n;i++) cout << " "; } void Stelute(int n){ int i; for(i=1;i<=n;i++) cout << "*"; } void Bradulet(int n){ int i; cout << endl; for(i=1;i<=n;i++){ Spatii(n-i); Stelute(2*i-1); cout << endl; } Spatii(n-1); cout << "|" ; }   *  *** *****   |     *    ***   *****  ******* *********     |

- 125 -

Introducere in ANSI C++ P5. Folosind functii, afisati pe ecran urmatoare piramida de numere: 1 121 12321 ....................

#include <iostream> using namespace std; void void void void Spatii(int); Crescator(int); Descrescator(int); Piramida(int);

int main(){ Piramida(5); } void Piramida(int n){ int i; for(i=1;i<=n;i++){ Spatii(n-i); Crescator(i); Descrescator(i-1); cout << endl; } } void Crescator(int n){ int i; for(i=1;i<=n;i++) cout << i; } void Spatii(int n){ int i; for(i=1;i<=n;i++) cout << " "; } void Descrescator(int n){ int i; for(i=n;i>=1;i--) cout << i; }     1    121   12321  1234321 123454321

- 126 -

  Valoarea va fi returnata din functie folosind instructiunea return. // var compatibil cu tip_returnat if (expresie == nume_functie()) .. tip_returnat nume_functie(void). . } unde expresie este convertibil la tip_returnat.. Realizati o functie care returneaza valoarea lui Pi cu doua zecimale exacte.127 - .. sau: .. Exemple de apeluri: var=nume_functie().4 Functii care nu primesc date de intrare dar returneaza o valoare Forma generala este: date de iesire Functie Figura 9.8 Prototipul: tip_returnat nume_functie(). La revenirea din apel. Forma generala a definirii functiei: tip_returnat nume_functie(){ . return expresie. cout << nume_functie().. P6. moment in care se iese din functie.Introducere in ANSI C++ 9. pe locul apelului "apare" valoarea returnata.

cin >> X. } 12 45 29 1000 45 .14 P7. int main(){ cout << Pi(). float Pi(). } 3. } return mx. while(X<1000){ if (X>mx) mx=X. int main(){ cout << max(). mx=X. #include <iostream> using namespace std. } int max(){ int X. } float Pi(){ return 3. cin >> X. int max().128 - . Realizati o functie care citeste de la tastatura valori intregi (<1000) pana la intalnirea valorii 1000 si returneza minimul acestor valori.Introducere in ANSI C++ #include <iostream> using namespace std.14.mx.

iar pe locul apelului va aparea valoarea returnata. se revine automat din functie. P8. La intalnirea acestei instructiuni.b) modul(a) min(a. Exemple de apeluri: var = nume_functie(lista_parametri).5 Functii care primesc un numar oarecare de parametri de intrare si returneaza o singura valoare Este probabil cea mai utilizata varianta de functie.c) .9 Prototipul: tip_returnat nume_functie(lista_parametri).Introducere in ANSI C++ 9. Realizati urmatoarele functii: • • • max(a.129 - . Forma generala: date de intrare Functie data de iesire Figura 9. if (nume_functie(lista_parametri)==expresie) cout << nume_functie(lista_parametri) sau: sau: Valoarea este returnata din functie prin folosirea instructiunii return.b.

b. float y.130 - . cout << "min=" << x<< endl. cout << "b=". } int max(int a. float). float min(float. cout << "max(" << a << ".c. float. int b){ if (a>b) return a. cout << "|"<< a+b+c << "|=" << modul(a+b+c)<< endl. cin >>a. Realizati functiile cu urmatoarele prototipuri: • int sumac(int).Introducere in ANSI C++ #include <iostream> using namespace std. P9. int). cout << "c=". else return (y<z)?y:z. float(b)/c. cin >>c. cin >>b." << b << ")=" << max(a. else return b. x=min(float(a)/b . float z){ if (x<y) return (x<z)?x:z.3)=3 |­2|=2 min=­2 Observam diferite modalitati de a apela functiile cerute in enunt. cout << "a=".b) << endl. float(c)/a). } a=­6 b=3 c=1 max(­6. int max(int. int main(){ int a. int modul(int). } int modul(int x){ return (x>0)?x:-x. float x. } float min(float x. // suma cifrelor unui numar .

int int int int sumac(int). } int primac(int n){ while (n>=10) n=n/10. // suma divizorilor unui numar int primac(int). cin >> a. for(d=1. sumadiv(int).Introducere in ANSI C++ • • • int sumadiv(int). cout << "b=". } int fact(int n){ int i. primac(int). fact(int). } int sumadiv(int n){ int d.i<=n.b. // // // // suma cifrelor unui numar suma divizorilor unui numar prima cifra a unui numar factorialul unui numar int main(){ int a. return S.n>0. P=1. S=0. return P. } a=5123 << << << << "sumac(" << a << ")=" << sumac(a) << endl. cin >> b.P. .131 - .d++) if (n%d==0) S=S+d. "primac(" << a << ")=" << primac(a) << endl. // prima cifra a unui numar int fact(int). "fact(" << b << ")=" << fact(b) << endl.i++) P*=i. return n.n/=10) S+=n%10.d<=n.S. // factorialul unui numar #include <iostream> using namespace std. for(. cout cout cout cout } int sumac(int n){ int S. "sumadiv(" << a << ")=" << sumadiv(a) << endl. for(i=1. return S. cout << "a=". S=0.

bool perfect(int). return S. Realizati urmatoarele functii ce returneaza valori logice: bool prim(int). return true. } bool perfect(int n){ return sumad(n)==n.d<=n/2.d++) if (n%d==0) S+=d. } x=28 . int sumad(int). for(S=0. else cout << x << " nu este prim \n".d. if (perfect(x)) cout << x << " este perfect \n". if (prim(x)==true) cout << x << " este prim \n". for(d=2. // verifica daca un numar este prim sau nu bool perfect(int). } int sumad(int n){ int S. } bool prim(int n){ int d.132 - . else cout << x << " nu este perfect \n".d++) if (n%d==0) return false.d<=n/2. cin>>x. cout << "x=". // verifica daca un numar este egal cu suma divizorilor sai #include <iostream> using namespace std. int main(){ int x. bool prim(int).Introducere in ANSI C++ b=4 sumac(5123)=11 sumadiv(5123)=5280 primac(5123)=5 fact(4)=24 P10.d=1.

} x=100 Cel mai mare numar prim mai mic ca 100 este 97 9.133 - .d<=n/2. return n. cout << "Cel mai mare numar prim mai mic ca " << x.d++) if (n%d==0) return false. #include <iostream> using namespace std. afisati cel mai mare numar prim mai mic ca n (numar intreg citit de la tastatura). return true. int prim_mic(int). bool prim(int). Folosind functii.Introducere in ANSI C++ 28 nu este prim 28 este perfect P11. cin>>x.6 Functii ce returneaza mai multe valori Forma generala: date de intrare Functie date de iesire Figura 9. } bool prim(int n){ int d. } int prim_mic(int n){ while(!prim(n)) n--. int main(){ int x. . cout << "x=". for(d=2.10 Vom prezenta in continuare doua variante de realizare. cout << " este " << prim_mic(x).

. return T.134 - . iar prototipul va fi de forma: nume_structura  nume_functie(lista_parametri). Vom grupa sub numele unei structuri datele care vor fi returnate de catre functie. . P12.. Realizati o functie care calculeaza suma si produsul a doua numere reale. . Definirea functiei va respecta urmatoarea structura: nume_structura  nume_functie(lista_parametri){ nume_structura  T.Introducere in ANSI C++ O prima varianta este folosirea structurilor. } Structura T din cadrul functiei va contine datele de returnat... .. Apelul va fi de forma: nume_structura var. var = nume_functie(lista_parametri).

cout << a. . float produs. sau: void nume_functie(lista_parametri_intrare_si_iesire).5). In acest caz. transferul parametrilor prin valoare nu duce la modificarea parametrilor actuali. Dupa cum am vazut. a=sp(3.produs=a*b. prototipul ca fi de forma: void nume_functie(lista_parametri_intrare.135 - . } 8 15 A doua varianta este folosirea referintelor (2.produs. float b){ doua_numere T.float).suma=a+b. doua_numere sp(float. medificarea acestuia modificand de fapt paramatrul actual. In acest caz. T.5). int main(){ doua_numere a. parametrul formal devine un alias al celui actual. vom folosi parametri referinte. In cazul in care dorim modifiarea lor. }. T. chiar daca acestia sunt variabile (se lucreaza cu copii pe stiva). struct doua_numere{ float suma. return T. Apelul: nume_functie(lista_parametri). } doua_numere sp(float a.Introducere in ANSI C++ #include <iostream> using namespace std.suma << " " <<a. lista_parametri_iesire).

alte_doua_numere sp(int. cout << a. struct alte_doua_numere{ int min.int). } alte_doua_numere sp(int a.max.min=(a<b)?a:b.max.Introducere in ANSI C++ Evident. T.max= (a+b)-T. Realizati o functie care returnezeaza maximul si minimul a doua valori intregi. in acest caz paramatri actuali trebuie sa fie variabile de un tip compatibil parametrul formal corespunzator. T. P13.min << " " <<a.min. int b){ alte_doua_numere T. a=sp(6. . int main(){ alte_doua_numere a. Valorile vor fi deci "returnate" prin modificarea variabilelor din apel.136 - . } 2 6 P14. #include <iostream> using namespace std. return T.2). Functie care interschimba doua variabile. }.

mai putin alte blocuri interioare in care declaram o variabila cu acelasi nume.7 Variabile locale si globale. } void interschimbare(int& a. Deci durata de viata a unei variabile locale este din momentul declaratiei si pana la sfarsitul blocului.b). P15. cin >>b. Am vazut ca o variabila locala este alocata pe stiva. t=a.Introducere in ANSI C++ #include <iostream> using namespace std. este consacrat ca variabilele locale sa fie asociate cu blocurile functiilor. int& b){ int t. cout << a << " " << b. cout << "a=".a=b. Domeniul de vizibilitate este dat de blocul variabilei.b=t. Definirea variabilelor in cadrul blocurilor va face ca variabilele sa fie locale acelui bloc. interschimbare(a. int main(){ int a. void interschimbare(int& . int&). apare la intrarea in bloc (functie) si dispare la iesirea din bloc (functie). cout << "b=". cin >>a. iar domeniul de vizibilitate este zona in care putem utiliza variabila respectiva.137 - . Variabile locale (fara folosirea functiilor).b. } a=2 b=5 5 2 9. Chiar daca putem defini variabile in orice bloc. Durata de viata si domeniu de vizibilitate Durata de viata a unei variabile reprezinta timpul cat timp aceasta este alocata in memorie. .

chiar si in cazul in care variabila globala este "acoperita" de catre una locala cu acelasi nume. // a din bloc si b din blocul main { int b=100. // b din bloc si a din blocul main } } 5 12 5 100 11 6 Variabilele globale sunt variabile declarate in afara oricarui bloc. . Durata de viata este din momentul declararii si pana la incheierea programului. // a din blocul exterior si b din blocul interior } } { int b=6.b=12. { int a=5. putem folosi operatorul scope. cout << a << " " << b << endl. posibilitatea modificarii acestora din cadrul oricarei functii putand duce la erori logice (bugs) greu de depanat. In general nu este recomandata folosirea variabilelor globale. ::. cout << a << " " << b << endl. In acest caz var va fi variabila locala. pentru a accesa variabila globala din cadrul zonei respective. iar ::var cea globala. Totusi. cout << a << " " <<b << endl. int main(){ int a=11. mai putin blocurile in care a fost definita o variabila locala cu acelasi nume.138 - .Introducere in ANSI C++ #include <iostream> using namespace std. Domeniu de vizibilitate este intreg programul.

P17. Urmatoarea problema ilustreaza un astfel de bug datorat folosirii variabilei globale in locul unora locale. Desi nu vom avea erori de compilare. folosirea variabielor globale poate duce la erori logice. } 5 2 2 100 Folosirea variabilelor globale nu este recomandata. La afisarea unei piramide de numere. int a=2.Introducere in ANSI C++ P16. cout << a << " " << b << endl. Variabile locale si variabile globale #include <iostream> using namespace std. // variabila globala void f(){ int a=5. // locala in main f(). Varianta 1 – in cazul folosirii variabilelor locale . modificarea variabilei contor din main in cadrul functiei apelate va duce la o bucla infinita.139 - . } int main(){ int b=100. accesibilitatea acesteia din orice functie putand duce la erori logice greu de depanat. // locala in f cout << a << " " << ::a << endl.

i<=4.i++){ Descrescator(i). } } void Descrescator(int n){ int i. // i declarat local for(i=1. } } void Descrescator(int n){ // int i. // i declarat local for(i=1. cout << endl.i++){ Descrescator(i). // i declarat local for(i=n.140 - . cout << endl.i<=4. // i declarat local for(i=n. int main(){ int i. } 1 1 // i declarat global . } 1 21 321 4321 // i declarat global Varianta 2 –in cazul folosirii variabilelor globale #include <iostream> using namespace std.Introducere in ANSI C++ #include <iostream> using namespace std.i>=1. int i.i>=1. // int i. void Descrescator(int). int main(){ // int i.i--) cout << i. void Descrescator(int).i--) cout << i.

#include <iostream> using namespace std.1). int b){ return (a>b)?a:b.Introducere in ANSI C++ .8 Supradefinirea functiilor C++ permite folosirea a mai multe functii cu acelasi nume.int). Diferentierea dintre functii va fi facuta dupa tipul si/sau numarul parametrilor.c). Alt exemplu de supradefinire a functiilor .. int main(){ cout << max(2. int max(int.141 - .c).b. int max(int.int. (se intra in bucla infinita) 9.b). int c){ return max(max(a.5.. folosind max(a.b). Calculati max(a. } int max(int a. int b. } 5 P19.int). P18. } int max(int a..

.. } .142 - . int main(){ este(int(123)). este('e'). } void este(int n){ cout << n << " este un intreg" << endl.. void este(char)... void este(float)..14).cpp: In function ‘int main()’: p19. } void este(char n){ cout << n << " este un caracter" << endl.cpp:8: note:                 void este(char) ... este(3. am fi obtinut erori de compilare de forma: p19. } void este(float n){ cout << n << " este un real" << endl.cpp:14: error: call of overloaded ‘este(double)’ is ambiguous p19. void este(int).14)). este(char('e'))..14 este un real e este un caracter In cazul in care am fi avut apeluri ca in exemplul de mai jos ..Introducere in ANSI C++ #include <iostream> using namespace std.cpp:6: note: candidates are: void este(int) p19... este(float(3.cpp:7: note:                 void este(float) p19. } 123 este un intreg 3...... int main(){ este(123)....

// in acest caz ultimul parametru ca fi cel implicit } void afisare(int a.i<=b.int b. 9. void afisare(int a. param_initializati).2).8.int b. Functie cu parametri impliciti care afiseaza un interval. #include <iostream> using namespace std. sub forma: tip_ret nume_functie(param_neinitializati. In momentul apelului. for(i=a. afisare(1.int pas){ int i. int main(){ afisare(1. Valorile implicite vor fi specificate in prototip. cout << endl. In acest caz.8). de la dreapta la stanga.Introducere in ANSI C++ Deci apelurile in cazul functiilor supradefinite nu au voie sa introduca ambiguitati. P20. } 1 3 5 7 1 2 3 4 5 6 7 8 .int pas=1). valorile parametrilor lipsa vor fi date de valorile implicite. functia care va fi apelata fiind unic determinata in momentul apelului. cu un pas dat. sau: tip_ret nume_functie(param_initializati).9 Functii cu parametri impliciti In cazul in care apelul unei functii se face de obicei cu aceleasi valori.i+=pas) cout << i << " ".143 - . putem omite parametri cu valori implicite. putem folosi parametri impliciti pentru acea functie.

ar fi existat o ambiguitate si am fi avut o eroare de forma: p21.cpp:7: note:                 int max(int. } 5 8 In cazul in care functia ajutatoare ce calculeaza maximul a doua valori ar fi avut numele max (supradefinind functia cu parametri impliciti).144 - .int b=-MAXINT.int c=-MAXINT. int d){ return mx(mx(a.cpp:6: note: candidates are: int max(int. int main(){ cout << max(5. int max(int a=-MAXINT.5.3) << endl.cpp: In function ‘int main()’: p21. int) p21. De obicei numarul efectiv de valori din vector va fi transmis printr-un alt . int) 9.h> using namespace std. #include <iostream> #include <values.b).Introducere in ANSI C++ P21. int c.d)).8. alti_parametri).int d=-MAXINT). int.int b){ return (a>b)?a:b. int mx(int. alti_parametri). Functie cu parametri impliciti care calculeaza minimul a maxim patru valori. cout << max(1.2) << endl. int).mx(c.cpp:10: error: call of overloaded ‘max(int. int)’ is ambiguous p21.10 Parametri vectori Prototipul ca fi de forma: tip_returnat nume_functie(tip []. } int max(int a. Apelul: nume_functie(Vector. int. } int mx(int a. int b.

Transmiterea vectorului va a vea un comportament analog transmiterii prin referinta.Introducere in ANSI C++ parametru. Parametri nu se aloca pe stiva ca o variabila simpla. modificarile facute pe elementele vectorului in cadrul functiei fiind regasite in vectorul cu care s-a apelat functia. deci un vector de lungime 100 nu va ocupa din stiva 100*sizeof(tip) octeti. P22. Functii care realizeaza urmatoarele operatii pe vectori: • • • • initializare cu valori aleatoare citire afisare suma elementelor .145 - .

int). afisare(a.m). int).i++) cout << a[i] << " ". afisare(int [].146 - .i<n. } void afisare(int a[].m. cin >> n. } void citire(int a[]. // vectorul a de lungime efectiva n initializare(a. int b[10].Introducere in ANSI C++ #include <iostream> using namespace std.n). cin >> n. for(S=i=0. int &n){ int i. citire(b. cout << "\nn=".m).i<n.i++) a[i]=random()%100.n. int main(){ int a[100]. cout << endl. for(i=0.i<n. void void void long initializare(int []. } n=3 83 86 77 n=4 1 2 3 4 10 . } long suma(int a[]. } void initializare(int a[]. cout << "\nn=". int &n){ int i.n). int n){ int i.i<n. int n){ int i.S. for(i=0. int &). cout << suma(b. return S. suma(int [].i++) cin >> a[i]. for(i=0.i++) S+=a[i]. citire(int []. int &).

for(i=0. Realizati functii care fac: intersectia. l=0.c. int&). int c[].int. int&l){ int i.c. void intersectia(int [].m.n. reuniunea(a. int [].8. // completam prima multime l=n.b.14}. int b[].i<n.l). int.i++) cout << a[i] << " ". void afisare(int [].m=4. int c[].b. } bool este(int a[].n=3.n. for(i=0. int.l).l). int b[]. int c[]. int&). int m.m. int&).i++) if (!este(b.i++) c[i]=a[i]. int&l){ int i. for(i=0.int). bool este(int [].8}.// multimea in care tine rezultatul operatiilor intersectia(a.4. reuniunea. int b[].i<m.b[i])) c[l++]=b[i].n. } void reuniunea(int a[]. } void afisare(int a[].i++) if (!este(a. int [].m.i++) if (a[i]==val) return true. int m.l). diferenta(a. int m.i++) if (este(b.147 - .i<n. for(i=0. int n. } .l. diferenta #include <iostream> using namespace std. int n. int n){ cout << endl.l).c. for(int i=0. int n. int.int). int.a[i])) c[l++]=a[i].int n.int val){ int i. for(i=0. int [].i<n.// verifica daca o valoare este sau nu intr-o multime int main(){ int a[]={2. // prima multime int b[]={1. l=0. afisare(c. int.Introducere in ANSI C++ P23. int [].b.n.4. } void intersectia(int a[]. void diferenta(int [].l). Fie doi vectori reprezentand multimi de valori intregi. return false.m. int. afisare(c. } void diferenta(int a[].a[i])) c[l++]=a[i].i<n. int []. // a doua multime int c[10]. int []. afisare(c.m.i<n. int&l){ int i. void reuniunea(int [].

.Introducere in ANSI C++ 4 8 2 4 8 1 14 2  9. acolo unde este posibil. Reluati toate problemele rezolvate de pana cum. refaceti rezolvarile folosind functii.148 - . si.11 Probleme propuse Ppx.

. nume_functie(lista_parametri_actuali) }  } Recursivitatea poate fi utilizată pentru a rezolva elegant multe probleme. n ⋅ (n − 1)!. P1.. n = 0 n!=  ..149 - . forma generala a unei functii recursive va fi urmatoarea: tip_returnat nume_functie(lista_parametri_formali){ if (!conditie_de_oprire){ . .. Sa se realizeze o functie recursiva ce calculeaza n! Plecam de la formula recursiva de calcul 1. 10. n > 0 Rescriind formula intr-o varianta mai apropiata de implementarea C/C++. avem: . dar funcţiile recursive sunt adesea mai lente decât corespondentele lor nerecursive: la fiecare apel depun în stivă valorile parametrilor (dacă există) şi adresa de revenire (Cap. In practica. 9) complexitatea algoritmilor recursivi este de obicei mai mare decat a "fratilor" iterativi.Introducere in ANSI C++ Capitolul 10 – Recursivitate Numim functie recursiva o functie care se autoapeleaza (direct sau indirect).1 Recursivitatea directa In cazul in care functia contine in corpul ei un apel la ea insasi vorbim despre recursivitate directa.

return n*fact(n-1). long fact(int).150 - .Introducere in ANSI C++ 1. Pentru fact(3) avem urmatoarea succesiune de operatii: (1) calculeaza 3*fact(2). În problema factorialului. altfel returnează rezultatul înmulţirii dintre valoarea parametrului şi factorialul apelat cu valoarea parametrului minus 1. atunci funcţia returnează 1. n = 0 fact (n) =  n * fact (n − 1). cin >> n. int main(){ int n. } 4 4!=24 //conditia de oprire //apel recursiv: n!=n(n-1)! La orice funcţie recursivă trebuie precizată o condiţie de ieşire. ceea ce duce la primul apel recursiv (2) calculeaza 2*fact(1) – apel recursiv (3) calculeaza 1*fact(0) – apel recursiv (4) returneaza 1 – revenire din fact(0) (5) returneaza 1 – revenire din fact(1) (6) returneaza 2 – revenire din fact(2) (7) returneaza 6 – revenire din fact(3) . Dacă parametrul primit de fact este 0. condiţia de ieşire este 0! care. n > 0 Trecerea la următorul program este naturala: #include <iostream> using namespace std. cout << n << "!=" << fact(n). } long fact(int n){ if(n==0) return 1. este 1. prin definiţie.

. return n*fact(n-1). return 2*fact(1). } vf 1 2 3 n n n long fact(0){ if(0==0) return 1. return 1*fact(0).Introducere in ANSI C++ Figura 10. } vf 3 n Iesirea in recursivitate long fact(2){ if(2==0) return 1.1 P2.1 ilustreaza succesiune de apeluri recursive: long fact(3){ if(3==0) return 1.151 - . } vf 0 1 2 3 n n n n Figura 10. return 3*fact(2). } Intrarea in recursivitate vf 2 3 n n long fact(1){ if(1==0) return 1. Realizati o functie recursiva care calculeaza 2n.

int main(){ int n. } long fibo(int n){ nr_apeluri++. Cate apeluri recursive au avut loc? #include <iostream> using namespace std. apeluri:15 . apeluri:" << nr_apeluri.Introducere in ANSI C++ #include <iostream> using namespace std. Calculati fibo(n) intr-o functie recursiva (cel de-al n-lea termen din sirul lui Fibonacci). cout << "Nr. if(n<=2) return 1. cout << "2^"<< n << "=" << doila(n). long fibo(int). return fibo(n-1)+fibo(n-2).152 - . return 2*doila(n-1). nr_apeluri=0. // retinem numarul de apeluri ale functiei int main(){ int n. } 3 2^3=8 P3. int nr_apeluri. } long doila(int n){ if(n==0) return 1. long doila(int). cin >> n. cout << "fibo("<< n << ")=" << fibo(n) << endl. cin >> n. } 6 fibo(6)=8 Nr.

c=getchar(). } void invers(){ char c. cout << c. Urmatoarea aplicatie va folosi faptul ca variabilele locale sunt alocate pe stiva. if (c!='\n') invers(). int main(){ invers(). numar care creste exponential. void invers(). Inversarea unui text citit de la tastatura folosind o functie recursiva. #include <iostream> using namespace std. face ca aceasta implementare sa nu fie practica.153 - . P4. } abcd dcba .Introducere in ANSI C++ Folosirea variabilei globale a permis contorizarea simpla a intrarilor in functia recursiva. iar prin adaugarea de valori apoi scoaterea lor din stiva. Numarul mare de apeluri recursive. acestea isi inverseaza ordinea.

} int g(int x. y  . int main(){ cout << f(5. numim acest tip de apel recursivitate indirecta.20).154 - . P5.y-1). pentru x y g x . y = unde x .int y){ if (x>=y) return x.2 Recursivitatea indirecta In cazul in care apelul recursiv se face prin intermediul unei alte functii. int f(int. else return 2*f(0. pentru x≥y g  x .int).y).Introducere in ANSI C++ 10. pentru xy≥5 2∗ f 0.int). y = xy−5. } 19 . y−1 . } int f(int x. int g(int. Calculati: f  x .int y){ if ((x+y)>=5) return x+y-5. else return g(x. pentru x y5 #include <iostream> using namespace std.

Pp4.. Afisati f(n) si g(n). Fie n numar natural citit de la tastatura. Pp3. Realizati o functie recursiva care calculeaza cmmdc-ul elementelor din vector. definit ca: A[n]=3*A[n-1]+2*A[n-2].155 - .3 Probleme propuse Pp1.. g(1)=1 g(n+2)=5*f(n)-g(n) f(n+1)=g(n+1)-f(n-1) . Fie un vector de numere intregi pozitive definit global....Introducere in ANSI C++ 10. Scrieti functii recursive pentru a afisa urmatoare piramida de numere: 1 12 12 3 .. Realizati o functie recursiva pentru a afisa primii n termeni ai sirului A.. Pp6. Functie recursiva care afiseaza cifrele unui numar... pentru n>=2 A[0]=A[1]=1 Pp2. Pp5. pentru f si g definite: f(0)=f(1)=1 g(0)=2. Functie recursiva care descompune un numar in factori primi.

Vom avea ceva de forma: stdin 35 9 12 stdout Algoritm Suma: 29 Figura 11. "r". respectiv de a scrie datele de iesire in altul. iesirea standard va fi nume_fisier. stdin Algoritm stdout Figura 11.2 Functia care permite redirectarea stdin si stdout este freopen. "w".Introducere in ANSI C++ Capitolul 11 – Fisiere Pana acum am citit datele de intrare de la tastatura. Dupa executarea functiei. Pentru redirectarea iesirii avem: freopen(nume_fisier. Pentru redirectarea intrarii avem: freopen(nume_fisier.stdout). vor accesa de fapt fisierele care au devenit intrari si iesiri standard.1 Redirectarea intrarii/iesirii Probabil cea mai simpla posibilitate de a citi date dintr-un fisier. cin si cout. Tastatura si ecranul reprezinta dispozitivele standard de intrare.stdin). intrarea standard va fi nume_fisier. iar cele de iesire au fost afisate pe ecran. respectiv iesire. . Dupa executarea functiei.1 11. este modificare intrarii si iesirii standard.156 - . In acest caz.

} intrare. cout << "Dati fisierul de intrare:". Fisierul "intrare. freopen("iesire. Afisati pe ecran suma lor. Se citeste de la tastatura numele unui fisier care contine 10 numere intregi.txt" suma acestor doua numere.p02 55 .txt"."r".txt" contine numere 2 numere intregi."r". } Dati fisierul de intrare:intrare.b.txt: 7 P2. } cout << S.stdout). S += x. cin >> a >> b.txt: 2 5 iesire.Introducere in ANSI C++ P1. int main(){ int a.157 - .stdin). #include <iostream> using namespace std.i<=10.i++){ cin >> x. for(i=1."w". cin >> FileName.S. int main(){ int x.txt". #include <iostream> using namespace std.stdin). Scrieti in fisierul "iesire. char FileName[20].i. cout << a+b. freopen("intrare. freopen(FileName. S=0.

158 - . inclusiv spatii. tab). fisierul este deschis si este pozitionat la inceput. enter. folosind operatorii >> si <<: flux_intrare >> variabila.Introducere in ANSI C++ 11. Daca nu. In acest moment.2 Fluxuri de intrare/iesire C++ pune la dispozitie fluxurile fisier ifstream (pentru date de intrare) si ofstream (iesire). Accesul la fluxuri de va face analog lucrului cu cin si cout. Mai sus sir va fi sirul de caractere in care va fi realizata citirea.getline(sir. iar nr reprezinta numarul maxim de caractere care va fi citit. fiserul este deschis si eventualele date existente sunt sterse. .open(nume_fisier). iar caracterele albe dintre doua variabile consecutive citite vor fi ignorate. sau: ifstream flux_intrare(nume_fisier). la nu moment dat sa schimbat fiserul asociat cu o anumita variabila flux. acel fisier va fi deschis in mod automat si va fi accesibil prin intermediul variabilei flux_iesire sau flux_intrare. flux_iesire << expresie. Declaratiilor vor fi de forma: ifstream flux_intrare. sau daca dorim. sau: ofstream flux_iesire(nume_fisier). In cazul in care se specifica un nume de fisier. folosim apeluri de forma: flux. Citirea unei variabile va fi incheiata la intalnirea unui caracter alb (spatiu. vom folosi: flux_intrare. daca fluxul este de intrare. ifstream si ofstream sunt clase definite in biblioteca fstream si permit declararea unor variabile care vor fi asociate cu fisierele cu care dorim sa lucram. Daca dorim citirea unui sir de caractere. nr). respectiv: ofstream flux_iesire. iar daca este de iesire.

prenume[20]. for(i=1.txt" suma acestor doua numere. char nume[20]. #include <fstream> #include <iostream> using namespace std. int main(){ int a.Introducere in ANSI C++ P3.i<=5.i++){ f >> nume >> prenume. ifstream fin("intrare. ifstream f("intrare. } } intrare.txt").txt").p04" contine 5 nume de persoane. fout << a+b.p04").b. Scrieti in fisierul "iesire. int main(){ int i.txt" contine numere 2 numere intregi. Afisati pe ecran persoanele care au numele de patru caractere.p04: Voinea Mircea  Tica Silviu  Toth Haralambie  Ion Ion  Gheorghe Gheorghe ecran: Tica Silviu .159 - . dar rezolvare cu fluxuri) #include <fstream> using namespace std.txt: 7 P4. Fisierul "intrare. ofstream fout("iesire. date pe cate un rand sub forma nume prenume. } intrare.txt: 2 5 iesire. if (strlen(nume)==4) cout << nume << " " << prenume << endl. fin >> a >> b. (identic cu P1. Fisierul "intrare.

ofstream fout("iesire. int main(){ int i.x. cate 5 pe un rand. foloseste(X).p05 1 2 3 4 1  2 3 4  . for(i=1. } } numere. fout << x << " ".i++){ fin >> x.3 Citirea unui numar cunoscut de valori dintr-un fisier La multe probleme.i<=n. fin >> n. enuntul va da ca fiserul de intrare un fisier in care. for(i=1. if (i%5==0) fout << endl.i++){ flux_intrare >> X. avem urmatoarea abordare: flux_intrare >> Nr_valori. #include <fstream> using namespace std. ifstream fin("numere. } P5.p05" contine. In acest caz. Scrieti numere in alt fisier.p05").i<=Nr_valori.160 - . pe primul rand un numar intreg n.Introducere in ANSI C++ Toth Haralambie 11.p05").n. in ordine crescatoare.p05 8 1 2 3 4 1 2 3 4 iesire. n numere reale. Fisierul "numere. ca prima valoare se va da numarul de valori care vor fi citite ulterior din fisier. iar pe urmatorul separat de cate un spatiu.

Afisati pe ecran matricea.txt 3 1 2 3 4 5 6 7 8 9 ecran 1 2 3 4 5 6 7 8 9 11.j++) cout << a[i][j] << " ". .i<n.i++) for(j=0. cout << endl. } } matrice. for(i=0.n. iar pe urmatorele n randuri cate n numere intregi care vor forma informatii dintr-o matrice scrisa pe linii.161 - . f >> n. int main(){ int i.j++) f >> a[i][j].Introducere in ANSI C++ P6.j<n. for(i=0.i<n.txt" contine. returneaza NULL.j<n.a[10][10].x. Fisierul "matrice. Folosindu-ne de aceasta vom avea: while (flux_intrare >> X) foloseste(X). ifstream f("matrice. pe primul rand un numar intreg n.4 Citirea pana la sfarsitul fisierului Daca fluxul a ajuns la sfarsit sau daca a avut loc o eroare la citirea unei valori din flux.i++){ for(j=0. atunci o instructiunea flux_intrare >> var.j. #include <fstream> #include <iostream> using namespace std.txt").

txt").getline(linie. Scrieti in fisierul "frecv. } P7. Se citeste numele unui fisier text de la tastatura. . } } P8.Introducere in ANSI C++ O alta varianta implica testarea sfarsitului de fisier folosint functia: flux_intrare. int main(){ ifstream f. Fie fisierul "intrare.250).eof() Aceasta functie va returna true daca s-a ajuns la sfarsitul fluxului si false in caz contrar.eof()){ f. foloseste(X). Realizati o copie a acestuia in fiserul "copie.linie[250]. char FileName[20]. cin >> FileName. f. g << linie << endl.txt". #include <fstream> #include <iostream> using namespace std.eof()){ flux_intrare >> X.open(FileName). while(!f.p08". cout << "Dati numele fisierului:".162 - . Vom avea: while (!flux_intrare. ofstream g("copie.p08" caracterele care apar in fiserul de intrare si de cate ori apar ele.

for(i=0.eof()){ f.i++) ct[S[i]]++.p08").i<256.i<256.p08"). ofstream g("frecv.p08   2 a 3 b 3 c 3 d 2 e 2 f 10 .i.getline(S.p08 abc abc abc dede ffffffffff frecv.i++) ct[i]=0.i++) if (ct[i]) g << char(i) << " " << ct[i] << endl. while(!f. int ct[256].100).Introducere in ANSI C++ #include <fstream> using namespace std. char S[100].163 - . } for(i=0. for(i=0. } intrare. int main(){ ifstream f("intrare.S[i].

Pp5. Pp2. apoi afisati literele mici din ext. Cititi o matrice dintr-un fisier. scriind rezultatul in alt fisier.164 - . ‘. Inversati liniile unui fisier text al carui nume este citit de la tastatura. . Pp3.’. Numarati cuvintele dintr-un fiser text. in ordine crescatoare dupa frecvente. Scrieti numerele pare intr-un fiser si cele impare in altul.’ si ‘. Un fisier contine nu text in limba engleza. Contorizati literele mici care apar in text. Pp6. Un fisier contine numere intregi. Verificati daca n fisiere citite de la tastatura sunt identice ca si continut. Pp4. Separatorii dintre cuvinte sunt Enter.Introducere in ANSI C++ 11.5 Probleme propuse Pp1. Scrieti inversa matricii in alt fisier.

&variabila = "adresa la vare este memorata variabila" In cazul in care avem o constructie de forma &variabila. daca apare in context de declaratie valoarea care se gaseste la adresa indicata de un pointer. tip definit de utilizator. se foloseste operatorul de redirectare *. 12. daca este o instructiune (nu o declaratie) Pentru a putea lucra direct cu adresele de memorie declaram pointeri: tip *pointer1. acesta poate insemna: – – o referinta..).. in context de instructiune Prin simpla declaratie a unui pointer. valoarea acestuia nu este initializata. etc. pointerul indicand o zona de memorie oarecare. unde tip este un tip de data oarecare (int. Semnul * poate sa insemne: – – declaratie de pointer. daca apare in context de declaratie de variabila adresa unei variabile. acesteia i se asociaza o locatie de memorie.. Un pointer este o variabila care contine o adresa de memorie. Pentru a utiliza valoarea care este memorata intr-o locatie indicata de un pointer. float.1 Declaratie si operatii elementare La declararea unei variabile. . .165 - . pointern. Determinarea adresei la care se gaseste o variabila se face folosind operatorul &. *pointer2.Introducere in ANSI C++ Capitolul 12 – Pointeri Accesul la o locatie de memorie folosita de program este realizata printr-o adresa unica. iar folosirea acestuia inainte de initializare poate avea rezultate dezastruoase (nu poate folosi nimanui modificarea unei zone oarecare de memorie!). Acest tip de pointer se numeste pointer liber.

cout << &p << " " << &q << endl. // declararea variabilelor intregi a si b int &copie_a = a.   P1. // copie_a este un alias al lui a int *p.b=2. // declararea pointerilor la intregi p si q cout << p << endl.Introducere in ANSI C++ In cazul in care dorim sa specificam ca un pointer nu indica o adresa valida vom folosi constanta NULL. } 0x8048906 0xbff9eefc 0xbff9eef8 0xbff9ef04 0xbff9ef04   0xbff9ef00 0xbff9ef00 11 11   3 3 La rulari succesive adresele afisate pot sa difere. sau. . echivalent: Observam ca pointerii liberi vor aparea ca pointeri valizi! Exista posibilitatea de a initializa un pointer la declarare.166 - . int *q=&var.. p=NULL. ++(*q). Operatii elementare cu pointeri #include <iostream> using namespace std. int main(){ int a=1.*q.// afisarea unui pointer liber!!! p=&a... cu NULL sau cu adresa unei variabile anterior declarate: int *p=NULL.. // p contine adresa lui a // a=a+10 // q contine adresa lui b // ++b. q=&b. if (p) . *p=*p+10. cout << a << " " << *p << " " << b << " " << *q. cout << &a << " " << p << " " << &b << " " << q<< endl. // initializarea pointerului nul Conditia de testarea daca un pointer este valid va fi: if (p!=NULL) .

. Figura 12... 2... Dupa atribuiri: q . Dupa declaratii: q ? 0xbff9eef8 p 0x8048906 0xbff9eefc b 2 0xbff9ef00 copie_a a 1 0xbff9ef04 . contin valori etc. Desi pointerii se comporta similar unor variabile obisnuite (au o adresa asociata in memorie. a si copie_a sunt de fapt una si aceeasi variabila..2 In acest moment.3 Incercarea de a asocia pointeri de un anumit tip cu adresele unor variabile de tipuri diferite va duce la erori de compilare.1 Observam ca p indica o adresa oarecare din memorie.).. pentru a creste claritatea. .. in urmatoarele figuri in care vor mai aparea pointeri. acestia vor fi desenati ca in Figura 12. ...167 - .Introducere in ANSI C++ Starea memoriei in cazul problemei P1 poate fi urmatoarea: 1. Figura 12.. 0xbff9ef00 0xbff9eef8 p 0xbff9ef04 0xbff9eefc b 3 0xbff9ef00 copie_a a 11 0xbff9ef04 . q p Figura 12. b . 3 copie_a a 11 . modificarea locatiilor de memorie indicate ducand la modificarea valorii variabilelor a si b.. pointerii p si q vor avea valori valide. variabilele a si b sunt initializate.3.

p=&a.cpp: In function ‘int main()’: p02. La prima vedere. // // } p=&b. ceea ce va duce la urmatoarea problema: dereferentierea nu va putea fi facuta direct. // aceste atribuiri nu sunt valide // intreg si pointer la int // intreg si pointer la double In cazul in care vom scoate comentariile. P3.*p. q=&b. Tipul indicat de un pointer #include <iostream> using namespace std. in combinatie cu operatorul de conversie explicita de tip (cast).Introducere in ANSI C++ P2. Pointerii void si modul lor de utilizare . q=&a.cpp:13: error: cannot convert ‘double*’ to ‘int*’ in assignment p02. ultimelPointeri void si utilizarea lore doua atribuiri vor da urmatoarele erori: p02.cpp:14: error: cannot convert ‘int*’ to ‘double*’ in assignment O categorie aparte de pointeri sunt pointerii void: void *pointer. acest tip de pointer pare sa aiba un grad de utilizare redus. ofera o flexibilitate crescuta aplicatiilor noastre. int main(){ int a. fiind obligatoriei folosirea operatorului cast pentru a specifica tipul indicat in acel moment de pointerul void. Cu toate acestea.*q. double b.168 - . Acest tip de pointer va putea indica zone de memorie de dimensiune variabila (dimensiune data in cazul altor pointeri de tipul de data indicat).

p=&d. int main(){ int i=1. char c='a'. } 1 12. in cazul nostru int: (int *)p Pentru a accesa zona de memorie vom dereferentia pointerul de mai sus: *(int *)p sau *((int *)p) La sfarsit.Introducere in ANSI C++ #include <iostream> using namespace std. (*(double *)p) = (*(double *)p)*3. void *p. cout << i << " " << d << " " << c << endl. cout << i << " " << d << " " << c.02 b Vom explica mai departe urmatoarea expresie: (*(int *)p)++. p=&i.34. . aplicam operatorul de incrementare. (*(int *)p)++. urmatoarea aplicatiei ilustrand un astefel de caz.34 a 2 37. deci ca prim pas trebuie sa specificam tipul spre care pointeaza.169 - . double d=12. (*(char *)p) = 'b' . Pointerul p este de tip void. p=&c. efectul fiind incrementarea intregului indicat de pointerul p: (*(int *)p)++ O situatie aparte o reprezinta pointerii la pointeri.

q=&p. int **q. p=&i. . #include <iostream> using namespace std. Pointeri la pointeri. p2. In C++ exista o serie de alte operatii specifice lucrului cu variabile de tip pointer.1 Atribuirea Operatorul = se comporta analog atribuirii dintre doua variabile oarecare. int main(){ int i=123. ..4.170 - .. int ***t. t=&q. O Expresie de forma: p1 = p2 = .Introducere in ANSI C++ P4. } 123 123 // pointer la int // pointer la pinter la int // pointer la pointer la pointer la int :) Situatia din problema anterioara este descrisa in Figura 12.4 12. int *p.2. .2 Aritmetica pointerilor In subcapitolul anterior am folosit operatori de referentiere/dereferentiere pentru a lucra cu pointeri. = pn va face ca pointerii p1. cout << i << " " <<***t. t q p i 123 Figura 12. 12. pn sa indice toti locatia de memorie indicata initial de pn...

P6. acestia putand retine valoarea oricaror pointeri. >= pot fi folositi cu operanzi pointeri. < . p1=p2=p3. double *p4.2. !=.2 Operatorii relationali Operatorii ==.. // // atribuire corecta // eroare la compilare (pointerii nu au acelasi tip) cout << i << " " << *p1 << " " << *p2 << " ". cout << *p3 << " " << *((int *)pv).5 Pointerii care apar in expresia de atribuire trebuie sa fie de acelasi tip. >. iar ultimii verifica daca un pointer indica o locatie de memorie mai mica sau mai mare fata de alt pointer.*p3. } 123 123 123 123 123 12. O situatie aparte apare in cazul in care utilizam pointeri void. In general expresii relationale apar intre pointeri care indica acelasi obiect in memorie (vezi 12. Atribuirea pointerilor #include <iostream> using namespace std. Primii doi operatori verifica daca doi pointeri indica sau nu aceeasi locatie de memorie.5). void *pv. Afisati locatia cea mai mica si locatia cea mai mare de memorie alocate in .. int main(){ int i=123... int *p1. p3=&i. pn Figura 12. p4=p1. indiferent de tipul lor de baza.*p2. pn p1 p2 123 . pv=p1.171 - . <=. P5.Introducere in ANSI C++ 123 ? ? p1 p2 .

p=&q. q=&b. // comparatie dintre un pointer si o referentiere p=&pmare. pmare=(p>pmare)?p:pmare. if (pmic<q) pmic=q. cout << &a << " "<< &b << " "<< &q << " ". pmic=(p<pmic)?p:pmic. #include <iostream> using namespace std.172 - – . pmare=(&pmic>pmare)?&pmic:pmare. adresa cea mai mica este data de pointerul in care retinem adresa cea mai mare :) . p indica p !!! // // pmic=(&pmic<pmic)?p:pmic. pmic=(p<pmic)?p:pmic. comparatie dintre pointeri de acelasi tip p=&p. pmare=(p>pmare)?p:pmare. int *q. int b. // if (p>0x10000). pmare=(p>pmare)?p:pmare. pointer si un intreg (eroare) } 0xbff6f618 0xbff6f614 0xbff6f610 0xbff6f60c 0xbff6f608 0xbff6f604 0xbff6f604 0xbff6f614 // comparatie dintre un Observatii: – in program am alocat variabile de 4 tipuri diferite. int main(){ double a. void *p. cout << pmic << " " << pmare. deci e obligatorie folosirea pointerilor void pointerii sunt alocati in memorie ca orice alta variabila. *pmare. *pmic. pmic=pmare=&a. cout << &p << " "<< &pmic << " "<< &pmare << endl.Introducere in ANSI C++ program. pmic=(p<pmic)?p:pmic. de tipuri diferite // comparatie dintre doi pointer if (pmare>=q) pmare=q.

  // p indica locatia de memorie anterioara de tipul dat p = p + i.Introducere in ANSI C++ – putem compara direct un pointer si adresa unei variabile oarecare 12.b. // q indica la stanga lui p cu i pozitii  Practic. cout << p << " " << q << endl. int main(){ int a.173 - . // p indica urmatoarea locatie de memorie de tipul dat p­­. q=q+10. p++. int *p=&a. } 0xbfcb90ac 0xbfcb90a8 0xbfcb90b0 0xbfcb90d0 0xbfcb90ac 0xbfcb90a8 . p++ . q-=10. // p "sare" spre dreapta in memorie cu i pozitii  q = p ­ i. in functie de tipul de baza al pointerului. valoarea efectiva cu care se modifica pointerul la aceste operatii este un multiplu de sizeof(tip). cout << p << " " << q << endl. Acest tip de operatii nu vor putea avea ca operanzi pointeri void.3 Scaderea si adunarea cu un intreg Operatiile de scadere si de adunare dintre un pointer vor "deplasa" pointerul in memorie inapoi sau inainte fata de pozitia initiala.2. P7. Adunarea si scaderea dintre un pointer si un intreg #include <iostream> using namespace std. Este permisa folosirea formelor scurte de atribuire += si ­=. --p. tip *p.*q=&b. cout << p << " " << q << endl.

12.2. In situatiile in care cantitatea de memorie necesara alocarii datelor cu care lucram nu este cunoscuta decat in timpul rularii se folosesc functii de alocare/dealocare dinamica a memoriei. C++ ofera operatorii new si delete pentru a aloca dinamic memoria. new tip .3 Alocarea dinamica a memoriei Pana in acest moment. } else  trateaza eroarea la alocare .4 Diferenta a doi pointeri Daca p si q sunt doi pointeri cu acelasi tip de baza (diferit de void) operatia: p­q returneaza un intreg si va da numarul de obiecte de tipul indicat de p si q care se gasesc intre cei doi pointeri (vezi 12. in ambele cazuri cunoscandu-se exact cantitatea de memorie necesara. Variabilele globale sunt alocate in momentul compilarii si cele locale sunt alocate pe stiva la rulare.aloca o zona de memorie de dimensiune sizeof(tip) si returneaza un pointer la zona alocata. 12.5 pentru exemple). respectiv NULL daca nu s-a putut realiza alocarea dealoca o zona de memorie indicata de un pointer. alocarea dinamica trebuie facuta intr-o constructie de forma: if (p=new tip){ foloseste p delete p.174 - .5. toate programele noastre au folosit variabile alocate static. de dimensiunea tipului de baza a pointerului p delete p  - In general.Introducere in ANSI C++ Pentru exemple utile vezi 12.

se pot folosi urmatoarele forme ale operatorilor new si delete (vezi 12.Introducere in ANSI C++ P8.175 - . } 2 3 2+3=5 Pentru a aloca/dealoca mai multe obiecte de acelasi tip.4 Pointeri la structuri O situatie relativ speciala este cazul in care tipul de baza al unui pointer este o structura. In acest caz este introdus operatorul ­>. if ((p= new int) && (q= new int)){ cin >> *p >> *q. delete q. Folosirea pointerilor la structuri. } else cout << "Eroare la alocare!". urmatoarele doua notatii fiind echivalente pentru p un pointer la o structura: (*p).membru p­>membru P9. cout << *p << "+" << *q << "=" << *p+*q.5 pentru exemple): p = new tip[nr] - aloca o zona de memorie de dimensiune sizeof(tip)*nr si returneaza un pointer la zona alocata. Alocarea dinamica a memoriei #include <iostream> using namespace std. int main(){ int *p. .*q.dealoca zona de memorie alocata anterior delete [] p  12. delete p. respectiv NULL daca nu s-a putut realiza alocarea .

? A ? ? ? 10 intregi ? .im=-1. }.6 A fiind un pointer. in cazul declaratiei: int A[10]. } z= 2 ­1*i 12.Introducere in ANSI C++ #include <iostream> using namespace std.im.5 Legatura dintre pointeri si tablouri 12. cout << p->im << "*i". A este un pointer la primul intreg din vector. cout << "z= " << (*p).7: .176 - .*p.5. ? Figura 12. int main(){ complex z. notatiile A[0] si *A fiind echivalente.. Deci. z. accesul la elementele tabloului va putea fi realizat intr-o varietate de forme..6 ilustreaza o situatie posibila in memorie in cazul declaratiei anterioare. struct complex{ float re. Folosind aritmetica pointerilor si faptul ca A este pointer la primul element. *A va reprezenta valoarea primului element.1 Accesul la elementele unui tablou folosind pointeri In C si in C++ numele unui tablou este un pointer constant la primul element al tabloului.re << char((p->im<0)?' ':'+'). p=&z. Figura 12. Faptul ca A este un pointer constant implica faptul ca acesta nu va putea fi modificat in program. ca in Figura 12. z.re=2.

Impementati functiile de initializare random. P11. de citire si de afisare a vectorilor fara a folosi notatia indexata. cout << "A:" << *A << " " << A[1] << " ".14. de lungime n. ? Figura 12. } A:11 12 13 14 15 16  Parcurgerea unui tablou A. p=A+5. for(p=A.13.15.12.p­A<n. cout << *(A+2) << " " << *(3+A) << " ". O alta variantaimplica pozitionarea unui pointer pe pozitia imediat urmatoare ultimului element din tablou si folosirea acestui pointer la verificarea sfarsitului de vector: sf=A+n.177 - .p++) foloseste(*p). Diferite modalitati de acces la elementele unui tablou #include <iostream> using namespace std. int *p. cout << 4[A] << " " << *p << " ".. // sau sf=&A[n]. se poate face fara a folosi notatia indexata folosind urmatoarea schema generala: for(p=A. int main(){ int A[10]={11.7 P10.Introducere in ANSI C++ ? *A ? A[1] ? *(A+2) ? 10 intregi ? *(3+A) 4[A] .p++) foloseste(*p).p<sf.16}. ..

m). } n=3 10 20 30 3 6 7 5 3 10 20 30 .n.p++) *p=rand()%10.m. int main(){ int A[10]. void init(int []. int &). cout << "n=".p++) cin >> *p. int B[10].Introducere in ANSI C++ #include <iostream> using namespace std.i++) cout << *(A+i) << " ".n).n). void afiseaza(int []. } void init(int A[]. cout << endl. int &n){ int *p. afiseaza(B. citeste(B. } void afiseaza(int A[]. int n){ int i. *sf.p-A<n.p<sf.178 - . int). for(p=A. } void citeste(int A[].i<n.m). afiseaza(A. void citeste(int []. n=5. cin >> n. for(i=0. int n){ int *p. sf=A+n. int). init(A. for(p=A.

foloseste(A. folosim urmatoarea schema generala.2 Alocarea dinamica a tablourilor Pnetru a aloca un vector abia dupa ce cunoastem numarul exact de elemente. A= new tip[n]. Accesul la elementele vectorului poate fi facut indexat sau folosind pointeri. A fiind un pointer la tip: cin >> n.179 - .5. delete []A. Fie un vector alocati dinamic si initializat cu valorile 0 si 1.n). . Mutati valorile de 0 la inceput si cele de 1 la sfarsitul vectorului.Introducere in ANSI C++ 12. P12.

int). *dr. int main(){ int *A. for(i=0. afiseaza(A. int n){ int i.180 - . } void rezolva(int A[]. int &). dr=A+n-1.i<n. cin >> n. cout << "n=". delete []A. init(A.i<n.n). *dr=1.} } } void afiseaza(int A[]. } void init(int A[]. void init(int []. void afiseaza(int []. } n=10 1 0 1 1 1 1 0 0 1 1 0 0 0 1 1 1 1 1 1 1 .n). int &n){ int *st.n). cout << endl.n).n. void rezolva(int []. A=new int[n]. while ((st<dr)&&(*dr==1)) dr--. int).Introducere in ANSI C++ #include <iostream> using namespace std. int n){ int i.i++) A[i]=rand()%2.i++) cout << A[i] << " ". for(i=0. afiseaza(A. st=A. while(st<dr){ while ((st<dr)&&(*st==0)) st++. if (st<dr){*st=0. rezolva(A.

. A[0] va fi un pointer la primul element al vectorului ce reprezinta prima linie a matricii. . A[0][2] A[1][2] .Introducere in ANSI C++ 12. A[0][1] A[1][1] .... Analog.. Vector[n­1] vor fi pointeri spre tip. A[9] A[9][0] A[9][1] A[9][2] .. A[0][9] A[1][9] .. Vector[1].. Fie urmatoarea declaratie de matrice: int A[10][10].8 P13.... . unde N este o constanta de tip intreg. A[i] este un pointer spre linia i a matricii. In acest caz.. Sortati crescator fiecare linie a matricii.3 Vectori de pointeri Declararea unui vector de pointeri se face similar declaratiei unui vector de un tip oarecare: tip *Vector[N]. . A[0] A[1] A[0][0] A[1][0] . Fie o matrice patratica de intregi initializata random.5. Vector[0].. Pe exemplul dat... A[9][9] Figura 12..181 - ..

n). } int init(int A[10][10]. int &).i++) sort(A[i]. } } 3 6 7 5 3 5 6 2 9 1 2 7 0 9 3 6 3 5 6 7 2 3 5 6 1 2 7 9 0 3 6 9 .i<n.i. afis(A. } } int sort(int A[]. for(j=0. init(A. int afis(int [][10]. int &n){ int i. A[j]=t.j++) if (A[i]>A[j]){ t=A[i].i++) for(j=0.i<n. A[i]=A[j].j. for(i=0.Introducere in ANSI C++ #include <iostream> using namespace std. n=4.t. for(i=0.n).i<n-1. for(i=0. cout << endl. int).n.j. int n){ int i. for(i=0.i<n. int sort(int [].j<n.182 - . int). int init(int [10][10].j<n.j++) cout << A[i][j] << " ".j<n.i++){ cout << endl. afis(A. } int afis(int A[][10].n).j. int main(){ int A[10][10]. int n){ int i.j++) A[i][j]=rand()%10.i++) for(j=i+1.n).

char t[10]. "duminica"}. } luni marti miercuri joi vineri sambata duminica duminica joi luni marti miercuri sambata vineri . "miercuri". char *s2){ char t[10]. char *). Afisati zilele in ordine lexicografica.i++) cout << Zi[i] << " ". void sort(char [7][10]).i<7. cout << endl. Fie o matrice de caractere initializata cu zilele saptamanii. } void afis(char Zi[7][10]){ for(int i=0.s1). afis(Zi). strcpy(t. "sambata". strcpy(s1.i++) for(j=i+1. } void sort(char Zi[7][10]){ int i. "joi".j++) if (strcmp(Zi[i]. "vineri".Zi[j])>0) inter(Zi[i].Introducere in ANSI C++ Un caz in care folosirea vectorilor de pointeri se dovedeste utila este cazul in care lucram cu matrici de caractere. strcpy(s2. } void inter(char *s1.t). #include <iostream> #include <string> using namespace std.j. for(i=0. int main(){ char Zi[7][10]={"luni". sort(Zi).i<6. void afis(char [7][10]).j<7. Zi[j]).s2). afis(Zi). "marti".183 - . void inter(char *. P14.

. 12. tip*.Introducere in ANSI C++ 12... parametrul efectiv corespunzator parametrului formal pointer trebuie sa fie un pointer care acelasi tip de baza.. folosind parametri pointeri... tip &p.6 Legatura dintre pointeri si functii In C/C++ avem posibilitatea de a transmite parametri de tip pointer unei functii...6. de a returna pointeri din functie si de a defini un pointer la o functie.... . in cazul in care dorim modificarea unor parametri in cadrul unei functii va conduce la un rezultat similar.. } si tip_returnat nume_functie(. mai putin situatia in care tip este void. } In cazul in care se doreste modificare pointerului (nu a valorii indicate de catre acesta) se va folosi o referinta la pointer: tip_returnat nume_functie(.  Parametrul pointer se comporta ca orice alt tip de parametru. dar in general utilizarea pointerului in cadrul functiei se va face in varianta dereferentiata.184 - . ... . El va fi alocat pe stiva (e variabila locala). tip *p. tip*&. P15..). La apel.){ foloseste(p).). Acesta ultima facilitate va permite apelul functiei folosind pointerul si ofera posibilitatea de a transmite parametri de tip functie. .){ foloseste(*p).. Folosirea pointerilor sau a referintelor.1 Functii cu parametri pointeri Prototipul unei functii care are ca parametri pointeri este de forma: tip_returnat nume_functie(..... Functie care realizeaza interschimarea a doua variabile de tip intreg. . Urmatoarele doua definitii de functii sunt echivalente: tip_returnat nume_functie(.

t=a. a=b. } 1 2 2 1 Daca nu am fi folosit referinte la pointeri interschimarea ar fi avut loc doar in .Introducere in ANSI C++ #include <iostream> using namespace std. cout << x << " " << y << endl. inter(p.q). b=t. } void inter(int *&a. } 1 2 2 1 Observam ca apelul trebuie facut cu adresele variabilelor de interschimbat! P16. *q=&y.185 - . *a=*b. void inter(int *. int *b){ int t. int main(){ int x=1. void inter(int *&. Functie care interschimba doi pointeri la int. #include <iostream> using namespace std.y=2. inter(&x. cout << *p << " " << *q << endl. t=*a.y=2. int *p=&x. int *&b){ int *t. int *). int main(){ int x=1. cout << x << " " << y << endl. int *&). *b=t. } void inter(int *a.&y). cout << *p << " " << *q << endl.

} 1 2 2 1 Un caz de transmitere de pointer a fost discutat anterior.186 - . *b=t.y=2. in 9. *a=*b. Realizati o functie care. void inter(int **. *q=&y. deci tranmiterea acestui nume este un caz particular e tranmitere de parametru pointer. #include <iostream> using namespace std. primind ca parametri doi vectori alocati static si lungimile acestora.&q). P17. Am stabilit ca numele unui vector este un pointer la primul sau element. t=*a. realizeaza interschimbarea lor (ca si continut). Urmatoarea varianta este echivalenta. int main(){ int x=1. . cout << *p << " " << *q << endl.10. } void inter(int **a. int *p=&x. P18. int **b){ int *t. int **).Introducere in ANSI C++ cadrul functiei. Functie care interschimba doi pointeri la int (varianta 2). cout << *p << " " << *q << endl. inter(&p.

30}.i++) A[i]=B[i].T.*m). void inter(int []. int &n.Introducere in ANSI C++ #include <iostream> using namespace std. afis(B.187 - . afis(A. int n){ for(int i=0. int m){ n=m.n.m).B. void afis(int []. B[10]={10.n. cout << "B:".n).2.B. int &.20. } A:1 2 3 4 B:10 20 30 A:10 20 30 B:1 2 3 4 In problema anterioara. } void inter(int A[].4}.l. P19.m).A. simpla interschimbare a pointerilor reprezentand numele vectorilor este imposibila.*m. afis(B. int &n. . realizeaza interschimbarea lor (ca si continut). cout << "B:". Realizati o functie care.i<n. int main(){ int A[10]={1.l. acestia fiind pointeri constanti. int []. copiaza(B. void copiaza(int []. cout << endl. int *). inter(A. int &. } void copiaza(int A[]. cout << "A:". copiaza(A. int). copiaza(T.n). int B[].3.n=4. int B[].l). int *m){ int T[100]. for(int i=0. int ).&m).n). primind ca parametri doi vectori alocati dinamic si lungimile acestora. afis(A. int [].i<n. } void afis(int A[].m=3. cout << "A:".i++) cout << A[i] << " ".

simpla interschimbare a pointerilor reprezentand vectorii si a lungimii acestora fiind suficienta. int *&.m=3. int &m){ int *T. for(int i=0. T=A. int *&B.B.6. . t=n. n=m. m=t. afis(B. int &. cout << endl. void inter(int *&.t.188 - .m). cout << "B:".m). afis(A.i++) cout << A[i] << " ". int &n. inter(A.n).i<n. int main(){ int *A=new int[4]. } void inter(int *&A.Introducere in ANSI C++ #include <iostream> using namespace std. void afis(int []. nefiind necesare mutarea in memorie a elementelor tablourilor. int ). for(int i=0. A=B. } A:1 2 3 4 B:10 20 30 A:10 20 30 B:1 2 3 4 In acest caz inteschimbarea are loc mult mai simplu.n=4.n). cout << "A:".i<m. int &).i++) B[i]=(i+1)*10. afis(B. Din nou este de remarcat folosirea referintelor la pointeri! 12. cout << "A:".i++) A[i]=i+1.2 Functii care returneaza pointeri Prototipul unei functii care returneaza pointeri este de forma urmatoare: tip * nume_functie(lista_parametri). int n){ for(int i=0.i<n. } void afis(int A[]. B=T.n. cout << "B:". afis(A.m). *B=new int[3].

} void stergere(int *A. } void afis(int A[]. void stergere(int *. stergere(A. void afis(int []. cout << "A:". exit(1). Afisati prima linie dintr-o matrice patratica ce contine cel putin o valoare nula (se stie ca matricea contine cel putin un zero). int main(){ int *A. cin >> n.n). } 5 1 2 3 4 5 A:1 2 3 4 5 P21.int). int).i<n. if (!(T= new int[n])){ cout << "Eroare la alocare!".189 - .i++) cout << A[i] << " ".i<n. int n){ if (A) delete []A. Functii de alocare/dealocare dinamica a vectorilor. #include <iostream> using namespace std. int n){ for(int i=0.Introducere in ANSI C++ O astfel de functie poate fi apelata din orice loc al programului in care are sens sa apara un pointer care nu se va modifica.n). A=creare(n). int * creare(int &). afis(A.n. P20. . } int * creare(int &n){ int *T. return T. cout << endl.i++) cin >> T[i]. } for(int i=0.

6.5}. } void afis(int A[].Introducere in ANSI C++ #include <iostream> using namespace std.2.2}}.j<n.i++) cout << A[i] << " ".0.j. In plus.i<n. int main(){ int A[4][4]={{1. deci o functie va putea primi ca parametru o alta functie! Forma generala a unei declaratii de pointer la functie: tip_returnat (* nume_pointer) (lista_parametri). acestea facand diferentierea dintre o declaratie de pointer la functie si un prototip de functie care returneaza un pointer.3.int n){ int i.4}. {2. afis(prima(A.190 - .j++) if (A[i][j]==0) return A[i].0.3 Pointeri la functii O facilitate foarte puternica oferita de C/C++ este posibilitatea definirii si folosirii pointerilor la functii. {0.3.1.int ). .n=4.4.n). int). numele unei functii (fara paranteze si parametri) este un pointer. {1.i<n.n).2. void afis(int *. int n){ for(int i=0. o functie (afis).3}. for(i=0. } int * prima(int A[4][4]. Acest pointer va putea fi transmis ca parametru.i++) for(j=0. Parantezele care cuprind * si numele pointerului nu sunt optionale. primeste ca parametru un pointer rezultat un urma apelului unei alte functii (prima). int * prima(int [4][4]. } 1 2 0 3  In aceasta problema. 12.

double x. Functie are primeste ca parametru alta functie.} 20 30  P23. } sin(0)=0 .3).pow. void afisare(char *. #include <iostream> #include <cmath> using namespace std. double y){ cout << endl << text << "(" << x << ". p=triplu. void afisare(char *. int dublu(int).Introducere in ANSI C++ P22. cout << p(x. cout << p(10).} void afisare(char *text. int main(){ afisare("sin". double (* )(double. } void afisare(char *text. cout << p(10) << " ". afisare("functia mea". double (* p)(double. int main(){ int (* p)(int).} int triplu(int x){return 3*x. double. double). int dublu(int x){return 2*x. double calcul(double.double). double y){return x*x+y*y.y).0). double x){ cout << endl << text << "(" << x << ")=". Apelul unei functii folosind un pointer la functie. calcul. 2.double).191 - . afisare("pow". // declaratie pointer la functie p=dublu. } double calcul(double x.sin. #include <iostream> using namespace std.double).double). double (* p)(double)." << y<< ")=".3). double (* )(double). cout << p(x).2. int triplu(int).

6. Compilatorul nu poate face nici un fel de verificare asupra parametrilor .precision(2). iar cele trei puncte "anunta" compilatorul ca s-ar putea sa mai apara si alti parametri. } cout << endl..4    30  12. Tip_pointer_functie p[4]={sin. numarul si tipul parametrilor ai unei functii este cunoscut inainte de apelul efectiv.abs}. #include <iostream> #include <cmath> using namespace std. cout << "x sin cos tan abs\n". folosim functii cu numar variabil de parametri: tip_returnat nume(lista_parametri. unde lista_parametri contine cel putin un parametru. for(x=0.3)=13 P24.tan.x+=10){ cout << x << " ".65    10 20   0. cout.x.15  ­6.192 - .2    20 30  ­0.width(6).41   2.). typedef double (* Tip_pointer_functie)(double).84  0. } } x     sin    cos   tan   abs 0      0     1     0     0 10  ­0.x<=30. Folosirea unui vector de pointeri la functii.i++){ cout. int main(){ int i.99  0.cos. cout << p[i](x).54 ­0.91  0.. In acest caz. for(i=0.Introducere in ANSI C++ pow(2..i<4.4 Functii cu numar variabil de parametri In anumite situatii.3)=8 functia mea(2.

.... opn cn+1.. tinem cont de urmatoarele: – – – parametri se aloca pe stiva parametri se aloca in ordine inversa a scrierii lor in lista de parametri stiva creste in memorie de sus in jos Figura 12.. situatie memorie este: p1 p2 parametri cunoscuti pn ..193 - ..Introducere in ANSI C++ nespecificati explicit si accesul la acestia trebuie facut "de mana".. Functie cu numar variabil de parametri care calculaeza o expresie de forma: c1 op1 c2 op2 c3 . Pentru a vedea cum anume putem accesa parametri nespecificati.9 ilustreaza un posibil caz de apel: Stiva . pn p2 p1 parametri necunoscuti parametri cunoscuti Figura 12. deci.10 Observam ca parametri necunoscuti se gasesc la adrese imediat urmatoare ultimului parametru cunoscut. Figura 12. parametri necunoscuti .9 Conform observatiilor anterioare. daca se poate determina la rulare numarul si tipul parametrilor necunoscuti (prin informatii date de parametri cunoscuti).. acestia vor putea fi accesati folosind pointeri. .. . unde ci sunt intregi si opi este + sau -.. in functie de informatii auxiliare oferite in cadrul parametrilor clar specificati (vezi situatia functiei printf din cstdio). ... P25... ..

cout << calcul("+".1.4) << endl.){ int E. cout << calcul("-+-+". else E-=*p. return E..Introducere in ANSI C++ #include <iostream> using namespace std.s++. int main(){ cout << calcul("+++". for(s=op. dupa cum se vede la ultimul apel. // pozitionam p pe primul parametru necunoscut E=*p.4. un interg care este peste varful stivei! – . // apel incorect.2..-1.*s. unde lipseste un parametru in acest caz folosim o valoare oarecare.194 - ..-3. int calcul(char *.p++) // ne "deplasam" in paralel pe //operanzi si pe operatori if (*s=='+') E+=*p.i.). // pointer prin care accesam operanzii t=&op. .1). int *p.*s. p=(int *) t.. t++.3. p++. .2. // initializam E si mutam p pe al doiela param. } 10 ­15 11403253 Observatii: – – pozitionarea pe primul parametru necunoscut se poate face si mai simplu compilatorul nu poate verifica daca functia a fost corect apelata. nec. char **t. imposibil de detectat de catre compilator } int calcul(char *op.-5) << endl.

.3.4) << endl.p[nr].. parametri sunt dati practic de elementele vectorului p: p[1].){ int S.-3.. int main(){ cout << suma(4.2.i. } In acest caz.2... int suma(int. . cout << suma(5. for(int i=1.i<=nr. .i++) foloseste(p[i]).  p[2]. } 10 ­3 . } int suma(int nr.4.i<=nr.-1.*p.1.i++) S+=p[i]. for(i=1.). p=&nr. S=0. Functie cu numar necunoscut de parametri care realizeaza suma valorilor (primul parametru da numarul de parametri necunoscuti).Introducere in ANSI C++ Un caz particular de functie cu numar variabil de parametri este cazul in care ultimul parametru cunoscut este un intreg care specifica numarul de parametri necunoscuti care urmeaza. Forma generala pentru de lucru cu astfel de functie este: tip_returnat nume(int nr. .. #include <iostream> using namespace std.195 - .. .. return S. paramentri nocunoscuti fiind de tip int.. P26.){ tip *p=&nr.-5) << endl.

196 - . Realizati o functie cu numar variabil de parametri care calculeaza cmmdcul parametrilor.7 Probleme propuse Pp1. . Pp2. Rescrieti functiile de la problemele rezolvate din capitolele cu vectori si cu siruri de caractere folosind pointeri (fara acces indexat). Realizati o functie care primeste ca parametri: – – – o functie de forma int f(int) un vector de intregi lungimea vectorului si returneaza valoare minima atinsa de functia f pentru parametri fiind valorile din vector.Introducere in ANSI C++ 12. Pp3.

la prima salvare se deschide fereastra save as.close .navigarea prin meniuri se face cu cursorii si tasta Enter pentru selectare .afisarea ferestrei output .intrare in meniuri . ..help context sensitive .open .in acest mod putem vizualiza rezultatele afisate pe ecran .va da informatii despre cuvantul pe care se gaseste in acel moment cursorul de editare .permite deschiderea unei text sursa salvat anterior .navigare intre ferestre .save .Introducere in ANSI C++ Anexe A1..197 - .maximizare fereastra curenta .help .1 Shortcut F1 ^F1 Efect .inchide fereastra curenta .rularea programului Tabelul A1 – Shortcut-uri generale F2 F3  alt+F3  F5  alt+F5 F6 F10 ^F9 . Shortcut-uri uzuale folosite in mediul Borland C++ 3.

Introducere in ANSI C++

Shortcut
Shift + Cursori ^Insert

Efect - selectare text - copy - este copiata in clipboard zona selectata - paste - copiere din clipboard la pozitia cursorului - stergerea zonei selectate - undo - se revine cu un pas inapoi in procesul de editare - Atentie: la salvare se sterge istoricul Undo - redo - se merge cu un pas inainte in procesul de editare - este activat doar dupa operatii Undo

Shift + Insert

^Delete Alt+Backspace

Shift+Alt+Backspace

Tabelul A2 - Scurtaturi legate de editor

A2 Erori uzuale si cauze posibile (Borland C++ 3.1)

Eroare
Declaration terminated  incorrectly Declaration syntax error Statement missing ;

Cauza posibila ';' dupa main(), inainte de '{' lipseste ';' dupa o declaratie lipseste ';' cu un rand mai sus

- 198 -

Introducere in ANSI C++ Eroare
Undefined symbol _main in  module c0.ASM

Cauza posibila s-a gresit numele functiei main (de exemplu s-a scris mein) s-a uitat #include <iostream.h> schimbati '<<' cu '>>' sau invers lipseste o directiva #include sau am gresit numele functiei (de exemplu crlscr in loc de clrscr) trebuie declarata variabila intr-o conditie s-a pus = in loc de ==  (este de fapt un warning, dar in 99% din cazuri programul nu va functiona corect)

Undefines symbol 'cout' Illegal structure operation Function 'cutarescu' should  have a prototype

Undefined symbol 'a' Possibly incorrect assignment 

A3 Indentarea programelor C++
Cand scrii cod, nu conteaza cat de scurt si de simplu ti se pare, scrie-l intr-o maniera care il face usor de citit. Foloseste un standard al indentarii pentru codul tau si nu te abate de la el de-a lungul intregului program.

A3.1. Regulile de baza ale indentarii
De fiecare data indenteaza corpul unei instructiuni cu o distanta constanta fata de primul caracter al instructiunii (prin corp al unei instructiuni intelegem setul de actiuni pe care le controleaza acea instructiune). Instructiunile care au corp includ buclele, instructiunile conditionale si subprogramele. De exemplu, fie urmatoarea instructiune if-else: - 199 -

Introducere in ANSI C++
if  (a==0) { z_aparitii++; printf(“Zero a aparut de %d ori\n”,z_aparitii); } else { nz_aparitii++; printf(“valori diferite de zero sunt %d\n”,z_aparitii); }

Motivul pentru care folosim indentarea devine evident daca studiem alternativa urmatoare:
if  (a==0) { z_aparitii++; printf(“Zero a aparut de %d ori\n”,z_aparitii); } else { nz_aparitii++; printf(“valori diferite de zero sunt %d\n”,z_aparitii); }

Chiar daca vom intelege pana urma ce face sursa data, timpul necesar va fi sensibil mai mare fata de primul caz. Care este numarul de spatii cu care ar trebui sa indentati corpul unei instructiuni? In principiu, o indentare eficienta respecta regulile urmatoare: cel putin 2 spatii (1 spatiu nu va faca o diferenta notabila) nu mai mult de 8 spatii (altfel ramaneti fara spatiu pentru instructiuni) aplicand aceeasi indentare in toata sursa

Sugerez folosirea TAB-ului (setat, daca permite editorul, pe 4 spatii), fiind mai usor de folosit. In cazul functiilor definite de utilizator, respectiv functia main, aplicati regulile de mai sus. De exemplu:
int main(){ int a,b; // declaratii de variabile float r; printf(“Dati numitorul:”);

- 200 -

Introducere in ANSI C++
scanf(“%d”,&b); . . . }

Celelalte subprograme vor fi aliniate la functia main. In cazul in care numarul de parametri este mare, este posibil ca antetul functiei sa nu incapa pe in rand. In acest caz, indentarea parametrilor se va face in asa fel incat numele si tipul returnat de functie sa fie usor de cazut. Deci,
int o_functie_oarecare(int indice_de_plecare, int contor_folositor,      arbore *radacina,informatie_utila Info[]);

sau:
int o_functie_oarecare( int indice_de_plecare,  int contor_folositor,          arbore *radacina, informatie_utila Info[]);

dar nu:

int o_functie_oarecare(int indice_de_plecare, int contor_folositor,  arbore *radacina,informatie_utila Info[]);

A3.2 Stiluri de indentare ale blocurilor
Printre multitudinea de variante, s-au remarcat doua: A3.2.1 Aliniaza “{“ cu “}” Prin alinierea acoladelor, cititorul nu va avea dubii in legatura cu blocul din care face parte o anumita instructiune. De exemplu:
if  (a==0) { z_aparitii++; printf(“Zero a aparut de %d ori\n”,z_aparitii); } else  {

- 201 -

} A3. A3. printf(“Zero a aparut de %d ori\n”.3.2 Aliniaza “}” cu instructiunea ce controleaza blocul In programare. nu este necesara prezenta acoladelor. if-else si switch A3. sau: if (numar < 0)  . Acolada deschisa va fi amplasata la sfarsitul primei linii a instructiunii. este acceptabila amplasarea ei pe aceeasi linie cu if-ul. blocurile au rolul de a grupa instructiuni ce formeaza corpul unei instructiuni. Exemplu: if  (a==0)  { z_aparitii++. Deci “}” marcheaza.3 Instructiuni de selectie: if.z_aparitii).Introducere in ANSI C++ nz_aparitii++.z_aparitii).202 - . printf(“valori diferite de zero sunt %d\n”. atat sfarsitul blocului cat si sfarsitul corpului instructiunii. printf(“valori diferite de zero sunt %d\n”. Daca instructiunea este indeajuns de scurta. iar aceasta metoda “pierde” linii. } Un dezavantaj minor al acestei abordari este acela ca numarul de linii ocupat este mare.2. Oricare dintre urmatoarele varianta poate fi considerata o optiune buna: if (numar < 0) numar = 0.z_aparitii). }  else { nz_aparitii++. devine logica alinierea acoladei inchise la instructiunea a carei corp o inchide. Folosind aceasta observatie.1 if cu corp simplu Daca nu avem decat o singura instructiune de executat. Programatorilor le place sa vada cat mai mult cod pe ecran la un moment dat.

} A3. folosirea acoladelor.203 - .4 if-else cu corp compus Evident.2). acesta este unul din cazurile in care isi dovedeste utilitatea. Aveti de ales intre: .3. apoi folositi-o de fiecare data. alegeti o varianta care vi se potriveste. sau: if (numar < 0) { numar = 0. } A3.3. folosirea acoladelor nu este necesara.3 if-else cu corp simplu Exact ca in cazul if-ului simplu. } else { printf(“Sunt negativ sau zero!”). O varianta posibila ar fi cea data in sectiunea (2. sau: if (numar > 0) { printf(“Sunt pozitiv!”). contor­­. A3. if (numar > 0) printf(“Sunt pozitiv!”). Repet. in acest caz acoladele sunt necesare. A3. dar nici nu deranjeaza. chiar daca nu este neaparat necesara.Introducere in ANSI C++ numar = 0. else  printf(“Sunt negativ sau zero!”). poate duce la cresterea lizibilitatii sursei.5 if-else in combinatia corp simplu si corp compus Daca ati ales varianta in care folositi acoladele chiar si pentru corpuri simple.2 if cu corp compus if (contor > 0) { printf(“Numar pozitiv la orizont!”).3. } Pentru ultima varianta.3.

default: printf(“Nimic interesant. numitor = ­ numitor. } respectiv: switch (litera) { case ‘ ‘: printf(“Spatiu \n”). break. break.6 Instructiunea switch Se poate pleca de la premiza ca instructiunea switch are corpuri multiple. daca ne gandim ca fiecare case este inceputul unui alt bloc de cod. case ‘a’: case ‘e’: case ‘i’: case ‘o’: case ‘u’: printf(“Vocala \n”).Introducere in ANSI C++ if (numitor < 0) { printf(“Numitor negativ!”).”). default: printf(“Nimic interesant. case ‘a’: case ‘e’: case ‘i’: case ‘o’: case ‘u’: printf(“Vocala \n”). } else printf(“Totul e OK”).”). break. break. Cele doua variante consacrate ar fi: switch (litera) { case ‘ ‘:  printf(“Spatiu \n”). numitor = ­ numitor. . si: if (numitor < 0) { printf(“Numitor negativ!”).3.204 - . } A3. } else { printf(“Totul e OK”).

se recomanda variantele: i=0.1 while fara corp Desi pare ciudat pentru un incepator. sau: i=0. while ( (vector[i++]<0) && (i<numar_elemente) ) { . while ( (vector[i++]<0) && (i<numar_elemente) ) . pozitioneaza indicele din vector pe prima valoare pozitiva: i=0. Pentru a nu ignora punct-virgula de la sfarsitul randului (si deci a avea impresia ca instructiunea ce urmeaza while-ului face parte din corpul instructiunii). while ( (vector[i++]<0) && (i<numar_elemente) ) { /* sunt un bloc vid */.4. } O alta posibilitate ar fi cea de a insera un comentariu prin care se indica blocul vid: i=0. instructiuni repetitive fara corp (mai ales for) se regasesc in C++ mai des decat ar parea la prima vedere.Introducere in ANSI C++ } A3.4 Instructiuni repetitive: while. Deci. daca corpul este destul de mic.4. Urmatoarea secventa de program. avem urmatoarele situatii: . while ( (vector[i++]<0) && (i<numar_elemente) )  .2 while cu corp simplu Observatiile de la sectiunea anterioara raman valabile.205 - . for si do-while A3. } A3.

do  i++. i). i = 0.4 for in toate variantele Nimic nou sub soare. while ((i<numar_elemente) && (vector[i] != valoare_cautata)) { i++. do { i++. while ( i < Maxim ) { printf(“%d” . while ((i< numar_elemente)&&(a[i]<0)). sau: i = ­1. while ((i<numar_elemente) && (vector[i] != valoare_cautata))  i++.206 - . while ((i< numar_elemente)&&(a[i]<0)). sau: i = ­1.4.  } while ((i< numar_elemente)&&(a[i]<0)). do i++.4.5 do-while fara corp sau cu corp simplu Avem variantele: i = ­1. i=i*2. i = 0. i=1. . respectati regulile de la while. } A3. A3.Introducere in ANSI C++ i = 0. } A3.3 while cu corp compus Nu exista variante altele decat cele discutate in (3).4. while ((i<numar_elemente) && (vector[i] != valoare_cautata)) i++.

while la inceput de rand putand duce la confuzii. vom putea usor considera o instructiune ca finnd in afara unei bucle. A3. [2]        if (numar>0)  [3] suma += numar.5 Indentarea instructiunilor imbricate Indentarea este cu atat mai importanta in cazul in care avem instructiuni complexe ce fac parte din alte instructiuni complexe.suma ). numar. i<=5. In caz contrar ne trezim in situatia de a nu mai avea spatiu in partea dreapta a randului. Urmatorul exemplu da o posibila solutie:  if (nota >= 9) . [2]        else { [3] suma ­= numar. [1]        } [1]        printf("\nSuma este:%d\n”. Considerand fiecare TAB de la inceput de rand ca fiind nivelul indentarii.207 - . [0] } Se poate enunta urmatoarea regula: “fiecare corp se indenteaza cu un nivel in plus”.6 do-while cu corp compus Nimic nou de remarcat. putem avea urmatoarea situatie: [0] int main (void) [0] { [1]        int   i. desi ea face parte din corpul ei. nu avem nici o problema.Introducere in ANSI C++ Este de preferat ultima varianta. i++) { [2]        scanf("%d". Daca numarul de imbricari nu este mare. Fara imbricare. Un caz special il reprezinta instructiunile if-else imbricate. [1]        for (i=1.&numar). [1]        printf("\nIntroduceti cinci numare intregi pozitive\n").4. A3. [1]        int   suma = 0 .

else if (score >= 5) printf(“La limita”). else if (nota >= 8) printf(“Bine”). else if (score >= 7) printf(“OK”). A4 Precedenta operatorilor Nivel 1 Operator :: () [] . else if (score >= 6) printf(“Satisfacator”).Introducere in ANSI C++ printf(“Foarte Bine”).208 - . ­> ++ ­­  dynamic_cast static_cast  reinterpret_cast  const_cast typeid ++ ­­ ~ ! sizeof new  delete Descriere scope Grupare Left­to­ right Left­to­ right 2 postfix unary (prefix) indirection and  reference (pointers) unary sign operator type casting pointer­to­member multiplicative additive shift Right­ to­left Left­to­ right Left­to­ right Left­to­ right Left­to­ right Right­ to­left 3 * & + ­ 4 5 6 7 8 (type) . else printf(“Nasol”).* ­>* * / % + ­ << >> .

 template. bitand. switch. private. continue.  volatile. enum. return. asm. signed. const_cast. short. virtual. relational equality bitwise AND bitwise XOR bitwise OR logical AND logical OR conditional assignment comma Left­to­ right Left­to­ right Left­to­ right Left­to­ right Left­to­ right Left­to­ right Left­to­ right Right­ to­left Right­ to­left Left­to­ right A5 Cuvintele cheie Lista cu cuvintele cheia ANSI C++ este: and. bool. explicit. export. reinterpret_cast. compl. or. xor. this.Introducere in ANSI C++ 9 10 11 12 13 14 15 16 17 18 < > <= >= == != & ^ | && || ?: = *= /= %= += ­= >>= <<=  &= ^= != . dynamic_cast. while. unsigned. goto. void. for. not. operator.  float. throw. do.  double. bitor. friend. delete.  register. wchar_t. public. const. static.  char. false. struct. case. typeid. sizeof. true. int. namespace.209 - . inline. if. union. auto. extern. else. break.  new. protected. long. try. mutable. not_eq.  typedef.  static_cast. typename. or_eq. class. using. xor_eq  . and_eq. default. catch.

Lars Klander . 2000 [7] Carmen Popescu .„Programare C si C++ sub Linux”. editura Agora. editura Teora. 2002 [6] Thomas H. 2001 [2] Bjarne Stroustrup – „C++”. Leiserson. editura ULBS.„Culegere de probleme de informatica”.„Totul despre C si C++”.„Aplicatii in C si C++”. 2001 [5] Dragos Acostachioaie . Charles E. editura Teora.210 - . 2002 . Ronald R. Editura Polirom.„Introducere in algoritmi”. editura Donaris.Rovest . 2002 [4] Bogdan Patrut . editura Teora.Introducere in ANSI C++ Bibliografie [1] Kris Jamsa. 2003 [3] Breazu Macarie – „Programarea Orientata pe Obiecte – Principii”. Cormen.

....................25 3...........................18 3.................14 2............1 Notiunea de algoritm...........3.............................33 4.........211 - .1.........................................................................4 Expresii logice................30 3....................... Variabile si constante......1 In mediul Borland C++ 3............................................................4 Secvente escape.............................23 3....40 4......................................................2 Conversii de tip.......................................................................................................................................3 Compilarea si rularea programului.................31 3...............................................................................9 2.....................27 3...................4 1..............................................................1 Atribuirea.......33 4..........................................................................................1 Instructiunea while......................................................................................................16 2......................................................................................................................6 2.............................................................44 5.....44 5............20 3...........................................18 3.....1 Structura generala a unui program C++.............................................................................................................7 Operatori care actioneaza la nivel de bit..................................................2 Hi man!...................3 Tipuri de date........................................................6 Operatorul virgula..................7 2.....................6 Probleme propuse.........................1 Instructiunea if...........................32 Capitolul 4 – Instructiuni conditionale................5 Capitolul 2 – Notiuni de baza..3 1.....................................................................3 Probleme propuse.......47 5.....................17 Capitolul 3 – Expresii C++.............2 Folosind compilatorul g++.....................................................................................2 Instructiunea do-while...................................................2 1.....6 2.........................................3 Instructiunea for..............5 Operatorul conditional.................................................................5 Referinte (alias-uri)....2 Citirea si afisarea datelor.........................................43 Capitolul 5 – Instructiuni repetitive.................4 1...................................................................................................................................................49 .3 Expresii aritmetice................................................................................................................2 1.................................................1 Capitolul 1 – Primul program...............................3...........................................2 Instructiunea switch...............................................8 Probleme propuse.........................................................Introducere in ANSI C++ Cuprins Introducere..........................................................................................................................................................

.......................................................................115 8..................................72 6.........58 5.........1 Generalitati..............................5 Probleme propuse....117 Capitolul 9 – Functii........................................4 Tipul enumerat..................................................5 instructiunea goto....................107 8...............................................3 Accesul la caracterele unui sir...........................................94 7.......................................70 6............................................55 5....................................................................................1 Structuri..53 5...............................6 Probleme tip.................................................................................81 6............119 .....................................................................................................................................1 Probleme pe cifrele unui numar.....................114 8.........56 5.................................................................2 Operatii de citire/scriere pe siruri de caractere.......Introducere in ANSI C++ 5..................................................................................... numarari....107 8......................64 5...................9 Probleme propuse........................................................................2 Citirea si scrierea vectorilor................118 9..............................................................................................63 5....1 Declaratie si initializare......................4 Cateva probleme simple..5 Citirea mai multor numere de la tastatura......6.......................6........7 Citirea si afisarea matricilor.............3 Generari de vectori.............91 Capitolul 7 – Siruri de caractere............................................8 Probleme cu matrici.............................4 Maxime si minime.........................................................85 6.............................................60 5..........................................118 9.....85 6.....................92 7...............................................................77 6................................92 7..1 Declararea si initializarea................................3 Sume..................................95 7...............................7 Probleme propuse..................................................................................................................................212 - ..............66 5..................6............................6..............................................................2 Functii care nu primesc si nu returneaza nimic....................2 Uniuni...............4 break si continue...70 6.............4 Functii specifice sirurilor de caractere....................69 Capitolul 6 – Vectori (matrici).............................................................3 Campuri de biti.....................................................................................................................87 6...............................................................................................................75 6..............6 Declararea matricilor.......................................................................................5 Sortarea si interclasarea.....................................................56 5.....111 8............. produse........................6............................................................................2 Probleme de divizibilitate............97 Capitolul 8 – Structuri si alte tipuri utilizator.6.........6 Generarea unor serii complexe de numere .............

.....6 Functii ce returneaza mai multe valori...2 Alocarea dinamica a tablourilor..................10 Parametri vectori..............................129 9......165 12...............................................6 Legatura dintre pointeri si functii..................................4 Citirea pana la sfarsitul fisierului.............170 12....................143 9......................1 Redirectarea intrarii/iesirii....................127 9.........................5 Legatura dintre pointeri si tablouri..................................3 Vectori de pointeri.................................161 11.155 Capitolul 11 – Fisiere.......149 10.....................................................................................213 - ..............................................................3 Alocarea dinamica a memoriei.................................................................................................... Durata de viata si domeniu de vizibilitate...................................................................4 Pointeri la structuri..........................................176 12.......................................................8 Supradefinirea functiilor.....3 Scaderea si adunarea cu un intreg...2.3 Functii care nu returneaza nimic...................................3 Citirea unui numar cunoscut de valori dintr-un fisier..........1 Atribuirea.............137 9............181 12.....................................................................................................................2 Operatorii relationali............................................1 Declaratie si operatii elementare.........................................................................................174 12..................................................................................175 12............................156 11...........9 Functii cu parametri impliciti...........................................7 Variabile locale si globale.................................................................................................................141 9...................................................................158 11...........................................................................154 10.............................176 12...........................................184 ..........................165 12......................133 9..........2..............2...............................149 10....2 Recursivitatea indirecta...................................................................................................................4 Functii care nu primesc date de intrare dar returneaza o valoare..................................5 Functii care primesc un numar oarecare de parametri de intrare si returneaza o singura valoare....2 Fluxuri de intrare/iesire................................11 Probleme propuse...2........1 Recursivitatea directa.......170 12......156 11...5.....144 9.................................................171 12.......................3 Probleme propuse..........4 Diferenta a doi pointeri.121 9.......................... dar primesc date de intrare...................148 Capitolul 10 – Recursivitate.............174 12..2 Aritmetica pointerilor..........................................................164 Capitolul 12 – Pointeri.................5.......1 Accesul la elementele unui tablou folosind pointeri................................5....179 12.5 Probleme propuse..........160 11.....................Introducere in ANSI C++ 9........173 12.........

.........197 A2 Erori uzuale si cauze posibile (Borland C++ 3..........188 12.....................Introducere in ANSI C++ 12.....2 Functii care returneaza pointeri..................208 A5 Cuvintele cheie............................201 A3..199 A3........2 Stiluri de indentare ale blocurilor....................................................192 12.................. Regulile de baza ale indentarii..........205 A3......197 A1.....................................................................................................207 A4 Precedenta operatorilor....................5 Indentarea instructiunilor imbricate........198 A3 Indentarea programelor C++..................................................................................................................................7 Probleme propuse..4 Instructiuni repetitive: while....................................................................199 A3..3 Pointeri la functii.......210 .................... for si do-while.....................6......................................... if-else si switch............................................1..................1 Functii cu parametri pointeri.4 Functii cu numar variabil de parametri.......................................................................................................1............209 Bibliografie..............214 - ..................................................196 Anexe.6..................................3 Instructiuni de selectie: if...............................................6.....................................1)..........................184 12..............................6........ Shortcut-uri uzuale folosite in mediul Borland C++ 3................202 A3..190 12......................................................

Sign up to vote on this title
UsefulNot useful