Sunteți pe pagina 1din 12

PROGRAMAREA ORIENTATĂ PE OBIECTE - Laborator

Lucrarea de laborator 1.

1. SCRIEREA PROGRAMELOR C++ ÎN MICROSOFT VISUAL STUDIO 2008


Visual Studio 2008 este mediul de dezvoltare integrat ce se va folosi pentru scrierea programelor C++.
El permite dezvoltarea de aplicaţii î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ă creăm un proiect.

Pentru a crea un proiect:


1. Pornim VS2008
2. În meniul principal, mergem la FILE → NEW → PROJECT… ca în figură:

Fig. 1 Creare proiect nou

3. În fereastra New Project, în stânga avem căsuţa Project types. Alegem VISUAL C++ iar în
căsuţa Templates din partea dreaptă, selectăm WIN32 CONSOLE APPLICATION.
PROGRAMAREA ORIENTATĂ PE OBIECTE - Laborator

Fig. 2 Fereastra New Project

4. În partea de jos avem căsuţele Name şi Location ce trebuie completate. Alegem un nume
pentru proiect. La Location selectăm un director creat de noi în D:/PG/ (vezi fig. 2)
5. Apăsăm OK.
6. Apare fereastra “WELCOME TO THE WIN32 APPLICATION WIZARD”. Apăsăm
NEXT, NU Finish!
PROGRAMAREA ORIENTATĂ PE OBIECTE - Laborator

Fig. 3 Welcome to the win32 application wizard

Fig. 4 Fereastra Application Settings


PROGRAMAREA ORIENTATĂ PE OBIECTE - Laborator

7. În fereastra apărută, rubrica ADDITIONAL OPTIONS, bifam “EMPTY PROJECT”.


Lăsăm celelalte setări neschimbate:
8. Apăsăm FINISH.

Proiectul este creat şi deschis în VS. Ar trebui să vedem următoarele ferestre:


 Solution explorer – în partea stânga. De aici se pot crea sau deschide fișierele proiectului.
Iniţial proiectul nu conţine nici un fişier.
 Start Page – în restul ecranului. Nu ne este de mare folos, putem să o închidem.

Mediul de dezvoltare va arăta în felul următor:

Fig. 5 Fereastra proiectului creat lab1

2. ADĂUGAREA UNUI FIȘIER LA PROIECT


Ca să putem scrie cel mai simplu program în VS2008, trebuie să adăugam un fişier sursă. Pentru
aceasta va trebui să urmăm următorii pași:
1. În SOLUTION EXPLORER, click dreapta peste grupul SOURCE FILESS și selectăm ADD
și apoi NEW ITEM și se va deschide o nouă fereastră.
PROGRAMAREA ORIENTATĂ PE OBIECTE - Laborator

Fig. 6 Adăugare fişier sursă


2. Apare fereastra “ADD NEW ITEM”.
3. În căsuţa templates alegem C++ FILE (.CPP)
4. La name alegem numele fişierului. De obicei vom numi fişierul care conţine funcţia main()
după regula <numeProiect>Main. În cazul nostru – salutMain:

Fig. 7 Fereastra “ADD NEW ITEM”


PROGRAMAREA ORIENTATĂ PE OBIECTE - Laborator

5. Apăsăm ADD. Noul fişier este creat şi deschis în editor.

3. SCRIEREA PRIMULUI PROGRAM


Se va scrie un program simplu care afişează un mesaj la consolă, după care aşteaptă apăsarea unei
taste:

Fig. 8 Scrierea codului sursă

Observăm în dreptul numelui fişierului – lab1.cpp că inițial apare o steluţă (*). Aceast lucru
specifică că fişierul conţine modificări nesalvate. Liniile modificate sunt marcate cu galben în stânga
editorului. Apăsăm Ctrl+S pentru a salva fişierul. Observăm cum steluţa a dispărut.
Funcţia _getch() la sfârşitul programului este echivalentul lui getch() din Borland C++. Ea
aşteaptă apăsarea unei taste fără să o afişeze pe ecran.
În Visual Studio codul este identat în mod automat atunci când îl scriem. Chiar dacă programul
nu este identat aşa cum ne dorim, putem să reformatăm codul în orice moment apăsând Ctrl+A, apoi
Ctrl +K, Ctrl +F. Este o practică bună să avem codul tot timpul formatat. Formatarea ne ajută să
înţelegem programul şi să detectăm mai uşor erorile.
4. COMPILAREA ȘI RULAREA PROIECTULUI. DETECTAREA ERORILOR.
Pentru a compila proiectul apăsăm Ctrl + Shift + B, sau din meniul principal selectăm BUILD →
BUILD SOLUTION.
Dacă sunt detectate erori de compilare, în partea de jos a ecranului va apărea fereastra Error List. Să
introducem intenţionat o eroare pentru a vedea facilităţile acestei ferestre.
PROGRAMAREA ORIENTATĂ PE OBIECTE - Laborator

