Sunteți pe pagina 1din 11

PRELEGERE XIV

PROGRAMAREA CALCULATOARELOR ŞI LIMBAJE DE PROGRAMARE

Elemente de grafică în C
I. Moduri video
Un număr ridicat de funcţii predefinite video din fişierul antet conio.h şi din biblioteca
graphics.lib definesc posibilităţi semnificative pentru utilizarea ecranului în cercetare şi
proiectare, în prognozare sau chiar în scopuri comerciale, sub forma clipurilor. În funcţie
de destinaţia lor, acestea pot fi împărţite în mai multe categorii, astfel: iniţializare şi
instalare mod grafic, tratare erori grafice, desenare linii, trasare cercuri, arcuri şi alte
curbe, desenare poligoane şi haşurări, desenare puncte, scriere texte grafice, salvare
imagini, definire culori şi definire şi utilizare de ferestre şi de pagini.
Pe de o parte, în configuraţiile hardware ale calculatoarelor compatibile IBM PC intervin
monitoare de diverse tipuri (monocolor, color sau color extins), iar pe de alta,
comunicarea dintre microprocesorul şi monitorul unui calculator nu se face direct, ci prin
intermediul memoriei video (memoriei ecran), care se află pe placa adaptorului video
(adaptorului grafic), aşa numita placă video (placă grafică, cartelă video, cartelă grafică).
Un program de interfaţă (un driver grafic) cu extensia .BGI (Borland Graphics Interface),
specific adaptorului folosit, permite controlul interfeţei între funcţiile video prin care
microprocesorul depune în memoria video semnale care reprezintă texte şi imagini şi
facilităţile oferite de adaptorul grafic, prin care monitorul îşi extrage continuu date din
memoria video şi le trimite pe ecran.
Dintre cele mai des întîlnite adaptoare video se enumeră: CGA (Color Graphics
Adapter), MCGA ( MultiColor Graphics Adapter), EGA (Enhanced Graphics Adapter),
EGA64, EGAMono, IBM8514, HGA (Hercules Graphics Adapter), ATT, VGA (Video
graphics Array) şi PC3270. Aproape toate adaptoarele grafice pot fi comutate în modurile
Hercules, VGA şi EGA, care este şi cel mai vechi. Spre exemplu, adaptoarele grafice
EGA şi VGA sînt controlate de driver-ul egavga.bgi. Pentru adaptorul color adresa
de început a memoriei ecran este la 0xB800:0, iar pentru cel monocolor la 0xB000:0.
Programul 14.1.1 interoghează calculatorul asupra tipului adaptorului video. Rezultatul
furnizat a fost adresa 0xB800, adică calculatorul pe care s-a rulat acest program are un
adaptor video color.
#include <stdio.h>
#include <conio.h>
#include <graphics.h>
#include <stdlib.h>
int placa(void)
void main()
{ long incepecran;
clrscr();
placa;
printf("incepecran = %0x", incepecran);
getch(); }
int placa(void);
int driver, modus;

1
driver=DETECT;
detectgrapf(driver, modus);
printf("Driver-ul grafic are numarul:%d", driver);
switch (driver)
{ case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 8:
case 9: incepecran = 0xb800;
break;
case -2:
case 7:
case 10: incepecran = 0xb000;
break;
}
return incepecran; }
Programul 14.1.1

Densitatea punctelor care alcătuiesc imaginea (rezoluţia) şi numărul maxim de


