1. Crearea unui proiect n MS Visual Studio 2008 ............................................................................ 1
2. Adugarea unui fiier la proiect .................................................................................................... 6 3. Scrierea primului program ............................................................................................................ 8 4. Compilarea, rularea i detectarea erorilor ................................................................................. 10 5. Scrierea / citirea cu cin i cout .................................................................................................... 12 6. Operatorii new i delete ............................................................................................................. 13 7. Un program mai complex ........................................................................................................... 14 8. Debug .......................................................................................................................................... 16 9. Documentaie .............................................................................................................................. 22 10. Exerciii ........................................................................................................................................ 22
1. Crearea unui proiect n MS Visual Studio 2008
Visual Studio 2008 este mediul de dezvoltare integrat (IDE Integrated Development Environment) pe care l vom folosi pentru scrierea programelor C++. Mediul permite dezvoltarea de aplicaii n mai multe limbaje de programare, de diverse tipuri. n cadrul laboratorului vom scrie programe C++ de tip consol. Pentru a scrie un program n VS2008, la nceput trebuie s creem un proiect. Pentru a crea un proiect, parcurgem urmtorii pai : 1. Pornim mediul de dezvoltare VS2008 2. n meniul principal, mergem la File New Project ca n figura 1.1:
Fig. 1.1 Crearea unui nou proiect
3. n fereastra New Project, n stnga avem csua Project types (vezi figura 1.2). Alegem Other languages Visual C++
Fig. 1.2 Fereastra New Project
4. n partea dreapt avem csua Templates. Alegem Win32 Console Application. 5. n partea de jos avem csuele Name i Location. Alegem un nume pentru proiect. La Location selectm un director de lucru creat de noi n C:\temp sau D:\temp dup caz. (vezi fig. 1.2) 6. Apsm OK. 7. n continuare, apare fereastra Welcome to the Win32 Application Wizard (vezi figura 1.3). Apsm Next, NU Finish!
Fig. 1.3 Fereastra Welcome
8. n noua fereastr aprut, la rubrica Additional options, bifm Empty project. Lsm celelalte setri neschimbate (vezi figura 1.4):
Fig.1.4 Fereastra Application Settings
9. Apsm Finish.
Proiectul este creat i deschis n mediul de dezvoltare (vezi figura 1.5). Ar trebui s vedem urmtoarele ferestre: Solution explorer n partea stnga. De aici se pot crea sau deschide fiierele proiectului. Iniial proiectul nu conine nici un fiier. Start Page n restul ecranului. Aceast ferestr nu este util, ea poate fi nchis. Mediul de dezvoltare va arta n felul urmtor:
Fig. 1.5 Proiectul nou creat 2. Adugarea unui fiier la proiect
Ca s putem scrie cel mai simplu program n VS2008, trebuie s adugam un fiier surs la proiect. Pentru aceasta, vom face urmtorii pai: 1. n Solution Explorer, click dreapta peste grupul Source Files Add New Item(vezi figura 1.6)
Fig. 1.6 Adugare fiier surs
2. Apare fereastra Add New Item (figura 1.7). 3. n csua Templates alegem C++ File (.cpp) 4. La Name introducem numele fiierului. De obicei vom numi fiierul care conine funcia main() dup regula <numeProiect>Main; n cazul nostru salutMain.
Fig. 1.7 Adugare fiier surs partea 2
5. Apsm Add. Noul fiier va fi creat i deschis n editor. 3. Scrierea primului program
S scriem un program simplu care afieaz un mesaj la consol, dup care ateapt apsarea unei taste (vezi figura 1.8):
Fig. 1.8 Scrierea codului surs n editor
Observm n dreptul numelui fiierului salutMain.cpp, o stelu (*). Aceasta nseamna c fiierul conine modificri nesalvate. Liniile modificate sunt marcate cu galben n stnga editorului. Apsm Ctrl+S pentru a salva fiierul. Observm c stelua a disprut. Funcia _getch() de la sfritul programului este echivalentul lui getch() din biblioteca <conio.h> utilizat la programele scrise n C Standard. Ea ateapt apsarea unei taste fr s o afieze pe ecran. n Visual Studio codul este formatat n mod automat atunci cnd l scriem. Chiar dac programul nu este formatat aa cum ne dorim, putem s reformatm codul, n orice moment, apsnd Ctrl+A, iar apoi Ctrl+K, Ctrl+F. Este bine s formatm permanent codul scris. Formatarea face programul mai lizibil i ne ajut s nelegem i s detectm mai uor erorile. Urmtorul experiment ilustreaz facilitatea reformatrii n practic: 1. n dreptul apelului printf() apsm tasta Tab pentru a-l deplasa(indenta) n mod eronat la dreapta (vezi figura 1.9):
Fig. 1.9 Exemplu de cod neformatat
2. Apsm Ctrl+A pentru selectarea textului din fereastra editorului. 3. Apsnd Ctrl+K, iar apoi Ctrl+F. Observm cum codul este formatat din nou, n mod corect. 4. Compilarea, rularea i detectarea erorilor
Pentru a compila proiectul apsm Ctrl+Alt+F7, sau din meniul principal selectm Build Rebuild Solution. Dac sunt detectate erori de compilare, n partea de jos a ecranului va aprea fereastra Error List. S introducem intenionat o eroare pentru a vedea facilitile acestei ferestre. De exemplu, putem nlocui linia printf("Salut!\n"); cu printf("Salut!\n", x);. La compilare, compilatorul consider c x este o variabil nedefinit i afieaz fereastra Error List cu urmtorul mesaj (vezi figura 1.10):
Fig. 1.10 Mesaj de eroare
Dac dm dublu-click peste mesajul de eroare, cursorul se va deplasa la linia de cod coninnd eroarea. Utilizarea unei variabile fr ca aceasta s fie declarat este una din cele mai comune erori de programare. n VS2008, aceasta poate fi detectat i corectat foarte uor. Alte tipuri de erori pot duce la mesaje de eroare mult mai neclare i chiar linia de cod a erorii poate fi detectat greit. n general s-a observat urmtoarea regul: eroarea trebuie cutat ori pe linia afiat n Error List, ori cu o linie mai sus. De exemplu, dac n program, tergem caracterul ; de la sfritul uneia dintre linii, vom vedea c mesajul de eroare ne duce cu o linie mai jos. S corectm programul i s l compilm din nou. Chiar dac, dup compilare, n fereastra Error List nu apar erori, dar apar warning-uri, acestea trebuie eliminate din codul surs. De cele mai multe ori warning-urile duc i ele la erori de execuie, deci se recomand eliminarea acestora nainte de rularea proiectului. Pentru a executa programul apsm tasta F5. Se deschide o fereastr, care este consola n care ruleaz programul. 5. Scrierea / citirea cu cin i cout
n C++ s-a elaborat o modalitate mai simpl de scriere/citire la/de la consol avnd accelai efect ca i funciile de bibliotec scanf()/printf() din C. La nceputul execuiei fiecrui program sunt instaniate automat dou variabile globale speciale cin i cout. Ele sunt folosite pentru citirea, respectiv scrierea utiliznd consola. Pentru a citi o variabil de la consol, se folosete urmtoarea sintax: int a; cin >> a;
Operatorul >> are un rol special pentru variabila cin. Expresia: cin >> a;
semnific faptul c de la consol este citit o valoare i depozitat n variabila a. Tipul variabilei din dreapta poate fi oricare din tipurile fundamentale: int, char, float, double sau char* care reprezint un ir de caractere. Pentru fiecare tip enumerat mai sus, implicit citirea se va face corect. Pentru a scrie o variabil la consol, folosim sintaxa: char str[] = "abc"; cout << str;
n mod similar, operatorul << are o semnificaie special pentru variabila cout. Expresia: cout << str;
semnific faptul c variabila str este scris la consol. Variabilele scrise pot avea aceleai tipuri ca i cele citite cu cin. Aceste tipuri au fost enumerate mai sus pentru variabila cin. Observm c n exemplul de mai sus a fost scris la consol o variabil de tip char[], tip care nu a fost menionat n lista de tipuri suportate pentru operandul dreapta. Totui, utilizarea lui a fost posibil ntr-o expresie cu cout. De ce? Variabilele cin i cout sunt definite n header-ul <iostream>. Ca s le putem folosi, trebuie s includem la nceputul programului urmtoarele linii: #include <iostream> using namespace std;
Aceste variabile speciale(cin i cout) sunt obiecte. Obiectele vor fi studiate n detaliu ncepnd cu laboratorul urmtor. Iat un exemplu complet folosind noile faciliti de scriere/citire din C++: // exemplu: cin si cout #include<conio.h> #include <iostream> using namespace std;
int main() { int iVal; char sVal[30];
cout << "Introduceti un numar: "; cin >> iVal; cout << "Si un sir de caractere: "; cin >> sVal; cout << "Numarul este: " << iVal << "\n" << "Sirul este: " << sVal << endl; _getch(); return 0; } Exemplu de rulare: Introduceti un numar: 12 Si un sir de caractere: abc Numarul este: 12 Sirul este: abc
Un element nou este cuvntul endl. Acesta este o funcie special numit i manipulator care trimite o nou linie (echivalent cu "\n") la ieirea standard, golind i bufferul acesteia. Att expresiile cu cin ct i cele cu cout pot fi nlnuite. Expresia cout << a << " " << b;
este echivalent cu cout << a; cout << " "; cout << b;
Comparativ cu funciile printf() / scanf() din C, expresiile cu cin i cout sunt mai simple i mai uor de neles. Nu mai sunt necesari specificatorii de format. Dezavantajul const n faptul c nu putem face afiri formatate pe un anumit numr de caractere. O afiare de genul: printf("%7.2f", f);
nu are echivalent folosind cout, dect dac se folosesc manipulatori speciali pentru formatare. 6. Operatorii new i delete
n C++, lucrul cu memoria dinamic este facilitat de doi operatori speciali: new i delete. Alocarea dinamic de memorie se face cu operatorul new. El returneaz un pointer ctre nceputul blocului de memorie alocat. Sintaxa operatorului este urmtoarea: TIP *p, *pvector; p = new TIP; pvector = new TIP[nr_elemente];
De exemplu, pentru pointeri la tipurile fundamentale, alocarea se va face ca n exemplul urmtor : int *pi; pi = new int; char *pch; pch = new char;
Pentru pointeri la vectori alocarea se face dup cum urmeaz: int *vi; vi = new int[10]; char *psir = new char[80];
Atunci cnd nu mai avem nevoie de o variabil alocat dinamic, aceasta trebuie dezalocat. Memoria dezalocat devine disponibil pentru noi cereri de alocare. Pentru dezalocri se folosesc operatorii delete pentru variabile de tip fundamental i delete[] pentru vectori. Exemplu: delete pi; delete pch; delete[] vi; delete[] psir; 7. Un program mai complex
n continuare vom scrie un program mai complex, care va exemplifica facilitile limbajului C++ de lucru cu consola i cu memoria dinamic(heap). Programul citete de la consol un vector de n iruri de caractere, aloc pentru ele spaiul de memorie strict necesar i le sorteaz n ordine cresctoare. Este una din problemele propuse la disciplina de Programarea Calculatoarelor din anul I, semestrul II, dar acum va fi rezolvat folosind facilitile C++. n Visual Studio, putem crea o soluie nou (o soluie reprezint o mulime de proiecte deschise simultan), sau putem aduga un proiect nou n cadrul soluiei existente. Vom crea un proiect nou i vom aduga la el trei fiiere: SortareSiruri.h, SortareSiruri.cpp, SortareSiruriMain.cpp. Codul surs este prezentat mai jos.
Acest program conine cteva elemente noi: 1. n fiierul SortareSiruri.h, apare urmtoarea directiv de preprocesare #pragma warning(disable : 4996) Conform acestei directive, mediul Visual Studio 2008 dezactiveaz warning-urile cu codul 4996. Dezactivarea lor este necesar pentru a putea folosi funciile cunoscute din limbajul C fr a obine warning-uri inutile la compilare. 2. n fiierul SortareSiruri.cpp, avem urmtoarea linie n funcia citireVSiruri(): cin.ignore(100, '\n');
Acest apel este necesar nainte de apelarea funciei cin.getline(), care citete o linie de caractere de la consol. Rolul apelului este s ignore caracterele din bufferul de intrare rmase de la citirea anterioar. Pentru detalii, putem studia documentaia acestei funcii. Ea are acelai rol ca i funcia fflush(stdin)n C, cu observaia c fflush(stdin) golete bufferul de intrare. 3. n aceeai fiier SortareSiruri.cpp, avem apelul: cin.getline(buffer, 100);
Funcia cin.getline() citete o linie de la consol, sub forma unui ir de caractere i o depune n buffer. Al doilea-lea parametru 100 este numrul maxim de caractere care pot fi citite. Funcia este echivalent cu fgets() din C. A fost necesar s utilizm aceste funcii noi, n loc de fflush(), fgets() din C, pentru c nu este bine s amestecm funciile de lucru cu consola din C cu cele din C++. La utilizarea lor mixt pot aprea incompatibiliti. Recomandare. Toate programele realizate n cadrul laboratoarelor de POO vor fi concepute ca proiecte, respectnd aceleai standarte ca i la obiectul Programarea Calculatoarelor. Adica unul sau mai multe fiiere header, unul sau mai multe fiiere cu funcii, i un fiier cu funcia main. 8. Debug
Debug-ul este facilitatea oferit de mediile de dezvoltare de a analiza procesul de execuie a unui program n scopul de a detecta erorile. n modul de lucru Debug, se poate rula programul instruciune cu instruciune, urmrind valoarea unor variabile dup fiecare instruciune executat. De asemenea, se pot stabili anumite linii de cod la care dorim ca programul s se opreasc i astfel, s vizualizm valoarea variabilelor alese de noi doar n acele puncte din program. Aceste linii n care dorim s ntrerupem execuia programului se numesc puncte de oprire (breakpoint-uri). De exemplu, s lum cazul unei erori des ntlnite i s presupunem c n programul SortareSiruri.cpp afiarea este greit. Vom dori s verificm n primul rnd dac alocarea memoriei i citirea a fost fcut corect iar apoi, dac sortarea a fost corect. Pentru aceasta, vom plasa dou breakpoint-uri n funcia main, unul dup funcia de citire i altul dup funcia de sortare. Pentru plasarea unui breakpoint, poziionm cursorul n dreptul liniei de cod la care vrem s oprim execuia programului i apsm tasta F9. Se poate scoate un breakpoint tot prin apsarea tastei F9. n partea dreapt a editorului va aprea o bulin roie pentru fiecare breakpoint astfel plasat(vezi figura 1.11):
Fig. 1.11 Breakpoint-uri
n continuare, apsm tasta F5 pentru a rula programul n mod Debug. Vom observa c programul i ncepe execuia normal, ne cere datele de intrare, iar dup ce le introducem consola se blocheaz. n acel moment ne ntoarcem n Visual Studio i observm c aranjamentul ferestrelor s-a schimbat, iar n dreptul primului breakpoint a aprut o sgeat (vezi figura 1.12):
Fig. 1.12 Oprirea execuiei la un breakpoint
Sgeata indic instruciunea la care s-a oprit execuia programului. Atenie! Instruciunea la care se afl sgeata nc nu s-a executat, dar instruciunea anterioar a fost executat! n acest moment, putem s vizualizm valorile unor variabile din program. n mod evident, ne va interesa valoarea celor dou variabile definite n main: n i vsiruri. Pentru a le vizualiza, mergem n meniul principal Debug Windows Watch Watch 1. n partea de jos a mediului de dezvoltare, apare fereastra Watch 1 (vezi figura 1.13). n aceast fereastr, dm click pe coloana Name i introducem numele variabilelor pe care dorim s le vizualizm nti n, apsm ENTER, pe urm vsiruri, apsnd din nou ENTER:
Fig. 1.13 Fereastra Watch
n a doua coloan (Value), va fi afiat valoarea variabilelor la acel moment al execuiei programului, iar n cea de-a treia coloan (Type), tipul acestora. La variabila n, valoarea este un numr pe care l putem vedea. ns la variabila de tip pointer la pointer,vsiruri, IDE-ul afieaz valoarea acesteia ntr-o form care nu ne este aa de util. Fereastra Watch ne permite s vizualizm nu doar variabile, ci i orice expresie. De exemplu, putem s vizualizm elementele vectorului vsiruri, pe care mediul de dezvoltare le afieaz ntr-o form mai relevant pentru programator (vezi figura 1.14):
Fig. 1.14 Vizualizarea elementelor unui vector
Observm c de data aceasta fiecare ir de caractere este afiat corect i putem vedea coninutul lui. Citirea s-a fcut aa cum ne ateptam. Pn n acest punct programul se execut corect. Apsm tasta F5 pentru a continua execuia programului pn la urmtorul breakpoint. Vom vedea urmtoarele (vezi figura 1.15):
Fig. 1.15 Breakpoint dup sortare
Ordinea elementelor n vsiruri s-a schimbat i acum, elementele sunt sortate cresctor, aa cum ne aeptam. Unele dintre elementele schimbate sunt afiate cu rou. Att citirea ct i sortarea sunt corecte. Mai apsm odat F5 pentru a rula programul pn la sfrit. Executia ajunge la instruciunea _getch() care ateapt apsarea unei taste. Se va activa fereastra consol. n consol, apsm o tasta i programul se termin. Explorai meniul Debug n timp ce v aflai ntr-un breakpoint pentru a afla i alte faciliti de debug.
Mai jos sunt prezentate combinaii de taste utile n Visual Studio 2008. Combinatia de taste Efect Ctrl + C Copy - copiere Ctrl + V Paste - afiare Ctrl + A Select all selectare total Ctrl + K, F Format selected formatare selecie Ctrl + A, K, F Format all formatare total Ctrl + Shift + B Build all compilare proiect F5 Debug, continue after breakpoint Intrare n depanare sau continuarea execuiei dup breakpoint F9 Insert / remove breakpoint Adugarea / eliminare breakpoint 9. Documentaie
Sursa recomandat pentru documentare este situl http://www.cplusplus.com/ . n particular, sunt recomandate urmtoarele link-uri: http://www.cplusplus.com/reference/clibrary/ unde putem gsi documentaia complet a tuturor fiierelor de bibliotec din C i a funciilor din acestea. Documentaia este similar cu cea din Borland C. http://www.cplusplus.com/reference/iostream/unde putem gsi documentaia claselor ce realizeaz operaii de intrare/ieire (intrare/ieire standard cin, cout i fiiere). http://www.cplusplus.com/doc/tutorial/ unde putem gsi un material didactic alternativ despre limbajul C++. 10. Exerciii
1. Creai un nou proiect care s conin programul prezentat n seciunea 7. 2. Compilai i rulai programul de la exerciiul 1. 3. Executai pas cu pas programul. 4. Introducei n mod intenionat o eroare n program, comentnd linia: suntPerm = 1; din funcia sortareVSiruri() . Plasai dou breakpoint-uri conform indicaiilor din sectiunea 8. Testai programul cu o intrare de cinci iruri i verificai dac la al doilea breakpoint irurile sunt sau nu sunt sortate corect. 5. ncerci s detectai eroarea, presupunnd c nu tii unde este. Localizai prima linie de cod care se execut dup ce se detecteaz c dou iruri trebuie inversate. Introducei un breakpoint pe acea linie. Vizualizai toate variabilele locale i cele dou iruri care urmeaz s fie inversate. Ce expresii vei introduce n fereastra Watch pentru cele dou iruri? De cte ori ar trebui s se realizeze inversarea irurilor i de cte ori are loc n realitate? Ce putei spune despre comportamentul programului? 6. Introducei un breakpoint pe linia while i demonstrai cu ajutorul lui c bucla while se execut doar o dat n programul eronat. 7. Corectai eroarea n program. Numrai de cte ori se execut bucla while i de cte ori are loc inversarea a dou iruri consecutive n funcia de sortare.