De exemplu, putem înlocui linia “return 0” cu “return x”. La compilare, compilatorul consideră că x
este o variabilă nedefinită şi afişează fereastra error list.
Dacă dam dublu-click peste mesajul de eroare, cursorul se va deplasa la linia de cod conținând
eroarea. Utilizarea unei variabile fără să fie declarată este una din cele mai comune erori de
programare. În VS2008 aceasta poate fi detectată şi corectată foarte uşor. Alte erori însa pot duce la
mesaje de eroare mult mai obscure şi chiar linia de cod a erorii poate fi detectată greşit.
In general s-a observat următoarea regulă – eroarea trebuie căutată ori pe linia afişata în error list,
ori cu o linie mai sus. De exemplu, ștergeți simbolul ; la sfârşitul uneia dintre linii. Veţi vedea că
mesajul de eroare ne duce cu o linie mai jos.
Chiar dacă fereastra error list nu s-a ridicat după compilare, trebuie să o verificăm, pentru că
aceasta nu se ridică atunci când programul are doar warning-uri. De cele mai multe ori warning-urile
sunt şi ele erori de program.

Pentru a putea folosi funcțiile cunoscute din limbajul C fără warning-uri inutile se va utiliza o
directivă specifică Visual Studio, care dezactivează warning-urile cu codul 4996. Aceasta este:

#pragma warning(disable : 4996)

Pentru a executa programul se apasă F5, deschizându-se o fereastră – consola în care rulează
programul. Dacă informația din această fereastră nu se vede bine se poate face clic dreapta cu mous-ul
pe bara de sus a ferestrei și se selectează Properties.

Fig.9 Fereastra Properties.

Selectând Properties putem stabili tipul de font, mărime, culoare fundal, etc.
PROGRAMAREA ORIENTATĂ PE OBIECTE - Laborator

Fig. 10 Opțiuni fereastra Properties.

SISTEMUL DE INTRARI/IESIRI DE BAZA DIN C++

În C++ între intrările şi ieşirile fizice se interpun zone tampon organizate sub forma unor clase
ierarhizate, aceste zone tampon se numesc streamuri. Spre deosebire de zonele tampon din C care erau
doar nişte locaţii de memorie asupra cărora acţionau o serie de funcţii în mod explicit sau implicit
(printf, scanf) în C++ acestea au devenit clase, având asociate şi doi operatori unul de inserţie (<<) şi
altul de extracţie (>>) care pot fi supraîncărcaţi.
În principiu sunt definite 4 streamuri standard:
cin - pentru intrări standard de la Tastatură;
cout – pentru ieşiri standard spre display (sau fereastră);
cerr – pentru ieşiri standard de eroare spre display;
clog – ieşirile de eroare sunt păstrate trec printr-o memorie tampon înainte de ajunge la
display;
Variabilele cin şi cout sunt definite în header-ul <iostream>. Pentru ca să le putem folosi,
trebuie să includem la începutul programului următoarele linii în fișierul sursă din Visual C++ 2008:

#include <iostream>
using namespace std;
PROGRAMAREA ORIENTATĂ PE OBIECTE - Laborator

Toate elementele bibliotecii standard C++ sunt declarate în ceea ce se numește namespace-ul cu
numele std. Pentru a accesa funcționalitățile acestei blibioteci, trebuie să utilizăm această instrucțiune.
Avantajul utilizării streamurilor este folosirea directă fără specificări sau configurări speciale
luându-se în acest caz setările implicite sau setări făcute anterior. Deşi atunci când se va dori o anumită
formatare se va apela la funcţii şi constante suplimentare spre deosebire de printf şi scanf aceste
formatari se vor păstra, astfel dacă se doreşte ca afişările de la un punct la alt punct al programului să se
facă cu aceeaşi formatare se va specifica formatarea o singura data, apoi aceasta păstrându-se.
Pentru a afişa nişte variabile,constante, şiruri de caractere pe ecran vom scrie:
cout<<v1<<v2<<k1<<”abcdefg”<<’a’<<’*’;