culori (paleta de culori) permise pe ecranul monitorului sînt două caracteristici
importante care rezultă din legătura monitor – adaptor şi care determină modul de operare
al adaptoarele video, modul text sau modul grafic. Fiecărui driver îi corespunde cel
puţin un mod grafic, prin care se precizează rezoluţia şi paleta de culori. Acestea pot fi
aflate din tabele sau prin interogarea calculatorului.
În modul text ecranul este gîndit ca o matrice (25, 43 sau 50 linii şi 80 sau 40
coloane) ale cărei elemente sîn caractere ASCII. Colţul din stînga sus are
coordonatele (1,1). Pentru o poziţie oarecare (x, y), abscisa x creşte de la stînga către
dreapta şi fixează coloana, iar ordonata y de sus în jos şi fixează linia. În memoria video
se rezervă doi octeţi pentru fiecare poziţie din matrice, primul octet conţine codul ASCII
al caracterului care ocupă acea poziţie, iar al doilea este octetul atribut, care determină
modul de reprezentare al caracterului: normal sau intens luminat, cu subliniere sau
clipitor (blinking), iar pentru monitoarele color, care este culoarea fundalului şi care cea a
textului. În mod normal, pagina de ecran conţine 25 de rînduri a cîte 80 de coloane,
deci colţul din stînga sus este (1, 1), iar colţul din dreapta jos (80, 25). Ceea ce rezultă că
în modul text sînt necesari 2000 de octeţi carcter şi 2000 de octeţi atribut, deci în total
4000 de octeţi.
În modul grafic, ecranul este descris tot ca o matrice ale cărei elemnte sînt
puncte individuale, numite pixeli. Colţul din stînga sus are coordonatele (0,0). Un
număr de 8 pixeli pot fi trataţi ca un octet, unde un bit setat înseamnă pixel luminos,
iar unul şters pixel întunecat. Imaginea pe ecran este o mulţime de pixeli luminoşi şi
coloraţi într-un anume fel. De exemplu, pentru Hercules pagina de ecran cuprinde 348
de rînduri, iar un rînd are 720 de pixeli, (în mod echivalent, 90 de octeţi). Ceea ce

2
înseamnă că este nevoie de multă memorie, adică 348x90=31320 octeţi sau 32ko per
pagina de ecran. Înălţimea unui rînd de ecran este de un pixel, pe cînd în modul text este
de 8 sau 9 pixele. Grafica în culori, în schimb, necesită mai multă memorie. Cu un bit de
pixel pot fi reprezentate maxim două culori, cu doi biţi de pixeli cel mult patru culori,
numărul biţilor crescînd rapid în funcţie de numărul culorilor folosite. Zona de memorie
necesară se alocă din RAM-ul adaptorului grafic, deoarece în memoria ecran operativă au
loc doar două pagini de ecran la adresele 0xB000:0 şi respectiv 0xB800:0. De exemplu,
codificarea numerică a paletei de culori implicită pentru VGA: black, blue, green, cyan,
red, magenta, brown, white, gray, light_blue, light_green, light_cyan, light_red,
light_magenta, yellow, light_white, în ordine, este precizată în lista (0, 1, 2, 3, 4, 5, 20, 7,
56, 57, 58, 59, 60, 61, 62, 63). Culoarea de fond (background) este 0, iar culoare cernelii
(foreground) este 63. Indicele culorii din paletă se denumeşte prin valoare pixel.
Un concept comun celor două stiluri de lucru îl reprezintă fereastra, care se
defineşte prin porţiunea rectangulară de ecran activă la un moment dat. Fereastra poartă
denumirea de window pentru modul grafic şi viewport pentru modul grafic. Fereasatra
implicită se consideră întreg ecranul. Scrierea textelor sau desenarea imaginilor se face
în fereastra curentă, restul ecranului rămînînd nefolosit. Conţinutul ecranului se poate
organiza pe mai multe pagini de ecran complete sau numai pe porţiuni de ecran, care pot
fi salvate temporar în memoria RAM şi care pot fi apelate succesiv într-un timp scurt,
încît să nu se obsrve trecerea de la o pagină la alta.
Placa video şi monitorul pot fi trecute automat la oricare mod în care a fost
realizat programul (modul text fiind implicit), atît la nivel PC/MS-DOS prin intermediul
funcţiilor realizate de programator, cît şi la nivel DOS SHELL cu ajutorul funcţiilor
predefinite video. Modul grafic de lucru, controlul memoriei video, utilizarea culorilor în
programe BIOS sau controlul aprinderii şi stingerii cursorului, cu toate că necesită un
efort şi cunoştinţe desebite, vor constitui, în cele ce urmează, subiectul unor programe
interesante.

