Sunteți pe pagina 1din 22

Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing.

Edelhauser Eduard

DOCUMENTE LIVRABILE
PENTRU ACTIVITATEA A5.2.
LUNA AUGUST 2019

Numele şi prenumele expertului: Stoicuța Olimpiu - Costinel


Poziția în cadrul proiectului: Expert elaborarea material didactic
Nr. și tipul contractului: CIM cu timp parțial 298 / 31.05.2019

1 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

Anexa 1
SPECIFICAREA MODALITĂȚILOR DE DOCUMENTARE

In vederea elaborarii suportului de curs Programare modulară (capitolul 1 – varianta 2), am


consultat următoarea bibliografie.

Cărți:
1. V. Huţanu, T. Sorin – Manual de informatică, Ed.L&S Soft, Bucureşti, 2006
2. M. Milosescu – Manual de informatică, Ed. Didactică și Pedagocică, Bucureşti, 2011
3. D. Oprescu, L.B. Ienulescu – Manual de informatică, Ed. Niculescu, 2006
4. B. Overland – Ghid pentru începători C++, Ed. Corint, Bucureşti, 2006
5. E. Cerchez, M. Şerban – Programarea în limbajul C/C++ pentru liceu, Ed. Polirom, Bucureşti
2007

Site-uri web:
6. ***, www.cs.utcluj.ro
7. ***, www.labs.cs.utt.ro
8. ***, www.facultate.regielive.ro
9. ***, www.didactic.ro
10. ***, www.infoscience.3x.ro
11. Carmen Ana Anton, https://carmenanton.files.wordpress.com/2015/10/lectia-7-informatica-
subprograme.pdf

2 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

UNIVERSITATEA DIN PETROȘANI

CURS
PROGRAMARE MODULARĂ
~Varianta 2~

CONF. DR. ING. STOICUȚA OLIMPIU - COSTINEL

2019

3 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

Anexa 2 - Capitolul 1

1.1. Noțiunea de subprogram

Subprogramul este o secvenţă de instrucţiuni care rezolvă o anumită sarcină şi care poate fi
descrisă separat de blocul rădăcină şi lansată în execuţie din cadrul unui bloc, ori de câte ori este
nevoie. În limbajul C++, subprogramele se mai numesc şi funcţii.
Un subprogram este un ansamblu ce poate conţine tipuri de date, variabile şi instrucţiuni destinate
unei anumite prelucrări (calcule, citiri, scrieri).
Subprogramul poate fi executat doar dacă este apelat de către un program sau un alt subprogram.
Avantajele utilizării subprogramelor în cadrul unor aplicații, este:
 permite economisirea de memorie şi de timp alocat. Un grup de instrucţiuni care trebuie să se
execute de mai multe ori într-o aplicaţie (chiar cu date de intrare şi de ieşire diferite) se va scrie o
singură dată într-un subprogram şi se va executa prin apelarea subprogramului ori de câte ori este
nevoie.
 permite lucrul în echipă la rezolvarea unor sarcini complexe pentru aplicaţiile mari. Fiecare
programator va putea să scrie mai multe subprograme, independent de ceilalţi programatori din
echipă. Pentru a realiza subprogramul, este suficient să i se precizeze programatorului specificaţiile
subprogramului: datele de intrare, datele de ieşire şi problema pe care trebuie să o rezolve
 depanarea şi actualizarea aplicaţiei se fac mai uşor. După implementare şi intrarea în exploatare
curentă, o aplicaţie poate necesita modificări, ca urmare a schimbării unor cerinţe. Este mult mai
simplu să se gândească modificarea la nivelul unui subprogram, decât la nivelul întregii aplicții.
 creşte portabilitatea programelor. Subprogramele sunt concepute independent de restul
aplicaţiei şi unele dintre ele pot fi preluate, fără un efort prea mare, şi în alte aplicaţii, în care
trebuie să fie rezolvate sarcini similare.
O parte din subprogram se contruieşte ca subprogram dacă un algoritm cuprinde în mai multe
locuri aceeaşi secvenţă de operaţii executabilă pentru aceleaşi date sau pentru date diferite. În loc ca
subprogramul să cuprindă în acelaşi loc, acelaşi grup de instrucţiuni, concepând grupul de intrucţiuni ca
subprogram, el va apărea în program o singură dată şi se va activa de mai multe ori. Partea respectivă de
program rezolvă o subproblemă din cele în care se descompune problema complexă.
De exemplu, considerăm următoarea secvenţă de program care memorează în variabila max
valoarea maximă dintre valorile variabilelor întregi a, b și c:

Din cadrul programului de mai sus, se observă că cele două instrucţiuni condiţionale (instrucțiunile
if) realizează acelaşi lucru: determină valoarea maximă dintre două numere întregi. Procesul de calcul este
acelaşi, diferă doar valorile numerelor întregi pentru care se execută cele două instrucțiuni.
Pe de altă parte, determinarea maximului dintre două numere întregi se poate modela matematic
ca o funcţie:

4 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

În aceste condiții, secțiunea de program ce calculează maximul dintre 3 numere întregi, se poate
scrie astfel:

1.2. Tipuri de subprograme

Clasificarea subprogramelor
 Subprograme standard (subprograme de sistem) – utilizarea lor presupune includerea fişierului