Se vor afişa una după alta fără spaţii între ele valoare lui v1, a lui v2 a constantei k1, şirul de
caractere dintre ghilimele, caracterul ‘a’ şi ’*’.
Pentru a citi o variabilă sau un şir de caractere vom scrie:
int a;
char s[100];
cin>>a;
cin>>s;
sau …
cin>>a>>s;

Se observă că săgeţile indică întotdeauna sensul de deplasare a informaţiei la cout toate


informaţiile se deplasează dinspre variabile spre stream, pe când la cin dinspre stream spre variabile.

Exerciţiu 1:
Citiţi trei valori float, calculaţi media lor şi afişaţi-o.

Formatarea streamurilor
Formatarea afişărilor şi intrărilor se poate face cu o serie de indicatori de format şi o serie de
funcţii prin care se activează aceşti indicatori.
Indicatorii de format sunt efectiv valori întregi pe 16 biţi. Aceste valori în format binar au doar
un singur bit setat, permiţând astfel implementarea a 16 indicatori maxim pe acest principiu. Ca tip de
date aceşti indicatori sunt definiţi ca enumerare.
Aceştia sunt definiţi astfel:
Enum{ skipws=0x0001, left=0x0002, right=0x0004, internal=0x0008,
dec=0x0010, oct=0x0020, hex=0x0040,showbase=0x0080,
showpoint=0x0100, uppercase=0x0200, showpos=0x0400,
scientific=0x800,fixed=0x1000,unitbuf=0x2000
};
Pentru setarea acestor indicatori se foloseşte funcţia membru setf(indicator),
Pentru resetarea lor se foloseşte funcţia unsetf(indicator).
Pentru a seta indicatorul hex scriem:
stream.setf (ios::hex);

unde stream poate fi cin sau cout.


Pentru a seta mai mulţi indicatori vom folosi următoare secvenţă de cod:
stream.setf(ios::ind1| ios::ind2 | ios::ind3 | …. ios ::indn) ;
Pentru a reseta indicatorii de format ai unui stream folosim aceleaşi expresii dar în loc de setf
vom scrie unsetf.
PROGRAMAREA ORIENTATĂ PE OBIECTE - Laborator

Semnificaţiile indicatorilor de format:


- skipws – la citirea unui şir de caractere nu ia în considerare spaţiile goale (spaţii şi
tabulatori);
Exemplu:
char s[100];
cin.setf(ios::skipws);
cin>>s;
cout<<s;

- left – alinează afişarea pe ecran la stânga; ( abc______)


- right – alinează afişarea pe ecran la dreapta;(______abc)
- internal – alinează semnul valorii la stânga;(-_____123)
- dec – specifică că streamul va lucra cu valori în baza 10;
- oct – specifică că streamul va lucra cu valori în baza 8;
- hex – specifică că streamul va lucra cu valori în baza 16;
- showbase –specifică că se va afişa baza de numeraţie în care se lucrează ( 0__ pentru octal,
0x__ pentru hexazecimal, fără nici o specificaţie pentru zecimal);
- showpoint – arată punctul zecimal pentru valori reale chiar şi atunci când nu au zecimale
diferite de zero (1234.0000)
- uppercase – arată notaţia bazelor cu literă mare şi pentru baza 16 toate cifrele literare
(a,b,c,d,e,f) vor fi scrise cu literă mare;(FFB9)
- showpos – dispune în faţa valorilor pozitive semnul +. ( +1234);
- scientific – valorile reale vor fi afişate în notaţie ştiinţifică (1.234e+03);
- fixed – valorile reale vor fi afişate în notaţie cu virgulă, opţiune ce este implicită;
- unitbuf – se golesţe memoria tampon asociată streamurilor după fiecare operaţie de ieşire;