II. Modul text


Modul grafic original de lucru al calculatorului la lansarea în execuţie a unui program
este modul text. Funcţiile predefinite aplicabile lucrului în modul text oferă facilităţi
pentru controlul ferestrei, scrierea şi modificarea textului cu anumite atibute de culoare,
sublinierea şi clipirea unor caractere sau deplasarea, stingerea şi aprinderea cursorului.
Aceste funcţii sînt grupate în biblioteca standard şi în plus, pentru fiecare model de
memorie există versiuni distincte pentru biblioteca standard.

III. Comutarea în modul text


Prototipul funcţiei pentru precizarea modului text de lucru este:
void textmode( int mod_lucru);.
Argumentul mod_lucru se stabileşte, în funcţie de tipul adaptorului grafic şi tipul
monitorului cu care este dotat calculatorul, conform tabelului următor:
În absenţa argumentului mod_lucru, se subînţeleg parametrii impliciţi ai modului text,
adică fereastra activă este tot ecranul, iar afişarea textului se face cu cerneală albă pe fond
negru. Comutarea pe modul de lucru anterior, dacă în timpul execuţiei programului s-a
schimbat modul de lucru, se face activînd textmode(LASTMODE);. Cu apelările

3
textmode(BW80); şi textmode(2); se descriu rezultate egale, adică un mod text cu 25 de
rînduri, 80 de coloane şi afişarea textului în nuanţe de gri.
Denumire simbolică Codul Caracteristici

BW40 0 40 x 25 negru/alb pe adaptor color


BW80 2 80 x 25 negru/alb pe adaptor color
MONO 7 80 x 25 negru/alb pe adaptor monocolor
40 x 25 color pe adaptor color
CO40 1 80 x 25 color pe adaptor color
CO80 3 Modul precedent
LASTMODE -1
Tabelul 14.3.1

IV. Funcţii de intrare/ieşire pentru modul text


Biblioteca standard Turbo C++, spre deosebire de cea din C, oferă pentru modul text un
ansamblu de funcţii video şi flag-uri (indicatori binari), declarat în conio.h, prin care se
realizează operaţii de intrare/ieşire la consolă sub anumite condiţii.
Controlul umplerii ferestrei active se efecuează prin setarea flag-ului _wscroll, care este o
variabilă globală, pe o valoare întreagă, astfel:
- cu 0 se continuă afişarea textului de la începutul liniei curente, fără saltul la linia
următoare;
- cu 1 (valoare implicită), atingerea limitei din dreapta a ferestrei determină
continuarea scrierii textului pe linia următoare începînd cu limita dinspre stînga a
ferestrei, prin derularea în jos (pe verticală) a textului pentru a face loc noii linii şi dacă
este cazul cu ieşirea ultimei linii de pe ecran.
Alegerea modului de scriere pe ecran se deduce din valoarea variabilei globale
directvideo:
- cu 0 scrierea se face prin folosirea funcţiilor sistemului de operare (BIOS);
- cu 1 (valoare implicită) scrierea se face direct în memoria video. Setarea
variabilei direcvideo pe valoarea implicită impune o creştere substanţială a vitezei de
scriere pe ecran.
Nu sînt schimbări esenţiale, în ceea ce priveşte prototipul, absenţa sau prezenţa
formatării datelor pe ecran şi modul de efectuare a operaţiilor de citire/scriere, la funcţiile
descrise în acest paragraf faţă de cele descrise în paragrafele 5.2.1 – 5.2.4. Numai că orice
secvenţă ‘\n’ din şirul de formatare, care descrie saltul la începutul liniei următoare,
trebuie să se înlocuiască prin ‘\r\n’.
Returnarea caracterului citit de la tastatură, cu sau fără ecou pe ecran, se descrie
prin funcţiile int getche(void); şi respectiv int getch(void);. Tipărirea unui caracter c în
fereastra curentă se face cu funcţia: int putch(c);. În caz de eroare, funcţia întoarce
EOF.
În mod corespunzător, pentru citirea/scrierea unui şir de caractere se folosesc
următoarele: char *cgets(char *s); şi respectiv char *cputs(const char *s);.
Cu funcţia cgets() se citeşte şirul de caractere afişat în fereastra curentă pînă la întîlnirea
secvenţei ‘\r\n’ sau pînă la satisfacerea lungimii maxime declarate, se depozitează şirul
citit la adresa s[2] şi se înscrie marcatorul de sfîrşit de şir de caractere, ‘\0’. La adresa s[1]
se memorează numărul efectiv de caractere citite, care poate să fie cel mult egal cu