ce conţine prototipul dorit şi apelarea subprogramului. Aceste subprograme sunt predefinite în
biblioteci ale limbajului de programare. (Exemplu: #include <cmath> include un set de funcții
utilizate în realizarea operațiilor și transformărilor matematice obijnuite: funcții trigonometrice;
funcții hiperbolice; funcții exponențiale și logaritmice; funcțiile putere: pow, sqrt; funcții de eroare;
funcții de rotunjire și rest; funcții de manipulare cu punct flotant; funcții de diferență – minim –
maxim).
 Subprograme definite de utilizator – sunt descrise de progamator pentru rezolvarea unor cerinţe
specifice. Utilizarea lor presupune precizarea prototipului, definirea şi apelul (a se vedea exemplu
din paragraful anterior).
 Subprograme apelate ca instrucţiuni procedurale – returnează una, mai multe sau nici o valoare
prin intermediul parametrilor. Exemple de apeluri de funcţii procedurale implementate în limbajul
C++:
o clrscr ( ); Apelul unei funcţii procedurale fără parametri (CLeaR SCReen) care şterge
informaţiile afişate pe ecranul calculatorului.
o randomize ( ); Apelul unei funcţii procedurale fără parametri care iniţializează generatorul
de numere aleatoare.
o swab(s1,s2,n); Apelul unei funcţii procedurale cu trei parametri: copiază n caractere (n
fiind un număr par), din şirul de caractere s1, la începutul şirului de caractere s2, inversând
caracterele adiacente. Parametrul s2 este un parametru de intrare-ieşire, iar parametrii s1 şi
n sunt parametri de intrare.
o gotoxy(x,y); Apelul unei funcţii procedurale cu doi parametri: în modul de lucru text, mută
cursorul în fereastra de text curentă, în poziţia precizată prin coordonatele x şi y. Parametrii
x şi y sunt parametri de intrare.
 Subprograme apelate ca operanzi – returnează un rezultat chiar prin numele său şi eventual alte
rezultate, prin parametri. Subprogramul se activează în interiorul unei expresii unde este folosit ca
operand. Exemple de apeluri de funcţii operand implementate în limbajul C++:
o x=3.5; e=5+floor(x); La calculul expresiei care se atribuie variabilei e se activează funcţia
floor() prin care se determină cel mai mare întreg mai mic decât valoarea parametrului.
Funcţia are un singur parametru – x, care este parametru de intrare şi are valoarea 3.5.
Rezultatul (data de ieşire) este furnizat prin numele funcţiei şi are valoarea 3. Aşadar,
variabilei de memorie e i se va atribui valoarea: 8 (5+3).

5 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

o for (i=0;i<=sqrt(n);i++); La calculul expresiei ce se atribuie valorii finale a contorului


structurii repetitive for, se activează funcţia sqrt(n) care furnizează radicalul de ordinul 2
din valoarea parametrului. Funcţia are un singur parametru – n, care este parametru de
intrare.
o x = sqrt (pow(3,2)+ pow(4,2)); La calculul expresiei care se atribuie variabilei x se
activează de două ori funcţia pow(): o dată pentru a calcula 3 la puterea 2, returnând
valoarea 9, şi o dată pentru a calcula 4 la puterea 2, returnând valoarea 16. Funcţia pow()
are doi parametri de intrare: primul este baza, iar al doilea este exponentul. Rezultatul este
furnizat prin numele funcţiei. Rezultatul obţinut prin evaluarea expresiei 9+16 = 25 va fi
parametru de intrare pentru funcţia sqrt()care extrage radicalul de ordinul 2 din valoarea
lui. Rezultatul funcţiei sqrt() – data de ieşire – este furnizat prin numele funcţiei şi are
valoarea 5. El este atribuit variabilei de memorie x. Aşadar variabila de memorie x va avea
valoarea 5.

1.3. Structura subprogramelor

Un subprogram (funcţie) are o definiţie şi atâtea apeluri câte sunt necesare.


Definiţia unui subprogram reprezintă de fapt descrierea unui proces de calcul cu ajutorul
variabilelor virtuale (parametri formali), iar apelul unui subprogram înseamnă execuţia procesului de
calcul pentru cazuri concrete (cu ajutorul parametrilor reali, efectivi, actuali).
Parametri formali apar în antetul subprogramului şi sunt utilizaţi de subprogram pentru descrierea
abstractă a unui proces de calcul.
Parametri actuali apar în instrucţiunea de apelare a uni subprogram şi sunt folosiţi la execuţia
unui proces de calcul pentru valori concrete.
Parametrii formali nu sunt variabile. O variabilă este caracterizată de nume, tip, şi adresă.
Legarea unui parametru formal la o adresă se realizează în timpul execuţiei instrucţiunii de apelare a
subprogramului.
În limbajul C++ există trei elemente implicate în utilizarea unui subprogram:
 definiţia subprogramului – conţine numele subprogramului, tipul argumentelor şi al valorilor
returnate şi specifică ceea ce trebuie să realizeze subprogramul;
 prototipul subprogramului – comunică compilatorului informaţii despre subprogram (modul în
care se poate apela subprogramul);
 apelul subprogramului – execută subprogramul.

Subprogramul se poate identifica printr-un nume care este folosit atât pentru definiţia
subprogramului, cât şi prin prototip şi activarea lui (apelarea lui). Apelarea subprogramului în cadrul
unui bloc înseamnă activarea subprogramului, adică lansarea lui în execuţie. Subprogramul poate fi apelat

6 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

ori de câte ori este nevoie (nu există restricţii pentru numărul de apeluri). Modulul apelant se execută
secvenţial (instrucţiune cu instrucţiune). La apelarea subprogramului, este părăsit blocul modulului apelant
şi se trece la executarea instrucţiunilor din subprogram. După ce se termină executarea acestor instrucţiuni,
se revine la blocul apelant şi se continuă execuţia cu instrucţiunea care urmează apelului.
Definiţia unui subprogram este formată din antetul şi corpul subprogramului:

a. Antetul subprogramului. Este o linie de recunoaştere a subprogramului, în care i se atribuie


un nume. El specifică începutul subprogramului.
Corpul subprogramului. La fel ca orice bloc C++, este încapsulat într-o instrucţiune compusă,
delimitată de caracterele {...} şi este format din două părţi:
 Partea declarativă. Conţine definiţii de elemente folosite numai în interiorul subprogramului:
tipuri de date, constante şi variabile de memorie. Nu se pot defini şi alte subprograme (nu este
valabilă tehnica de imbricare a subprogramelor existentă în alte limbaje de programare).
 Partea executabilă. Conţine instrucţiunile prin care sunt descrise acţiunile realizate de
subprogram.
Subprogramul trebuie să aibă un antet prin care se precizează interfaţa dintre programul apelant şi
subprogram. El conţine trei categorii de informaţii:
 Tipul rezultatului. Pentru funcţiile operand se precizează tipul rezultatului furnizat de
subprogram prin chiar numele său. Pentru funcţiile procedurale, tipul rezultatului este void (nu
întoarce nici un rezultat prin numele său; rezultatele vor fi întoarse prin parametrii
subprogramului). Dacă nu se precizează tipul rezultatului, compilatorul va considera că acesta
este implicit de tip int.
 Numele subprogramului. Este un identificator unic, care se atribuie subprogramului. Numele
trebuie să respecte aceleaşi reguli ca orice identificator C++. Parametrii folosiţi pentru
comunicare. Pentru fiecare parametru se precizează numele şi tipul.
 Parametrii folosiţi pentru comunicare. Pentru fiecare parametru se precizează numele şi
tipul.

Antetul unui subprogram are următoarea formă:

unde lista de parametrii are următoarea formă:

Exemple aferente limbajului C++:

7 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

 float alfa (int a, int b, float c)


Acesta este antetul unei funcţii operand care furnizează un rezultat de tip float. Numele funcţiei
este alfa, iar parametrii folosiţi pentru comunicare sunt a şi b de tip int şi c de tip float.
 void beta (int a, float b, float c, char d)
Acesta este antetul unei funcţii procedurale. Numele funcţiei este beta, iar parametrii folosiţi pentru
comunicare sunt: a de tip int, b şi c de tip float şi d de tip char.
 void gama ( )
Acesta este antetul unei funcţii procedurale. Numele funcţiei este gama şi nu foloseşte parametri
pentru comunicare.

Observația 1: Separarea parametrilor în listă se face prin caracterul virgulă (,).


Observația 2: Tipul parametrilor poate fi:
 orice tip standard al sistemului folosit pentru date elementare:
o întreg (int, unsigned, long), real (double, float, long double) sau caracter (char sau unsigned
char);
o tipul pointer sau orice tip de structură de date (vector, matrice, şir de caractere sau
înregistrare);
 orice tip definit de utilizator înainte de a defini subprogramul.
Observația 3: Numele subprogramului poate fi folosit în trei locuri distincte:
 în prototipul subprogramului, unde are un rol declarativ;
 în antetul subprogramului, unde are un rol de definiţie, dar şi declarativ;
 în apelul subprogramului, unde are rol de activare.

b. Corpul subprogramului este un bloc care conţine atât instrucţiuni declarative, cât şi
instrucţiuni imperative. Variabilele de memorie declarate în corpul subprogramului se numesc
variabile locale. În cazul unei funcţii operand, ultima instrucţiune din corpul subprogramului
trebuie să fie instrucţiunea return, care are sintaxa:

Valoarea obţinută prin evaluarea expresiei <expresie> va fi atribuită funcţiei operand (va fi
valoarea returnată prin numele funcţiei). Rezultatul expresiei trebuie să fie de acelaşi tip cu tipul funcţiei
sau de un tip care poate fi convertit implicit în tipul funcţiei.
Când compilatorul C++ întâlneşte într-un subprogram instrucţiunea return, termină execuţia
subprogramului şi redă controlul modulului apelant. Prin urmare, dacă veţi scrie în subprogram, după
instrucţiunea return, alte instrucţiuni, ele nu vor fi executate.

Prototipul subprogramului este o linie de program, aflată înaintea modulului care apelează
subprogramul, prin care se comunică compilatorului informaţii despre subprogram (se declară
subprogramul).
Prin declararea programului, compilatorul primeşte informaţii despre modul în care se poate apela
subprogramul şi poate face verificări la apelurile de subprogram în ceea ce priveşte tipul parametrilor
folosiţi pentru comunicare şi a modului în care poate face conversia acestor parametri.
Un subprogram, pentru a putea fi folosit, trebuie declarat. Pentru declararea lui se foloseşte
prototipul. El conţine trei categorii de informaţii, la fel ca şi antetul subprogramului: tipul rezultatului,
numele subprogramului şi tipul parametrilor folosiţi pentru comunicare. Pentru fiecare parametru din
antetul subprogramului, se poate preciza numai tipul, nu şi numele lui.

8 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

Prototipul unui subprogram este de forma

unde lista tipului parametrilor are următoarea forma

Observația 4: Separarea tipurilor de parametri în listă se face prin caracterul virgulă (,). Lista trebuie să
conţină atâtea tipuri de parametri câţi parametri au fost definiţi în antetul subprogramului. În listă se
precizează tipul de dată la care se referă, în aceeaşi ordine în care au fost scrişi parametrii la definirea lor
în antet.
Observația 5: Spre deosebire de antetul subprogramului, prototipul se termină cu caracterul ; .

