Documente Academic
Documente Profesional
Documente Cultură
Scrierea aplicaiilor
Un program are nevoie de date pentru a opera. Pn acum am scris programe n care valorile datelor se gsesc chiar n program, n constante simbolice sau literale. Dac dorim s modificm o dat, trebuie s facem o mic modificare n program, s l recompilm i s l executm din nou. n acest capitol vom vedea cum putem introduce date n program chiar n timpul rulrii lui. Odat ce am aflat cum s introducem date n program, s procesm datele i s afim rezultatele, putem s ne gndim la scrierea unor programe mai complicate. Pentru aceasta avem nevoie de o abordare ceva mai organizat. n finalul capitolului vom discuta despre descompunerea n module i despre programarea orientat pe obiecte.
4.1
Unul dintre marile avantaje ale calculatorului este c un program poate fi folosit cu diverse seturi de date. Pentru aceasta trebuie s separm datele de program pn n momentul execuiei. Anumite instruciuni din program copiaz valori n variabilele din program. Dup stocarea acestor valori n variabile, programul poate s le foloseasc n calcule. Procesul de plasare a unor valori dintr-o mulime de date n variabile din program se numete intrare (input). ntr-o terminologie mai larg, calculatorul se spune c citete date din exterior n variabile. Datele pot proveni dintr-un fiier, de la tastatur etc. Dispozitivul standard de intrare este tastatura.
fiind echivalent cu: cin >> lungime; cin >> latime; Trebuie s fim ateni atunci cnd folosim cei doi operatori, pentru c cin poate fi folosit doar n combinaie cu >>, iar cout doar cu <<. Dac ntr-o instruciune de afiare putem folosi constante, variabile i chiar expresii foarte complicate, ntr-o instruciune de intrare nu putem folosi dect nume de variabile. Aceasta pentru c o instruciune de intrare trebuie s precizeze clar unde se stocheaz valoarea unei date de intrare. Doar numele de variabile refer locaii de memorie ale cror valori pot fi modificate n timpul execuiei unui program. Atunci cnd introducem o dat de la tastatur, trebuie s ne asigurm c tipul introdus i cel ateptat de program se potrivesc. Un numr ntreg este forat automat la un numr real. Operaia invers, ns, poate conduce la rezultate eronate. Atunci cnd extrage valori dintr-un stream, operatorul >> ignor orice spaiu de la nceput. De asemenea, ignor caracterul care marcheaz sfritul liniei. Apoi, operatorul >> procedeaz la extragerea valorilor din stream-ul de intrare. Dac data ateptat este un char, intrarea se ntrerupe dup primul caracter. Dac este vorba de un int sau double, intrarea se ntrerupe la primul caracter care nu se potrivete ca tip de dat, cum ar fi un spaiu. Exemplu int i, j, k; char ch; float x; Instruciunea Data Coninutul variabilei dup intrare cin >> i; 32 i = 32 cin >> i >> ch >> x; 25 A 16.9 i = 25 ch = A x = 16.9 cin >> i >> j >> x; 12 8 i = 12 j = 8 Programul ateapt al treilea numr cin >> i >> x; 46 32.4 15 i = 46 x = 32.4 15 este pstrat pentru o intrare ulterioar
Caracterul newline
Fiecare linie are un caracter invizibil care marcheaz sfritul su caracterul newline. Pentru a determina urmtoarea valoare de intrare, operatorul >> trece peste caracterul newline, n cazul n care acesta exist. Atunci cnd utilizm tastatura, caracterul newline este introdus prin apsarea lui Return sau Enter. Programul poate genera un newline folosind manipulatorul endl ntr-o instruciune de ieire. n C++ putem s ne referim la caracterul newline folosind simbolurile \n. Dei \n const din dou caractere, el se refer la unul singur caracterul newline. Aa cum putem pstra litera A n variabila ch de tip char prin instruciunea char ch = A; tot aa putem pstra caracterul newline ntr-o variabil: 2
ch = \n; Exemplu Cnd avem o secven de citiri, putem introduce valorile n mai multe feluri: cin >> i; 25 A 16.9\n 25\n 25A16.9\n cin >> ch; A\n Citirea se oprete cnd cin >> x; 16.9\n tipul de dat nu mai corespunde Dup citire, variabilele vor avea urmtoarele valori: i = 25 ch = A x = 16.9
A B\n CD\n
ch1 = A; ch2 = B; ch3 = C; ch1 = A; ch2 = ; ch3 = B; ch1 = A; ch2 = B; ch3 = \n;
cin.get(ch1); A B\n cin.get(ch2); CD\n cin.get(ch3); cin >> ch1; A B\n cin >> ch2; CD\n cin.get(ch3);
ABCDEF\n
ch = C;
int cantitate; double pretUnitar; double pretTotal; cout << "Introduceti comandat:" << endl; cin >> codNumeric; codul numeric al produsului
cout << "Introduceti cantitatea:" << endl; cin >> cantitate; cout << "Introduceti produs:" << endl; cin >> pretUnitar; pretul unitar pentru acest
pretTotal = cantitate * pretUnitar; cout.setf(ios::fixed, ios::floatfield); cout << << << pretUnitar << cout << "Produsul " << codNumeric ", cantitatea " << cantitate ", pretul unitar " << setprecision(2) " lei " << endl; "Total: " << pretTotal << endl;
<<
return 0; } n timpul rulrii acestui program se va tipri cte un text care va arta utilizatorului care este urmtoarea valoare ateptat. Exemplu Introduceti codul numeric al produsului comandat 4671 Introduceti cantitatea: 10 Introduceti pretul unitar pentru acest produs: 272.55 Produsul 4671, cantitatea 10, pretul unitar 272.55 lei Total: 2725.50 Volumul informaiei afiate depinde de cel care va folosi programul. Dac el este destinat unor persoane nefamiliarizate cu calculatorul, mesajele vor fi mai detaliate. Dac programul este folosit frecvent de aceeai persoan, putem da mesaje mai scurte sau se pot introduce mai multe valori pe aceeai linie.
4.2
Fiierul este o zon pe un suport de stocare, de exemplu hard disc, desemnat printr-un nume, care pstreaz o colecie de date, de exemplu codul programului scris cu un editor. Un program poate citi datele dintr-un fiier n aceeai manier n care le citete de la tastatur. Se poate scrie n fiier la fel cum se scrie pe ecran. Atunci cnd programul ajunge s lucreze cu cantiti mari de date, este de preferat s folosim fiierele. Acestea pot fi scrise cu un editor de texte, corectate i salvate pe disc. Totodat, nu suntem obligai s introducem toate datele dintr-o singur dat.
ifstream inConsum; ofstream outConsum; inConsum.open("incons.dat"); outConsum.open("outcons.dat"); inConsum >> cant1 >> cant2 >> cant3 >> cant4 >> indicatiePlecare >> indicatieSosire; litriPerKm = (cant1 + cant2 + cant3 + cant4)*100.0/ (indicatieSosire - indicatiePlecare); outConsum << "Consumul este " << litriPerKm << " litri per km." << endl;
return 0; } Mai nti folosim directiva de preprocesare #include <fstream> Prin acest header se definesc dou noi tipuri de date, ifstream i ofstream. Cele dou tipuri de dat reprezint, primul, un stream de caractere provenind de la un fiier, iar al doilea un stream de caractere care conduce ctre un fiier. Toate operaiile valabile pentru un istream: >>, get sau ignore sunt valabile i pentru tipul ifstream. Operaiile folosite pentru un ostream: <<, endl, setw, setprecision se pot folosi i pentru un ofstream. Declararea stream-urilor pentru fiiere Obiectele de tip stream se declar la fel ca orice variabil Exemplu int unInt; float unFloat; ifstream unFisier; ofstream altFisier; Obiectele cin i cout nu trebuie declarate n fiecare program pentru c ele sunt declarate n fiierul iostream, citirile de la tastatur i scrierile pe ecran fiind operaii frecvente. Spre deosebire de ele, stream-urile pentru lucrul cu fiiere trebuie declarate n program pentru c fiecare aplicaie folosete propriile fiiere de date. Pentru programul nostru declarm dou stream-uri: ifstream inConsum; ofstream outConsum; De notat c ifstream se utilizeaz doar pentru fiiere de intrare, iar ofstream doar pentru fiiere de ieire. Prin intermediul unui obiect ifstream se pot face doar citiri, iar prin intermediul unui obiect ofstream se pot face doar scrieri. Deschiderea fiierelor Trebuie s pregtim acum fiierele pentru citire sau scriere, deci le deschidem. Ne propunem s citim din stream-ul tip fiier inConsum i s scriem n streamul outConsum. Deschidem fiierele folosind urmtoarele instruciuni: inConsum.open("incons.dat"); outConsum.open("outcons.dat"); Funcia open are un singur argument cuprins ntre ghilimele. Prima instruciune este un apel al funciei open asociate cu tipul de dat ifstream, iar a doua apeleaz funcia open asociat cu ofstream. Funcia open asociaz variabila stream din program cu un fiier fizic pe disc. Prima instruciune realizeaz o conexiune ntre obiectul inConsum i fiierul incons.dat. A doua instruciune leag obiectul outConsum de fiierul outcons.dat. inConsum este conectat cu incons.dat aa cum cin este legat de tastatur. Mai departe, aciunea depinde de tipul de stream. Pentru un fiier de intrare, funcia open poziioneaz markerul de citire pe primul element din fiier. Pentru un fiier de ieire, funcia verific dac acesta exist. Dac exist, terge vechiul coninut al su. Dac nu exist, l creeaz. Apoi markerul de scriere este aezat pe prima poziie.
Folosim noiunile de marker de citire sau de scriere pentru a reprezenta locul din care se va citi dintr-un stream de intrare, respectiv se va scrie ntr-un stream de ieire. Exemplu inConsum outConsum 23.2 _ 17.4 19.8 16.7 22451 23544 Deschiderea fiierelor trebuie realizat naintea oricrei utilizri a lor deoarece funcia open le pregtete pentru citire sau scriere. Specificarea stream-urilor n instruciuni I/O Pentru citirea i scrierea din fiier nu va trebui dect s nlocuim obiectele cin i cout cu obiectele de tip stream de fiier declarate mai devreme. Exemplu inConsum >> cant1 >> cant2 >> cant3 >> cant4 >> indicatiePlecare >> indicatieSosire; outConsum << "Consumul este " << litriPerKm << " litri per km." << endl; Cel mai interesant este c C++ folosete o sintax uniform pentru operaiile I/O, indiferent dac este vorba despre fiiere sau dispozitive I/O.
4.3
Erori de citire
La citirea datelor de la tastatur sau dintr-un fiier pot aprea erori. S presupunem c programul ne cere s introducem un numr ntreg, iar noi introducem caractere. Operaia de intrare eueaz datorit datelor de intrare invalide. n terminologia C++ stream-ul cin intr ntr-o stare de eroare - fail state. Dac un stream intr ntr-o astfel de stare, orice alt operaie ulterioar asupra sa este anulat. Din pcate, calculatorul nu oprete programul i nu d niciun mesaj de eroare n astfel de situaii. De cele mai multe ori erorile de intrare apar din cauza nepotrivirii tipurilor de dat. Exemplu int i = 10; int j = 20; int k = 30; cin >> i >> j >> k; cout << i: << i << j: << j << k: << k; Dac tastm 1234.56 7 89 programul afieaz i: 1234 j: 20 k: 30 Un alt motiv pentru care un stream intr n fail state este incercarea de deschidere a unui fiier de intrare care nu exist. S presupunem c avem pe disc fiierul myfile.dat i scriem urmtoarele instruciuni care i propun s lucreze cu acest fiier: ifstream inFisier; inFisier.open(myfil.dat); 8
inFisier >> i >> j >> k; Datorit scrierii incorecte a numelui de fiier, inFisier va intra n fail state. Ca urmare, variabilele i, j i k vor avea nite valori nedeteminate. Un stream de citire dintr-un fiier intr n fail state atunci cnd se citete din fiier dincolo de caracterul EOF, cel care marcheaz finalul fiierului.
4.4
Scrierea aplicaiilor
Problemele pe care le-am prezentat pn acum au fost simple i uor de programat. n acest moment putem scrie i aplicaii mai complexe i de aceea trebuie s vedem cum putem concepe corect o aplicaie. Vom vorbi despre descompunerea funcional i despre proiectarea orientat pe obiecte.
Descompunerea funcional
Aceast este o tehnic de dezvoltare a unei pri a unui program sau chiar a unui program de dimensiuni reduse prin care problema este mprit n subprobleme mai uor de rezolvat, soluii care creeaz o soluie global a ntregii probleme. Printr-o astfel de descompunere crem o structur ierarhic numit structur arborescent. Rezolvarea problemei Pas I Pas II Pas III abstract Nivelul 0
pas abstract Subproblema I Pas A Pas B Subproblema II Pas C Pas D Subproblema III Pas E Pas F Nivelul 1
Subproblema A Pas 1
Subproblema B Subproblema C Pas 2 Pas 3 Pas 4 Pas 5 Pas 6 Subproblema 2 Pas a Pas b Pas c 9
pas concret
Nivelul 3 concret
Paii haurai conin suficiente detalii pentru a putea fi implementai n C++. Cei nehaurai trebuie descompui n continuare. Fiecare celul este un modul. Modulele sunt elemente de baz ntr-o descompunere funcional. Pentru conceperea unui modul trebuie s parcurgem urmtorii pai: 1. S schim o soluie a problemei 2. S descriem paii majori 3. Dac un pas este suficient de simplu pentru a putea fi implementat, nu mai necesit descompuneri ulterioare 4. Dac pasul poate fi gndit ca o serie de pai mai mici, este nc un pas abstract
10
petrecut cu analiza i proiectarea poate salva foarte mult timp care se poate pierde cu dezvoltarea unui sistem greit conceput. Unified Modeling Language (UML) Exist multe procedee pentru analiza i proiectarea orientat pe obiecte. Pentru totate acestea se folosete un limbaj grafic de comunicare a rezultatelor numit Unified Modeling Language (UML). Prima versiune a acestui limbaj a fost lansat n anul 1996 de ctre James Rumbaugh, Grady Booch i Ivar Jacobson de la Rational Software Corporation. n acelai timp, organizaia non-profit Object Management Group (OMG) a lansat, la iniiativa companiilor HP, IBM, Microsoft, Oracle i Rational Software, o propunere de creare a unui limbaj unic de modelare. UML a fost limbajul adoptat de OMG care, ncepnd cu anul 1997 asigur revizuirea permanent a sa. UML este o schem de reprezentare grafic pentru modelarea sistemelor orientate pe obiecte. Una dintre cele mai atractive caracteristici ale sale este flexibilitatea. UML este extensibil i independent de multele procese de analiz i proiectare orientate pe obiecte. Tehnologia obiectelor a devenit indispensabil n industria software, iar UML este din ce n ce mail folosit. Specificaiile complete ale UML sunt disponibile la http://www.uml.org.
11