4
lungimea declarată a şirului de caractere. Lungimea maximă a şirului se înscrie la adresa
s[0] înainte de activarea funcţiei cgets(). Deci, dimensiunea şirului de caractere s[] trebuie
declarată cu trei octeţi mai mare decît lungimea maximă a acestuia. Rezultatul întors de
funcţie este adresa şirului de caractere, adică s+2.
La scriere, spre deosebire de funcţia puts(), nu se sare la linie nouă la întîlnirea secvenţei
‘\r\n’.
Formatarea datelor editate în fereastra curentă, la citire, se realizează cu funcţia cscanf(),
care are prototipul următor:
int cscanf(char *şir_de_formatare [, lista_adrese_variabile]);. În mod similar,
pentru scriere se uitlizează funcţia:
int cprintf(const char * şir_de_formatare, listă_valori_ieşire);.

V. Mutarea cursorului şi a textului


Pentru mutarea unei porţiuni de ecran se foloseşte funcţia:
int movetext(int x1, int y1, int x2, int y2, int x_stînga, int y_dreapta);.
Porţiunea dreptunghiulară de text delimitatată de colţul din stînga sus (x1, y1) şi colţul
din dreapta jos (x2, y2) se copie începînd cu poziţia de coordonate (x_stînga, y_dreapta),
care constituie colţul din stînga sus al dreptunghiului care urmează să-l ocupe textul.
Coordonatele sînt date în coloane – linii şi sînt suficiente pentru a delimita o porţiunea
dreptunghiulară, după cum se observă în următoarea schemă grafică:
(x1, y1)

(x2, y2)
Mutarea textului se face corect chiar dacă zonele sursă şi destinaţie se suprapun pe unele
porţiuni, coordonatele fiind relative la ecran, nu la fereastra curentă. Se semnalează
eroare dacă s-au precizat coordonate care nu se pot localiza în fereastra curentă. În
situaţia unui eşec funcţia returnează 0, altfel o valoare nenulă.
Schimbarea poziţiei cursorului pe suprafaţa ferestrei curente se realizează cu funcţia:
void gotoxy(int x, int y);. Se deplasează cursorul în poziţia de coordonate (x, y),
unde x este coloana, iar y linia. Activarea funcţiei nu are efect dacă una din coordonate
este în afara ferestrei curente.
Pentru aflarea coordonatelor poziţiei curente a cursorului sănt disponibile funcţiile int
wherex(void); şi int wherex(void);.

VI. Modificarea textului


Inserarea unei linii noi în poziţia marcată de cursor se descrie prin funcţia: void
insline(void);. Liniile situate dedesubtul cursorului vor defila în jos cu o linie şi dacă este
cazul ultima linie iese de pe ecran.
Pentru şteregerea unei linii de ecran este disponibilă funcţia:
void delline(void);. Se şterge linia marcată de cursor, coloana neavînd nici o
importanţă. Liniile următoare din fereastra curentă sînt deplasate în sus cu un rînd.
Pentru ştergerea unei porţiunii dintr-o linie se utilizează funcţia:
void clreol(void);. Se şterg taoate caracterele din dreapta cursorului în linia
marcată de cursor. Poziţia cursorului rămîne neschimbată.

5
Ştergerea completă a informaţiilor existente în fereastra activă cu deplasarea cursorului în
colţul din stînga sus (1, 1) se face cu funcţia: void clrscr();. Funcţia clrscr() nu
absentează din programele prezentate în această lucrare.