Pentru funcţiile al căror antet a fost precizat anterior (a se vedea exemplele anterior prezentate),
prototipurile vor fi:
 float alfa (int, int, float);
 void beta (int, float, float, char);
 void gama ();

Subprogramul trebuie să fie cunoscut, atunci când se cere prin apel activarea lui:

 dacă subprogramul este standard, trebuie inclus fişierul care conţine prototipul subprogramului în
fişierul sursă.
 dacă subprogramul este utilizator, trebuie declarat fie prin folosirea prototipului, fie prin definirea
lui înaintea apelului.

În funcţie de modul în care a fost definit, subprogramul se activează fie printr-o instrucţiune
procedurală, fie ca operand într-o expresie.
Pentru funcţiile al căror antet a fost precizat anterior, activarea se poate face astfel:

 exemplul 1:
int x,y; float z,w;
w = alfa (x,y,z);
 exemplul 2:
int x; float y,z; char w;
beta (x, y, z, w);
 exemplul 3:
gama ();

Orice subprogram trebuie declarat şi definit. Declararea unui subprogram este necesară pentru ca
el să fie cunoscut de subprogramele care îl apelează. Declararea lui poate fi făcută fie prin prototip, fie
prin definiţia lui (antetul împreună cu corpul subprogramului). Pentru a declara subprogramul, fie scrieţi
prototipul înaintea subprogramelor care îl apelează, putând scrie apoi definiţia lui oriunde în program, fie

9 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

definiţi subprogramul înaintea subprogramului care îl apelează. În cele ce urmează, se prezintă un


exemplu:

Aşadar:
 Prototipul subprogramului declară subprogramul.
 Apelul subprogramului execută subprogramul.
 Antetul subprogramului specifică numele subprogramului şi tipul argumentelor şi al valorilor
returnate, iar corpul subprogramului îl defineşte, adică specifică ceea ce trebuie să realizeze
subprogramul.

În concluzie, forma generală a unui subprogram este prezentată mai jos:

unde:
 tip_returnat. Reprezintă tipul rezultatului calculat şi returnat de funcţie şi poate fi: int, char, char,
long, float, void, etc. În cazul în care tipul rezultatului este diferit de void, corpul funcţiei trebuie
să conţină cel puţin o instrucţiune return. Înstrucţiunea return va specifica valoarea calculată şi
returnată de funcţie care trebuie să fie de acelaşi tip ca şi tip_returnat.
 nume_funcție. Reprezintă numele dat funcţiei de către cel ce o defineşte, pentru a o putea apela.
 lista parametrilor formali. Reprezintă o listă de declaraţii de variabile separate prin virgulă.
Această listă poate să fie şi vidă.
 instrucțiune. Este o instrucţiune vidă sau o instrucţiune simplă sau o instrucţiune compusă.

În altă odine de idei, construirea subprogramelor se face prin :


 Antet – conţine date despre: tipul rezultatului, nume şi parametrii efectivi. Dacă funcţia nu
returnează nimic, tipul este void()
 Corp – este un bloc de instrucţiuni declarative şi imperative (de execuţie) ce definesc modul de
acţiune al subprogramului
 Prototip – pentru a putea fi apelată, funcţia trebuie declarată. Conţine date despre: tipul
rezultatului, nume şi parametrii efectivi.
 Apel – este modul prin care subprogramul e pus în execuţie. Apelul poate fi făcut ori de câte ori
este nevoie.
 Parametrii – datele care circulă între modulul appelant şi apelat se introduc între paranteze, după
numele subprogramului.
 Modul apelant – blocul ce conţine apelul subprogramului
 Modul apelat – blocul ce conţine funcţia (subprogramul apelat).

10 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

Exemplu:

În memoria internă, fiecărui subprogram i se alocă o zonă de memorie în care este încărcat codul
executabil.
La apelarea unui subprogram, compilatorul îi predă controlul, adică încep să se execute
instrucţiunile subprogramului, până la întâlnirea unei instrucţiuni return sau până la sfârşitul blocului care
formează corpul subprogramului, după care compilatorul redă controlul modulului apelant, adică va
continua execuţia cu instrucţiunea care urmează, în modulul apelant, imediat după instrucţiunea care a
apelat subprogramul. Acest mecanism de transfer al controlului se poate realiza deoarece, într-o zonă de
memorie internă numită stiva sistemului (stack), se păstrează temporar informaţii despre subprogramul
apelant. Aceste informaţii sunt introduse în stivă atunci când este apelat subprogramul. Ele formează
instanţa subprogramului.

11 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

Etapele executate la apelarea subprogramului sunt:


1. Se întrerupe execuţia modulului apelant.
2. Se pregăteşte stiva sistemului, astfel:
 se introduce adresa de revenire în modulul apelant;
 se introduc valorile parametrilor cu care a fost apelat subprogramul;
 se rezervă spaţiu pentru variabilele locale declarate în subprogram.
3. Se lansează în execuţie codul executabil al subprogramului apelat.

Etapele executate la terminarea subprogramului sunt:


1. Se eliberează din stivă spaţiul ocupat de variabilele locale şi de parametri.
2. Se extrage din stivă adresa de revenire în modulul apelant.
3. Se continuă execuţia cu instrucţiunea de la adresa extrasă din stivă.

Astfel, pentru exemplele anterioare de declaraţii de subprograme, la apelarea lor, în stivă se vor
introduce următoarele informaţii:

Aşadar, în timpul execuţiei subprogramului, în stivă sunt păstrate datele cu care el lucrează:
variabilele locale şi parametrii cu care a fost apelat. Instrucţiunile subprogramului pot modifica aceste
date. Modificările se execută asupra valorilor memorate în stivă. Când se termină execuţia
subprogramului, trebuie să se reia execuţia modulului apelant cu instrucţiunea de adresă de revenire.
Pentru a se ajunge în stivă la adresa de revenire, spaţiul ocupat de parametri şi de variabilele locale
este eliberat şi se pierd valorile lor.

Exemplu: Să se verifice dacă un număr natural n, citit de la tastatură, este număr prim. Pentru
testarea numărului se va folosi un subprogram. Obiectivul acestui exemplu este exemplificarea modului
în care este folosită stiva sistemului la apelarea unui subprogram.
Funcţia prim(a) furnizează, prin numele său, o valoare întreagă ce poate fi interpretată ca o valoarea
logică: 0 – false sau 1 – true. În variabila locală x se calculează valoarea funcţiei prim (1 sau 0, în funcţie
de numărul a – dacă este sau nu este număr prim).

12 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

Conţinutul stivei sistemului va fi:

1.4. Transmiterea parametrilor

Transferul de parametri este o tehnică folosită pentru schimbul de date între module.
Transmiterea datelor între apelant şi apelat se poate face fie prin parametri, fie prin variabile
globale. Prin utilizarea variabilelor globale nu se face un transfer propriu-zis, ci se folosesc în comun
anumite zone de memorie.
Transferul se poate face prin valoare sau prin referinţă/adresă.
Datele care se transferă între apelant şi apelat se introduc între paranteze, după identificatorul
subprogramului.
În antetul subprogramului parametrii se înscriu prin tip şi nume, separaţi prin virgulă, fără a fi
grupaţi. Ei se numesc parametrii formali.
În apelul subprogramului se înscriu separaţi prin virgulă, în aceeaşi mordine ca în antet, prin valori
concrete.Ei se numesc parametrii efectivi (actuali).
Regula de corspondenţă notifică o anumită concordanţă între numărul, ordinea şi tipul parametrilor
formali şi a parametrilor efectivi.
 Numărul parametrilor formali poate să difere de numărul parametrilor efectivi în cazul funcţiilor
cu număr de parametri variabil, respectiv în cazul supraîncărcării funcţiilor.
 Tipul parametrilor formali poate să difere de tipul parametrilor efectiviîn cazul conversiei implicite
a parametrilor efectivi în tipul parametrilor formali, ca o operaţie de atribuire, respectiv în cazul
supraîncărcării funcţiei.
 Numele parametrilor formali poate să difere de numele parametrilor efectivi.
Parametrii sunt memoraţi în segmentul de stivă în ordinea înscrierii lor.

Exemplu: Să se construiască un subprogram care să calculeze valoarea absolută a unui număr real.
Numele subprogramului este mod_r. Acest subprogram va fi construit în două variante: ca funcţie
procedurală şi ca funcţie operand. În ambele cazuri modulul apelant va fi funcţia rădăcină, iar modulul
apelat va fi subprogramul mod_r. Principalul scop a acestui exemplu este exemplificarea modului în care
poate fi construit un subprogram C++.
Varianta 1:
În cazul funcţiei procedurale, subprogramul va afişa valoarea modulului numărului şi nu va furniza
niciun rezultat funcţiei rădăcină care îl apelează. El va primi valoarea numărului de la funcţia rădăcină
prin intermediul parametrului.

13 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

Varianta 2:
În cazul funcţiei operand, subprogramul va returna funcţiei rădăcină, prin numele său, valoarea
absolută a numărului. El va primi valoarea numărului de la funcţia rădăcină prin intermediul parametrului.

Transmiterea prin referinţă/adresă - se transmite adresa parametrului actual. Este utilizată la


prelucrarea unei variabile în interiorul unei funcţii, astfel încât, la revenirea din funcţie, variabila să reţină
valoarea modificată, nu valoarea de intrare.
În momentul apelării subprogramului, în stivă este încărcată adresa de memorie la care se găseşte
valoarea parametrului. Subprogramul va lucra direct în zona de memorie în care se găseşte data. Atât
modulul apelant cât şi subprogramul lucrează asupra aceleiaşi date, şi orice modificare a valorii acestui
parametru făcută în subprogram se va reflecta şi în modulul apelant. La terminarea execuţiei
subprogramului, este eliberată din stivă zona în care este memorată adresa parametrului.
Parametrul prin intermediul căruia se face transferul prin referinţă se numeşte parametru
variabilă.

14 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

Acest transfer se recomandă pentru parametrii de intrare-ieşire sau parametrii de ieşire. Modulul
apelant transmite, prin aceşti parametri, date de intrare-ieşire către subprogram, subprogramul preia data,
o prelucrează şi o returnează modulului apelant. Acest parametru mai poate fi şi un rezultat (dată de ieşire)
obţinut în urma prelucrărilor din subprogram, care este returnat apoi modulului apelant.
Distincţia dintre un parametru valoare şi un parametru variabilă (definirea tipului de transfer) se
face în lista de parametri formali din antetul subprogramului în care parametrii variabilă sunt precedaţi de
operatorul adresă de memorie &. (Parametrii transmişi prin referinţă vor fi precedaţi de caracterul
ampersand “&”, atât la declararea, cât şi la definirea funcţiei).
Un exemplu de antet de subprogram (subprogramul furnizează, prin parametrii ma şi mg, media
aritmetică, şi respectiv media geometrică, a două numere transmise subprogramului prin parametrii a şi
b), este:

Apelarea acestui subprogram se va face prin: medie(x,y,m1,m2);


Din modulul apelant se transmit: parametrilor a şi b, care sunt parametri valoare – valorile
variabilelor x şi respectiv y, iar parametrilor ma şi mb, care sunt de tip parametri variabilă – adresele
variabilelor m1 şi respectiv m2.
În apel, parametrii efectivi corespunzători parametrilor formali transmişi prin referinţă trebuie să
fie variabile de memorie.
Transmiterea prin referinţă înseamnă că parametrii sunt transmişi prin referinţă tunci când ne
interesează ca la revenirea din subprogram, variabila transmisă să reţină valoarea stabilită în timpul
execuţiei subprogramului. Pentru aceasta parametrii efectivi trebuie să fie referinţe la variabile.
Subprogramul reţine în stivă adresa variabilei.

Transmiterea prin valoare – se transmite o copie a parametrului actual. Este utilizată la relucrarea
unei variabile în interiorul unei funcţii. La revenirea din funcţie, variabila nu reţine valoarea modificată,
ci valoarea de intrare.
Modulul apelant transmite prin parametru, către subprogram, date de intrare. În momentul apelării
subprogramului, o copie a valorii parametrului este încărcată în stivă.El este văzut în subprogram ca o
variabilă locală, care este iniţializată cu valoarea transmisă de modulul apelant prin parametrul actual din
apel. Valoarea acestei variabile se poate modifica în subprogram, dar această modificare nu se va reflecta
şi în modulul apelant, deoarece modificarea se face în stivă, şi, la terminarea execuţiei subprogramului,
zona din stivă în care este memorat parametrul este eliberată.
Parametrul prin intermediul căruia se face transferul prin valoare se numeşte parametru valoare.
Acest transfer se foloseşte în general numai pentru parametrii de intrare. În cazul în care parametrii
transmişi prin valoare sunt parametri de ieşire sau de intrare-ieşire, pentru a putea transmite rezultatul
obţinut în subprogram, către modulul apelant, se pot folosi variabile de tip pointeri.
Un exemplu de antet de subprogram pentru un astfel de transfer (subprogramul furnizează, prin
parametrii ma şi mg, media aritmetică, şi respectiv media geometrică, a două numere transmise
subprogramului prin parametrii a şi b), este prezentat mai jos:

15 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

Apelarea acestui subprogram se va face prin: medie(x,y,&m1,&m2);


Parametrilor a şi b li se transmit, din modulul apelant, valorile variabilelor x şi respectiv y, iar
parametrilor de tip pointer, ma şi mb, valoarea adreselor variabilelor m1 şi respectiv m2.
Parametrii transmişi prin valoare se folosesc doar ca parametrii de intrare. Pentru parametrii de
ieşire se va folosi instrucţiunea return().
În apel, parametrii efectivi corespunzători parametrilor formali transmişi prin valoare pot fi : valori,
variabile, expresii sau alte funcţii.
Transmiterea prin valoare se utilizează atunci când suntem interesaţi ca subprogramul să lucreze
cu acea valoare, dar în prelucrare, nu ne interesează ca parametrul efectiv, cel din blocul apelant, să reţină
valoarea modificată în subprogram.
Se pot transmite prin valoare:
 Valorile reţinute de variabile : parametrii efectivi trebuie să fie numele variabilelor care se trimit
prin valoare.
 Expresii, care pot conţine şi funcţii : parametrii efectivi sunt expresii care mai întâi se evaluează.

Observația 1: Pentru transmiterea unor rezultate din subprogram către modulul apelant (parametru de
ieşire sau de intrare-ieşire) se foloseşte fie transferul prin referinţă, fie transferul prin valoare, folosind
variabile de tip pointeri.
Observația 2: Parametrii actuali corespunzători parametrilor valoare pot fi exprimaţi prin:
 valoare (constantă);
 expresie;
 variabilă de memorie;
 adresă a unei variabile de memorie (este obligatorie, în cazul în care parametrii formali sunt de tip
pointer).
Observația 3: Parametrii formali corespunzători parametrilor valoare pot fi iniţializaţi în antetul
subprogramului. La apelul subprogramului, parametrilor formali li se atribuie valoarea parametrilor
actuali. Dacă lipseşte un parametru actual, parametrul formal va fi iniţializat cu valoarea din listă:

Observația 4: Parametrii actuali corespunzători parametrilor variabilă pot fi exprimaţi numai prin
variabile de memorie.

16 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

Exemplu: Să se construiască un subprogram care să realizeze interschimbarea valorilor a două


variabile de memorie întregi. Obiectivul acestui exemplu este exemplificarea modului în care pot fi
transmişi parametrii între subprograme.
Numele subprogramului este schimb. Modulul apelant va fi funcţia rădăcină, iar modulul apelat
va fi subprogramul schimb. Din funcţia rădăcină se vor transfera subprogramului parametrii x şi y, care
reprezintă variabilele a căror valoare se interschimbă. Acest subprogram va fi construit în trei variante, în
funcţie de modul în care sunt transferaţi parametrii:
Varianta 1: Transferul parametrilor se face prin valoare

Varianta 2: Transferul parametrilor se face prin valoare, folosind variabile de tip pointer.

Varianta 3: Transferul parametrilor se face prin referință.

17 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

1.5. Apelul subprogramelor

Apelul subprogramului este modul prin care subprogramul este pus în execuţie. Apelul
subprogramului se poate realiza în două moduri:
 Printr-o instrucţiune de apel
 Ca operand într-o expresie.
Instrucţiunea de apel a unui subprogram are următorul format general:

unde
 nume: reprezintă numele subprogramului.
 lista parametrilor actuali este formată dintr-o succesiune de expresii, separate prin virgulă.
Se utilizează instrucţiuni de apel atunci când subprogramul nu returnează nici o valoare sau când
nu se doreşte utilizarea valorii returnate de subprogram, ci doar efectuarea prelucrărilor descrise de
subprogram.
În cazul în care se doreşte utilizarea valorii returnate de subprogram ca operand într-o expresie, se
va apela subprogramul în cadrul expresiei astfel:

În această situaţie lipseşte caracterul „;”, care marchează sfârşitul instrucţiunii de apel. La apelul
unui subprogram, valorile parametrilor actuali sunt atribuite, în ordine, parametrilor formali
corespunzători.
Construirea apelului subprogramului:
 Dacă subprogramul este definit de utilizator, el trebuie declarat prin prototip sau prin definirea
subprogramului înainte de blocul apelant.
 Este modul prin care subprogramul este pus în execuţie. Apelul poate fi făcut ori de câte ori este
nevoie.
 Apelul poate fi făcut din funcţia rădăcină main (), dintr-o altă funcţie sau din ea însăşi prin
autoapelare (recursivitate)
 Dacă subprogramul este standard (de sistem), trebuie inclus fişierul ce conţine subprogramul
utilizat.
Atât procedurile, cât şi funcţiile trebuie definite înainte de a fi apelate.
Apelarea unei funcţii nu este o instrucţiune de sine stătătoare , ea trebuie inclusă ca operant în
cadrul unei expresii.
Transmiterea parametrilor efectivi la apelul unei funcţii se face prin copierea valorilor parametrilor
efectivi în parametrii formali, care sunt variabile locale ale funcţiei. În acest fel, funcţia apelată lucrează
cu duplicate ale variabilelor parametrilor efectivi şi nu poate modifica accidental variabile din funcţia
apelantă. Compilatorul generează o secvenţă de atribuiri la parametrii formaliînainte de efectuarea saltului
la prima instrucţiune din funcţia apelată.
O funcţie recursivă este o funcţie care se apelaeză pe ea însăşi. Există două tipuri de funcţii
recursive:
 Funcţii cu un singur apel recursiv, ca ultimă instrucţiune, care se pot rescrie sub formă nerecursivă
(iterativă)
 Funcţii cu unul sau mai multe apeluri recursive, a căror formă trebuie să folosească o stivă pentru
memorarea unor rezultate intermediare.
Recursivitatea este posibilă deoarece, la fiecare apel al funcţiei, adresa de revenire, variabilele locle
şi parametrii formali sunt memorate într-o stivă, iar la ieşire din funcţie, se scot din stivă toate datele puse
la intrarea în funcţie.

18 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

O funcţie recursivă trebuie să conţină cel puţin o instrucţiune if, de obicei la început, prin care se
verifică dacă este necesar un apel recursiv sau se iese din funcţie.
Apelul unei funcţii care nu returnează nici o valoare are forma generală:

unde:
 parametru efectiv = parametru actual = parametru real = parametru de apel
 lista parametrilor efectivi = fie vidă, fie o expresie sau mai multe despărţite prin virgulă
Pentru a apela o funcţie, aceasta trebui mai întâi definită. Astfel apelul unei funcţii trebuie precedat
de definiţia funcţiei respective.
O a doua posibilitate de apelare a funcţiei constă în scrierea prototipului funcţiei înainte ca acesta
să fie apelată.
Prototipul funcţiei conţine informaţii asemănătoare cu cele din antetul funcţiei. Pot lipsi numele
parametrilor formali (contează doar tipul şi ordinea acestora), în plus acesa este urmat de “;”.

Exemplu: Apelul unei funcții ce nu returnează o valoare.

Exemplu: Apelul unei funcții ce returnează o valoare.

19 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

1.6. Modularizarea programelor (Tipuri de variabile, domeniul şi plasarea subprogramelor.


Variabile globale şi locale. Domeniul de vizibilitate)

Variabilele pot fi definite în C++ în orice poziţie a programului. Locul unde a fost definită o
variabilă determină domeniul de vizibilitate a acesteia. Acest domeniu începe în locul unde variabila este
definită şi se sfârşeşte în locul de încheiere a blocului ce o conţine.
Prin domeniul de vizibilitate (valabilitate) se intelege zona de program in care e valabila declararea
sau definirea unui identificator.
Variabilele globale sunt declarate la începutul programului, în afara funcţiilor, inclusv în afara
rădăcinii. Acestea sunt vizibile şi pot fi utilizate în orice punct al programului. Sunt iniţilizate în mod
automat cu zero. Durata lor de viaţă este pe tot parcursul executării programului.
Variabilele declarate într-o funcţie se numesc variabile locale şi pot fi referite numai din funcţia
respectivă. Sunt vizibile doar în interiorul funcţiei. Nu sunt iniţializate automat. Durata lor de viaţă este
pe tot parcursul executării funcţiei în care au fost definite. Domeniul de valabilitate a unei variabile locale
este funcţia sau instrucţiunea compusă în care a fost definită.
În cazul în care există o variabilă locală care are acelaşi nume cu o variabilă globală, aceste două
variabile se numesc variabile omonime. Variabilele locale sunt prioritare variabilelor globale omonime.
Exemplu:

#include <iostream>
int z=8;
void schimb(int x, int &y)
{ int s; /*se poate folosi doar în acest subprogram este o variabilă locală*/
x=15; //parametru de intrare, transmis prin valoare
y=16; //parametru de iesire, transmis prin referință
z=9; //variabila globala, se transmit modificările
}
void main()
{
int a=2,b=3;
schimb(a,b);
cout<<"a="<<a<<" b="<<b<<" z="<<z; // se va tipari a=2 b=16 z=9
}

Plasarea subprogramelor în cadrul programului.


A defini un subprogram înseamnă al scrie efectiv, după o anumită structură. A declara un
subprogram înseamnă a-l anunţa. Un subprogram nedeclarat nu poate fi folosit. Definiţia unui subprogram
ţine loc şi de declaraţie.
Orice program trebuie să conţină :
 Instrucţiuni imperative, prin care se comandă executarea anumitor acţiuni;
 Declaraţii de variabile, de funcţii, etc. necesare compilatorului, dar fără efect la execuţie ;
 Comentarii, ignorate de compilator, necesare utilizatorului.
Instrucţiunile executabile sunt grupate în subprograme. În C++ trebuie să existe cel puţin o funcţie
“main“ cu care începe execuţia unui program. Celelalte funcţii sunt apelate din funcţia “main“ sau din
alte funcţii activate direct sau indirect de “main“.
Acoladele sunt necesare pentru a delimita definiţia unei funcţii, care este un bloc de instrucţiuni şi
declaraţii. Un program descrie procedurile de obţinere a unor rezultate pe baza unor date iniţiale şi
foloseşte rezultate intermediare. Toate aceste date sunt memorate în variabile ale programului. Pot exista

20 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

şi date constante, ale căror valoari nu se pot modifica în cursul execuţiei. Toate variabilele folosite într-un
program trebuie definite sau declarate prin declaraţii ale limbajului de programare.
Un program C este compus în general din mai multe functii, dintre care functia "main" nu poate
lipsi, deoarece cu ea începe executia programului.
Functiile pot face parte dintr-un singur fisier sursã sau din mai multe fisiere sursã. Un fisier sursã
C este un fisier text care contine o succesiune de declaratii: definitii de functii si, eventual, declaratii de
variabile.
Antetul conţine tipul şi numele funcţiei şi o listã de argumente.
Practic nu existã program care sã nu apeleze functii din bibliotecile existente si care sã nu continã
definitii de functii specifice aplicatiei respective.
Motivele utilizãrii de subprograme sunt multiple:
 Un program mare poate fi mai usor de scris, de înteles si de modificat dacã este modular, deci
format din module functionale relativ mici.
 Un subprogram poate fi reutilizat în mai multe aplicatii, ceea ce reduce efortul de programare al
unei noi aplicatii.
 Un subprogram poate fi scris si verificat separat de restul aplicatiei, ceea ce reduce timpul de
punere la punct a unei aplicatii mari (deoarece erorile pot apare numai la comunicarea între
subprograme corecte).
 Intretinerea unei aplicatii este simplificatã, deoarece modificãrile se fac numai în anumite
subprograme si nu afecteazã alte subprograme (care nici nu mai trebuie recompilate).
Utilizarea de functii permite dezvoltarea progresiva a unui program mare, fie de jos în sus (“bottom
up”), fie de sus în jos (“top down”), fie combinat.

Exemplu: Modularizarea unui program utilizând subprograme. Să se scrie un program care pentru
un număr citit de la tastatură va determina daca e număr prim, perfect, va face suma divizorilor și va tipări
pătratul lui.

#include <iostream>
int sumad(int x)
{ int i,s=0;
for(i=1;i<x;i++)
if (x%i==0) s=s+i;
return s;
}
int prim(int x)
{int i,s;
s=0;
for(i=2;i<=x/2;i++)
if((x%i)==0) s=1;
if (x==1) s=1;
return s;
}
void perfect(int x, int sum,int &rez)
{
if(sum==x) rez=0;
else rez=1;
}
void main()

21 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel


Avizat, manager de proiect: Prof. univ.dr.ec.dr.ing. Edelhauser Eduard

{
int a,sum,r;
cout<<"Dati numarul "; cin>>a;
if (prim(a)==0) cout<<a<<" este prim";
else cout<<a<<" nu este prim";
sum=sumad(a);
cout<<endl<<"Suma divizorilor lui "<<a<<" este "<<sum;
perfect(a,sum,r);
if(r==0) cout<<endl<<a<<" este numar perfect";
else cout<<endl<<a<<" nu este numar perfect";
cout<<endl<<"Patratul lui este "<<a*a;
}

Schema modulelor este:

Modulul Sumad:
 subprogram de tip funcție;
 parametri de intrare: numărul de tip întreg - x;
 parametri de ieșire: nu are;
 scopul subprogramului: calcularea sumei divizorilor unui număr și returnarea lui ca rezultat al
funcției (tip intreg).

Modulul Prim:
 subprogram de tip funcție;
 parametri de intrare: numărul (tip intreg) - x;
 parametri de ieșire: nu are;
 scopul subprogramului: verificarea daca un număr este prim sau nu și returnarea ca rezultat al
funcției valoarea 0 dacă este prim și 1 dacă nu este prim.

Modulul Perfect:
 subprogram de tip procedura;
 parametri de intrare: numarul (tip intreg) - , suma divizorilor (tip intreg) - sum;
 parametri de ieșire: o variabilă a cărei valoare va fi 0 dacă este perfect sau 1 dacă numărul nu este
perfect - rez;
 scopul subprogramului: compararea numărului cu suma divizorilor săi și atribuirea unei valori
corespunzătoare parametrului de ieșire.

22 Întocmit: Conf.dr.ing. Stoicuța Olimpiu - Costinel

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