Funcția setf() cu un singur argument este utilizata pentru activarea unuia sau mai multor
indicatori de formatare. Fiind o funcție membra a clasei ios, ea trebuie sa fie apelata pentru un anumit
obiect (stream), ceea ce înseamnă ca nu exista o stare globala de formatare, ci fiecare stream are
propria lui stare. Indicatorii de formatare pot fi modificați individual, prin apeluri separate ale functiei
setf() sau grupati intr-o expresie logica OR (SAU). De exemplu, instructiunile: cout.setf(ios::hex);
cout.setf(ios::showbase); sunt echivalente cu instructiunea: cout.setf(ios::hex | ios::showbase); si au ca
efect afisarea unui numar in format hexazecimal, cu reprezentarea explicita a bazei folosite. Dupa o
astfel de formatare, instructiunea: cout << 100; va afisa la consola: 0x64.
Dat fiind ca indicatorii de formatare sunt definiti in interiorul clasei ios, pentru a avea acces la valorile
lor, acestia trebuie sa fie insotiti de specificarea domeniului clasei ios (de exemplu, ios::hex).
Functia setf() cu doua argumente este o forma supraincarcata care permite modificarea acelor stari care
sunt reprezentate prin campuri compuse din mai multi biti. De exemplu, baza numerica de afisare
implica un camp format din trei biti (dec, oct si hex) din care numai unul poate fi setat la un moment
dat. Pentru o astfel de setare se apeleaza functia setf() avand ca prim argument (setbits) indicatorul care
trebuie sa fie setat, al doilea fiind un pseudoargument (field), care defineste campul celui dintai.
Pseudoargumentele definite in clasa ios sunt: ios::basefield (pentru baza de numeratie, format din bitii
dec, oct, hex), ios::adjustfield (pentru campul de aliniere format din bitii left si right) si ios::floatfield
(pentru campul de afisare a numerelor cu virgula mobila, format din bitii scientific si fixed).
De exemplu, fiecare din instructiunile:
cout.setf(ios::oct, ios::basefield); // octal cout.setf(ios::dec, ios::basefield); // zecimal cout.setf(ios::hex,
ios::basefield); // hexazecimal
seteaza baza de numeratie fara efecte asupra altor parti ale starii streamului.
PROGRAMAREA ORIENTATĂ PE OBIECTE - Laborator

Functia unsetf() este complementara functiei setf() si are ca efect stergerea unuia sau mai multor
indicatori de format. Functia unset() opereaza intr-un mod asemanator cu functia setf().

Exerciţiu 2.

Să se citească un număr întreg în baza 16 şi să se afişeze valoare citită în baza 10 și în


baza 8.

Exerciţiu 3.

Să se citească o valoare float şi să se afişeze fără punctul zecimal.(dacă valoarea nu are


zecimale), altădată să se afişeze în notaţie ştiinţifică, şi mai apoi în notaţie fixă.
Alte funcţii membre ale streamurilor: flags(), width(), precision(), fill()
Pentru a citi sau a scrie valorile tuturor indicatorilor de formatare se va folosi funcţia flags().
Exemplu:
long a;
a=flags(); // am citit toate valorile
flags(a); // am suprascris toate valorile

Pentru a specifica lungimea minima a spaţiului(câmpului) de afişare a unei variabile, şir de


caractere sau constante se foloseşte funcţia width() având prototipul:
int width(int dimensiune_camp);
Pentru a specifica precizia(numărul de zecimale) cu care va fi afişat un număr real se fa folosi
funcţia membru precision() având prototipul:
int precision(int nr_de_zecimal);
Pentru a specifica caracterul cu care se umple spaţiile libere ale unui câmp când informaţia
efectivă afişată ocupă mai puţin decât lărgimea câmpului se foloseşte fill() având prototipul:

char fill(char noul_caracter_de_umplere);


// funcţia va returna caracterul de umplere anterior

Exemplu:
#include <iostream>
#include <conio.h>
#include <iomanip>
using namespace std;
#pragma warning(disable : 4996)
void main() {
cout.width(10); //latimea câmpului de 10
cout <<"salut" << "\n";
cout.width(10);
cout.fill('_');
cout << "salut" << "\n";
// utilizare manipulatori
cout<<setw(15)<<setfill('*')<<"Salut"<<hex<<" "<<24<<endl;
cout.setf(ios :: left);
PROGRAMAREA ORIENTATĂ PE OBIECTE - Laborator

cout.width(10);
cout << "salut" << "\n";
cout <<123.234567 << "\n";
cout.width (10);
cout.precision(8);
cout << 123.234567 << "\n";
}

Exerciţiu 4.

Să se afişeze pe câte un rând valoare radicalului primelor 15 numere începând cu 2. Valoarea va


fi afişată cu 7 zecimale. Pe prima coloană se va afişa numărul, pe cea de-a doua radicalul său. Fiecare
câmp va avea o lărgime de 20 de caractere iar valorile vor fi alineate la dreapta.(Ca în figura de mai
jos.)
Pentru a calcula radicalul se va include biblioteca math.h şi din această bibliotecă se va folosi
funcţia sqrt(), care acceptă variabile tipul foat, double sau long double. Pentru linie nouă se va folosi
caracterul `\n`) Este setarea făcută cu funcţia width() permanentă?