VII. Gestiunea ferestrelor


Deschiderea unei ferestre în care să se aranjeze date de diverse tipuri conform
necesităţilor programatorului, fără să se ocupe întreg ecranul, se produce cu funcţia:
void window(int x1, int y1, int x2, int y2);. Colţul din stînga sus al noii ferestre deschisă
este (x1, y1), iar colţul din dreapta jos este (x2, y2). În mod normal, fereastra principală
poate fi descrisă prin window(1, 1, 80, 25);. Fereastra minimă care se poate deschide este
de o linie şi de o coloană. Prin tragere, ferestrele pot fi mutate oriunde pe suprafaţa
ecranului sau se pot suprapune. Dacă una din coordonate este necorespunzătoare, atunci
apelul funcţiei are efect nul.
Din acest moment coordonatele vehiculate prin program vor fi relative la freastra curentă
nou delimitată şi nu la întreg ecranul. De aceea, aflarea parametrilor caracteristici ai
ferestrei curente are importanţă pentru stabilirea poziţiei curente a cursorului sau pentru
adaptarea funcţiilor şi prelucrărilor ulterioare la noile condiţii de lucru.
Funcţia care permite citirea acestui set de parametri este:
void getextinfo(struct text_info *dw);.

VIII. Atribute de ecran


Am văzut că fiecare caracter de text, care apare pe ecran, este caracterizat printr-un octet
de atribut, care se află în memoria de ecran, imediat după octetul de caracter. Deci, modul
în care caracterele apar pe ecran depinde de alegerea atributului curent. Octetul de
caracter are structura următoare: biţii: 7 6 5 4 3 2 1 0
bf ffic cc
unde, biţii: 0 – 2 descriu culoarea în care se afişează caracterul;
3 stabileşte intensitatea luminoasă: 1 = intensitate mare (culoare
deschisă), iar 0 = intensitate redusă (culoare închisă);
4 – 6 descriu culoare fondului;
7 stabileşte clipirea caracterului (blinking): 1 = cu clipire, iar 0 =
fără clipire. În monocrom se obţine: subliniere cu bitul 0, video invers cu biţii de text 0,
biţii de fond 1. Se adaugă că la utilizarea unui 0, bitul respectiv nu va fi setat. Un octet
atribut 0 realizează un caracter invizibil. Astfel, porţiuni de text pot să fie vizibile sau
invizibile, în funcţie de necesităţi.
Pentru stabilirea valorii octetului de atribut sînt disponibile funcţiile:
1) void textcolor(int culoare); precizează culoarea textului. Valorile posibile
sînt prezentate în tabelul 14.8.1.
Constante simbolice Culoare Codul
BLACK Negru 0
BLUE Albastru 1
GREEN Verde 2
CYAN Cyan 3
RED Roşu 4
MAGENTA Magenta 5
BROWN Maron 6

6
LIGHTGRAY Gri deschis 7
DARKGRAY Gri închis 8
LIGHTBLUE Albastru deschis 9
LIGHTGREEN Verde deschis 10
LIGHTCYAN Cyan deschis 11
LIGHTRED Roşu deschis 12
LIGHTMAGENTA Magenta deschis 13
YELLOW Galben 14
WHITE Alb 15
BLINK Clipitor 128
Tabelul 14.8.1
Pentru claritatea programului se recomandă utilizarea constantelor simbolice, care sînt cu
efect egal, aşa cum s-a precizat în exemplul de la sfîrşitul paragrafului 6.1.1.1. Spre
exemplu, cu apelul textcolor(LIGHTRED); se optează pentu textul ce urmează să se
scrie să aibă caractere roşu deschis.
2) void textbackground(int culoare); precizează culoarea fondului.
Numai primele 7 valori din tabelul 6.1.1.6.1 pot fi folosite pentru stabilirea culorii
fondului.
3) void normalvideo(void); selectează un mod de scriere normal, adică cel
existent valabil pînă la acest punct.
4) void lowvideo(void); selectează un mod de scriere mai puţin luminos, adică
bitul 3 va fi completat cu 0.
5) void highvideo(void); selectează un mod de scriere cu intensitate sporită, cu
alte cuvinte înscrie în bitul 3 valoarea 1.
6) void textattr(int atribut); modifică întreg octetul atribut. Prin operaţii de
mascare convenabile, cu operatorii logici binari & (conjuncţie) şi | (disjuncţie), se poate
modifica atributul după necesităţi. Spre exemplu, cu aplelul textattr(BLINK | RED * 16 |
WHITE); se va tipări un text roşu clipitor pe fond alb.
Trasarea unui cadru drepunghiular simplu, care poate fi completat eventual cu o
tabelă de meniu, se realizează cu funcţia cadru. Ca rezultat al celor 4 apelări în
programul 14.8.1, pe ecran se obţine o schemă grafică de genul:
roşu deschis

cyan
galben
#include <stdio.h>
#include <conio.h>
#include <graphics.h>
void cadru(int, int, int, int, int);
void main()
{ clrscr();
cadru(1, 2, 80, 5, 12);
cadru(1, 6, 80, 22, 14);
cadru(64, 8, 78, 10, 11);
cadru(67, 19, 78, 21, 11);
getch(); }

7
void cadru(int x1, int y1, int x2, int y2, int culoare)
{ unsigned char css=218, co=196, cds=191, cv=179, csj=192, cdj=217;
int i;
textcolor(culoare);
gotoxy(x1, y1); putch(css); /* Coltul stinga sus */
for( i = x1+1; i<=x2-1; ++i) putch(co); /* Linie orizontala superioara */
putch(cds); /* Coltul dreapta sus */
for( i = y1+1; i<=y2-1; ++i)
{ gotoxy(x1, i); putch(cv); /* Linie verticala stinga */
gotoxy(x2, i); putch(cv); /* Linie verticala dreapta */
}
gotoxy(x1, y2); putch(csj); /* Coltul stinga jos */
for( i = x1+1; i<=x2-1; ++i) putch(co); /* Linie orizontala inferioara */
_wscroll = 0;
putch(cdj); /* Coltul dreapta jos */
_wscroll = 1; getch(); }
Programul 14.8.1
În ultima parte a programului s-a impus anularea temporară a scrierii pe ecran cu “scroll”
pentru ca la trasarea colţului din dreapt jos să se împiedice saltul la linie nouă. În caz
contrar, s-ar pierde linia superioară din cadru prin derularea conţinutului ferestrei în sus.
Dacă funcţia cadru se descrie prin intermediul structurii text_info, atunci
coordonatele colţurilor stînga sus şi dreapta jos ale unui cadru vor fi precizate prin
window în modulul principal. În desenarea chenarului coordonatele sînt relative la
fereastra curentă, nu la întreg ecranul.
#include <stdio.h>
#include <conio.h>
#include <graphics.h>
void cadru(int);
void main()
{ clrscr();
window(1, 2, 80, 5); cadru(12);
window(1, 6, 80, 22); cadru(14);
window(64, 8, 78, 10); cadru(11);
window(67, 19, 78, 21); cadru(11);
getch(); }
void cadru(int culoare)
{ unsigned char css=218, co=196, cds=191, cv=179, csj=192, cdj=217;
int i, dx, dy;
struct text_info dw;
textcolor(culoare);
gettextinfo(&dw); /*Determina dimensiunile unei ferestre */
dx = dw.winright – dw.winleft + 1; /* Latimea ferestrei */
dy = dw.winbottom – dw.wintop + 1; /* Inaltimea ferestrei */
gotoxy(1, 1); putch(css); /* Coltul stinga sus */
for( i = 2; i<=dx; ++i) putch(co); /* Linie orizontala superioara */
putch(cds); /* Coltul dreapta sus */

8
for( i = 2; i<=dy; ++i)
{ gotoxy(1, i); putch(cv); /* Linie verticala stinga */
gotoxy(dx, i); putch(cv); /* Linie verticala dreapta */
}
gotoxy(1, dy); putch(csj); /* Coltul stinga jos */
for( i = 2; i<=dx; ++i) putch(co); /* Linie orizontala inferioara */
_wscroll=0;
putch(cdj); /* Coltul dreapta jos */
_wscroll=1; getch(); }
Programul 14.8.2
Logica de rezolvare a problemei şi comentariul făcut la sfîrşitul programului
anterior privitor la anularea temporară a scrierii pe ecran cu “scroll” rămîn neschimbate,
doar mecanismul de codificare este altul.
Observaţie. În mod analog, în modul grafic există funcţii predefinite specifice de
desenare figuri geometrice, stiluri de linii şi modele de haşurare. De exemplu,
pentru figurile geometrice uzuale se menţionează cîteva:
void far line(int x, int y, int x1, int y1);,
void far linerel(int dx, int dy); şi
void far lineto(int x, int y);. Funcţia line() are ca efect trasarea unei linii între
punctele de coordonate (x, y) şi (x1, y1), fără modificarea poziţiei curente. Pentru funcţia
linerel(), punctul iniţial este poziţia curentă a cursorului, iar coordonatele punctului final
se obţine incrementînd cu dx şi dy abscisa şi respectiv ordonata poziţiei curente. Punctul
final devine noua poziţie curentă. Ultima funcţie desenează o linie între poziţia curentă şi
punctul de coordonate (x, y), care stabileşte noua poziţie curentă.
Apelul funcţiei void far rectangle(int x, int y, int x1, int y1); permite
desenarea unui dreptunghi, unde colţul din stînga sus este punctul de coordonate (x, y),
iar colţul din dreapta jos este (x1, y1).
Cu funcţia void far circle(int x, int y, int r); se desenează un cerc cu centrul în
(x, y) şi de rază r.
Pentru desenarea unui arc de cerc pe lîngă centrul cercului şi rază trebuie să se
specifice, în grade, unghiurile de început şi de sfîrşit ale arcului:
void far arc(int x, int y, int unghi_start, int unghi_final, int r);. Dacă
unghi_start este 0˚ şi unghi_final este 360˚, atunci se trasează un cerc complet.
Un arc de elipsă poate fi efectul activării funcţiei:
void far ellipse(int x, int y, int unghi_start, int unghi_final, int axa_o, int axa_v);.

Consideraţii generale despre programarea orientată


către obiect
Stilul de programare orientat spre obiect (POO) adaugă un grad ridicat de abstractizare
programelor C++, pe lîngă modularizare şi structurare, şi permite facilităţi de adaptare şi
extindere a acestora în întreţinerea versiunilor existente şi respectiv în dezvoltarea
versiunilor ulterioare. Efortul de bază se îndreaptă, acum, către definirea obiectului şi a
ierarhiei între obiecte.
Atributele fundamentale ale POO sînt încapsularea, moştenirea şi polimorfismul.

9
1. Încapsularea. Spre deosebire de programarea procedurală, unde structurile de date se
tratează separat de către algoritmi cu nivele diferite de complexitate, prin încapsularea
datelor se încearcă, pe de o parte tratarea mai apropiată de realitate a structurilor de date,
în sensul că se precizează, strict, numai modurile în care se poate opera asupra acestora,
iar pe de alta protejarea structurilor de date împotriva unor accidente nedorite, ca de
exemplu suprascrierea din greşeală.
2. Moştenirea tranzitivă. Tratarea adecvată a realităţii complexe şi diverse, în continuă
transformare şi modificare, presupune traducerea în practica programării a noţiunilor de
gen proxim şi diferenţă specifică. Definirea obiectului de bază cuprinde aspectele
esenţiale (aspectele ce redau genul proxim) în descrierea şi manipularea obiectului.
Adăugînd succesiv alte caracteristici specifice la descrierea obiectului definit anterior se
obţine un nou obiect. În acest mod se poate construi o structură arborescentă de clase, de
tip descendent înlănţuit. Obiectele din clasele descendente preiau automat atît datele
(însuşirile, caracteristicile) cît şi metodele (capacităţile) din obiectele strămoş (definitor)
pe linie ascendentă pînă la rădăcina arborelui. Cu alte cuvinte, transmiterea ereditară a
caracteristicilor şi capacităţilor unui obiect într-o ierahie de obiecte este un proces
tranzitiv, şi anume: dacă obiectul O2 este urmaşul obiectului O1, iar obiectul O3 este
urmaşul obiectului O2, atunci O3 este urmaşul lui O1.
Numărul de descendenţi este nedeterminat şi moştenirea se măreşte proporţional cu
lungimea adîncimii unei ramuri. Ordinea de amplasare a textelor care definesc tipurile de
clasă trebuie să cuprindă mai întîi tipurile de clasă care vor servi ca strămoş, descendenţii
urmează după aceea. Definiţiile metodelor pot fi aşezate oriunde, compilatorul le culege
în ordinea corectă.
3. Polimorfismul. Structura metodelor care acţionează asupra obiectelor poate fi
reconfigurată ulterior în cadrul ierarhiei de obiecte stabilită conform cerinţelor
utilizatorului. Deci, un indentificator de recunoaştere al unei metode moştenite poate fi
redefinit în cadrul ierarhiei de obiecte. Redefinirea unei metode moştenite are ca efect
crearea unei noi metode cu un bloc de metodă diferit şi dacă este cazul cu o altă listă de
parametri. Astfel, diferite variante ale unei metode pot acţiona automat şi în mod specific
asupra obiectelor de pe diverse nivele de ierarhizare, aşa cum se întîmplă, de exemplu, în
cazul metodelor virtuale.

IX. Operaţii de intrare/ieşire specifice POO


Pentru partea de POO, compilatorul C++ este prevăzut cu un sistem adecvat de
dispozitive logice şi de operatori de citire/scriere. Pentru vizualizarea la consolă a
mesajelor care permit fixarea momentelor în construirea, utilizarea şi distrugerea unui
obiect dintr-o anumită clasă sînt suficienţi operatorii cin şi cout, pe care îi vom descrie în
continuare. Cu alte cuvinte, dispozitivelor logice stdin şi stdout în POO le corespund
operatorii cin şi respectiv cout. Specificatorii de delimitare a valorilor de intrare/ieşire,
controlul formatului şi erorile de citire/scriere se tratează în acelaşi mod ca în cazul
funcţiilor predefinite scanf() şi printf(). După caz, pentru execuţia unui program care
conţine operatorii cin/cout este obligatorie includerea unuia din fişierele antet istream.h,
ostream.h sau iostream.h.
Formatul general de citire a n valori de la tastatura calculatorului este următorul:
cin >>nume_var_1>> nume_var_2>> …>>nume_var_n; unde variabilile
desemnate prin indentificatorii de recunoaştere nume_var_i, cu i = 1,2, …, n, pot avea

10
tipuri aritmetice sau pot fi şiruri de caractere. Valorile lor sînt citite în ordine, iar orice
caracter invalid provoacă întreruperea operaţiei de citire.
Pentru scrierea a n valori pe ecranul calculatorului se utilizează operatorul cout cu
următoarea sintaxă generală:
cout<< nume_var_1<< nume_var_2<< …<<nume_var_n;.
Variabilile nume_var_i, cu i = 1,2, …, n, pot fi cu tipuri aritmetice, şiruri de caractere
sau pointeri. La pointeri nu se admite tipul char.
Un exemplu de utilizare a operatorilor cin şi cout se prezintă în programul de mai jos:
/* Operatorii cin si cout */
#include <iostream.h>
void main (void)
{ int i;
float j;
cout << “Intrduceti i si j: ”;
cin >>i>>j;
cout<<”\nS-au citit valorile ”<< i<<” si ”<<j<<’\n’; }
Introduceti i si j: 15 22.45
S-au citit valorile 15 si 22.45
Programul 14.9.1
Alte informaţii despre POO necesită un timp îndelungat. Spre informare se recomandă
consultarea bibliogafiei, prezentată în primul curs.

11

S-ar putea să vă placă și