Sunteți pe pagina 1din 47

Funcii

Programarea calculatoarelor i
limbaje de programare I

Capitolul 7
Introducere
Am folosit deja funcii C++
atunci cnd am introdus rutinele
din bibliotecile standard,
amintind de sqrt i abs
Vom analiza n detaliu modul n
care programatorul poate s i
scrie o funcie, alta dect main

Programarea calculatoarelor i 2
limbaje de programare I
Sumar
1. Funcii void
2. Sintaxa i semantica funciilor void
3. Variabile locale
4. Parametri
5. Funcii recursive

Programarea calculatoarelor i 3
limbaje de programare I
Funcii void
Limbajul C++ folosete dou tipuri de
subprograme
funcii void
funcii care ntorc o valoare
Unele funcii complexe pot fi
implementate ca i colecii de module
Multe dintre acestea pot fi transpuse
sub forma unor funcii void

Programarea calculatoarelor i 4
limbaje de programare I
Scrierea modulelor ca funcii void
n principiu, o astfel de funcie arat ca
funcia main, cu deosebirea c header-ul
su folosete cuvntul cheie void n locul
lui int
O funcie void nu conine nicio instruciune
de tipul
return 0;
aa cum se ntmpl n cazul lui main, deci
nu ntoarce nicio valoare ctre apelant

Programarea calculatoarelor i 5
limbaje de programare I
Scrierea modulelor ca funcii void
Vom studia un program simplu care
folosete funcii void
Acest program tiprete textul
*************
*************
Welcome Home!
*************
*************
*************
*************

Programarea calculatoarelor i 6
limbaje de programare I
Scrierea modulelor ca funcii void
Iat cum putem schia un program
care s tipreasc acest mesaj
Nivelul 0
main
Tiprete dou linii de asteriscuri
Tiprete textul Welcome Home!
Tiprete patru linii de asteriscuri

Programarea calculatoarelor i 7
limbaje de programare I
Scrierea modulelor ca funcii void
Nivelul 1
Tipareste2Linii
Tiprete textul *************
Tiprete textul *************

Tipareste4Linii
Tiprete textul *************
Tiprete textul *************
Tiprete textul *************
Tiprete textul *************

Programarea calculatoarelor i 8
limbaje de programare I
Scrierea modulelor ca funcii void
Dac modulele de la nivelul 1 sunt scrise ca funcii
void, atunci programul se va scrie astfel
#include <iostream>
using namespace std;
void Tipareste2Linii();//prototip de functie
void Tipareste4Linii();//prototip de functie
int main()
{
Tipareste2Linii();//apel de functie
cout << "Welcome Home!" << endl;
Tipareste4Linii();//apel de functie
return 0;
}

Programarea calculatoarelor i 9
limbaje de programare I
Scrierea modulelor ca funcii void
Programul (continuare)
void Tipareste2Linii()
//Aceasta functie tipareste doua linii de asteriscuri
{
cout << "*************" << endl;
cout << "*************" << endl;
}
void Tipareste4Linii()
//Aceasta functie tipareste patru linii de asteriscuri
{
cout << "*************" << endl;
cout << "*************" << endl;
cout << "*************" << endl;
cout << "*************" << endl;
}

Programarea calculatoarelor i 10
limbaje de programare I
Scrierea modulelor ca funcii void
Se observ similaritatea dintre funcia main
i descrierea de la nivelul 0
Cele dou funcii care fac parte din corpul
funciei main sunt fara parametri
Fiecare dintre definiiile acestor funcii este
format din header-ul funciei urmat de un
bloc de instruciuni care alctuiesc corpul
funciei
Header-ul unei funcii void ncepe cu
cuvntul cheie void care semnaleaz c nu
ntoarce nicio valoare
Programarea calculatoarelor i 11
limbaje de programare I
Scrierea modulelor ca funcii void
n corpul unei astfel de funcii nu va aprea nicio
instruciune return urmat de o valoare
Se poate folosi, totui, instruciunea
return;
care ncheie execuia unei funcii void.
Definiiile funciilor pot aprea n orice ordine, deci
main ar fi putut aprea dup cele dou funcii
Cele dou declaraii dinaintea funciei main se numesc
prototipuri de funcii
Ele sunt necesare pentru c regulile din C++ impun
declararea unui identificator naintea folosirii sale

Programarea calculatoarelor i 12
limbaje de programare I
Sumar
1. Funcii void
2. Sintaxa i semantica funciilor void
3. Variabile locale
4. Parametri
5. Funcii recursive

Programarea calculatoarelor i 13
limbaje de programare I
Apelul funciilor (invocarea)
Un apel de funcie ntr-un program
nseamn execuia corpului funciei apelate
ablonul sintactic al apelului unei funcii
este urmtorul:
NumeFuncie(ListParametriActuali);
Parametri actuali
Parametrii dintr-un apel de funcie
Parametri formali
Parametrii care apar n header-ul funciei
Lista de parametri poate s fie vid

Programarea calculatoarelor i 14
limbaje de programare I
Apelul funciilor (invocarea)
Dac lista conine doi sau mai muli
parametri, acetia trebuie separai prin
virgul:
Expresie, Expresie ...
n momentul apelului unei funcii, parametrii
actuali sunt transmii parametrilor formali
conform poziiei lor, de la stnga la dreapta
Controlul este transferat apoi primei
instruciuni din corpul funciei
Cnd se ncheie i execuia ultimei
instruciuni din funcie, controlul este
transmis punctului n care s-a fcut apelul
Programarea calculatoarelor i 15
limbaje de programare I
Declaraii i definiii de funcii
O declaraie de funcie anun compilatorul despre
numele funciei
tipul de dat al valorii returnate (poate fi i void)
tipurile datelor folosite n lista de parametri
Prototipuri de funcii
Programul din exemplul de mai sus conine dou
declaraii de funcii care nu sunt nsoite de corpul
funciilor
Definiii de funcii
Declaraiile sunt nsoite i de corpul funciei
Toate definiiile sunt declaraii, dar nu toate
declaraiile sunt definiii

Programarea calculatoarelor i 16
limbaje de programare I
Declaraii i definiii de funcii
Prototipuri de funcii
Prototipul de funcie de mai numete n
unele limbaje i declaraie forward
Pentru o funcie void, ablonul sintactic al
unei declaraii este:
void NumeFuncie(ListParametriFormali);
Prototipul nu este nsoit de corpul funciei,
lista de parametri formali este opional i
declaraia se ncheie cu ;

Programarea calculatoarelor i 17
limbaje de programare I
Declaraii i definiii de funcii
Prototipuri de funcii
Lista parametrilor formali este opional i
are urmtoarea form:
TipData & NumeVariabil, TipDat & NumeVariabil ...
Ampersantul & este ataat tipului de dat i
este opional
ntr-un prototip de funcie, lista
parametrilor formali trebuie s specifice
tipurile de dat ale parametrilor
Numele lor poate s lipseasc

Programarea calculatoarelor i 18
limbaje de programare I
Declaraii i definiii de funcii
Prototipuri de funcii
Exemplu
void Traiectorie(int, double);
sau
void Traiectorie(int viteza, double unghi);

Numele parametrilor sunt utili pentru


explicitarea funciei
Compilatorul, ns, le ignor

Programarea calculatoarelor i 19
limbaje de programare I
Declaraii i definiii de funcii
Definiii de funcii
Definiia unei funcii const din
header-ul funciei
corpul funciei care este, de fapt, un bloc
ablonul sintactic al unei definiii de funcie este
void NumeFuncie(ListParametriFormali)
{
Instruciune
...
}
Header-ul funciei nu se ncheie cu ; ca la prototipurile de
funcii.
Sintaxa listei de parametri din definiie difer de cea folosit
n prototip
Aici trebuie specificate numele tuturor parametrilor formali
TipData & NumeVariabil, TipDat & NumeVariabil ...

Programarea calculatoarelor i 20
limbaje de programare I
Sumar
1. Funcii void
2. Sintaxa i semantica funciilor void
3. Variabile locale
4. Parametri
5. Funcii recursive

Programarea calculatoarelor i 21
limbaje de programare I
Variabile locale
Deoarece corpul unei funcii este un bloc,
orice funcie poate include declaraii de
variabile n interiorul ei
Aceste variabile se numesc variabile locale
pentru c sunt accesibile doar n interiorul
blocului n care sunt declarate
n contrast cu variabilele locale sunt
variabilele declarate n afara tuturor
funciilor i accesibile lor i se numesc
variabile globale
Programarea calculatoarelor i 22
limbaje de programare I
Variabile locale
Variabilele locale ocup spaiu de memorie
doar pe timpul execuiei funciei
Cnd funcia i ncheie execuia, variabilele
locale sunt terse din memoria
calculatorului
Acesta este motivul pentru care la fiecare
apel al unei funcii variabilele locale pornesc
cu valori nedefinite, deci trebuie iniializate
n interiorul funciei
Fiind terse din memorie dup ncheierea
apelului, valorile variabilelor locale nu se
pstreaz ntre dou apeluri de funcii

Programarea calculatoarelor i 23
limbaje de programare I
Sumar
1. Funcii void
2. Sintaxa i semantica funciilor void
3. Variabile locale
4. Parametri
5. Funcii recursive

Programarea calculatoarelor i 24
limbaje de programare I
Parametri
Atunci cnd se execut o funcie, ea folosete
parametrii actuali care i-au fost transmii prin apelul
su, innd, ns, cont de natura parametrilor formali
Limbajul C++ accept dou tipuri de parametri
formali
parametri valoare
parametri referin
Parametrii referin sunt cei pentru care tipul de dat
este nsoit, n lista parametrilor formali, de semnul &
Funcia primete adresa de memorie a parametrului
actual
Din declaraiile parametrilor valoare lipsete semnul &
Funcia primete o copie a valorii parametrului actual

Programarea calculatoarelor i 25
limbaje de programare I
Parametri
Tip de parametru Folosire
Parametru actual Apare n apelul funciei. Parametrii
corespunztori pot fi att valoare ct
i referin
Parametru valoare formal Apare n header-ul funciei. Primete
o copie a valorii pstrate n
parametrul actual corespunztor
Parametru referin formal Apare n header-ul funciei. Primete
adresa parametrului actual
corespunztor

Programarea calculatoarelor i 26
limbaje de programare I
Parametri
Numrul parametrilor actuali din apelul unei funcii
trebuie s fie egal cu numrul parametrilor formali din
header-ul funciei
Tipurile datelor trebuie s corespund
Exemplu
Header:
void ShowMatch(double num1, int num2, char letter);
Apel:
ShowMatch(varDouble, varInt, varChar);
Dac tipurile de dat nu se potrivesc, compilatorul
ncearc s aplice operaiile de cast
Pentru a evita aceste conversii implicite de tip, se pot
aplica i conversii explicite

Programarea calculatoarelor i 27
limbaje de programare I
Parametrii valoare
Deoarece parametrii valoare primesc copii
ale parametrilor actuali, se pot folosi
constante, variabile i expresii n apelul
unei funcii
Cnd funcia se ncheie, coninutul
parametrilor valoare este ters, la fel cum
se ntmpl n cazul variabilelor locale
Diferena dintre parametrii valoare i
variabilele locale este c cele din urm sunt
nedefinite la startul funciei, n timp ce
primele sunt iniializate automat cu valorile
corespunztoare ale parametrilor actuali

Programarea calculatoarelor i 28
limbaje de programare I
Parametrii referin
Parametrii valoare nu pot fi folosii
pentru a transmite informaie ctre
codul apelant pentru c valorile lor se
pierd la finalul execuiei funciei
Pentru aceasta se folosesc parametrii
referin
Prin intermediul parametrilor referin
funciei i se permite s modifice
valoarea parametrului actual

Programarea calculatoarelor i 29
limbaje de programare I
Parametrii referin
Dac parametrul unei funcii este de tip referin,
se transmite ctre funcie locaia (adresa de
memorie) i nu valoarea parametrului
Exist o singur copie a informaiei, folosit att
de apelant ct i de funcia apelat
Numele parametrului actual i cel al parametrului
formal devin sinonime pentru aceeai variabil
Ceea ce va lsa funcia n acea locaie va fi
regsit de funcia apelant
Ctre parametrii referin pot fi transmise doar
nume de variabile

Programarea calculatoarelor i 30
limbaje de programare I
Parametrii referin
Exemplu
Presupunem c variabila y este de tip double si
variabila i este de tip int
Header: void Functie2(double val, int& contor);

Apeluri corecte: Functie2(y, i);


Functie2(9.81, i);
Functie2(4.9*sqrt(y), i);
Apel incorect: Functie2(y, 3);

Programarea calculatoarelor i 31
limbaje de programare I
Parametrii referin
Pentru parametrii referin verificarea
tipurilor de dat ntre parametrii actuali i
cei formali se face n mod diferit fa de
parametrii valoare
Compilatorul copiaz valoarea parametrului
actual ntr-o variabil temporar de tip
corect i transmite aceast variabil
temporar parametrului formal
Cnd funcia se ncheie, variabila temporar
este tears din memorie i modificrile din
funcie nu se mai reflect n codul apelant
Programarea calculatoarelor i 32
limbaje de programare I
Parametri
Exemplu

int PatratPrinValoare(int);
void PatratPrinReferinta(int&);
int main()
{
int x = 2, z = 4;
cout << PatratPrinValoare(x) << endl;

PatratPrinReferinta(z);
cout << z << endl;
return 0;
}
int PatratPrinValoare(int a)
{
a = a * a;
return a;
}
void PatratPrinReferinta(int& b)
{
b = b * b;
}

Programarea calculatoarelor i 33
limbaje de programare I
Parametri
Parametrul referin este un nume
alternativ pentru argumentul corespondent
Apelul funciilor care au parametri valoare
este asemntor celui pentru funcii cu
parametri referin atunci cnd parametrii
sunt variabile
n ambele situaii se specific doar numele
variabilei, ns compilatorul stabilete pe
baza tipurilor parametrilor formali care
dintre cele dou mecanisme de transmitere
a parametrilor va fi invocat
Programarea calculatoarelor i 34
limbaje de programare I
Sumar
1. Funcii void
2. Sintaxa i semantica funciilor void
3. Variabile locale
4. Parametri
5. Funcii recursive

Programarea calculatoarelor i 35
limbaje de programare I
Funcii recursive
Programele pe care le-am scris pn
acum sunt structurate sub forma unor
funcii care apeleaz alte funcii ntr-o
manier ierarhic
n unele aplicaii, este util ca funciile
s se poat apela ele nsele
O funcie recursiv este o funcie care
se autoapeleaz

Programarea calculatoarelor i 36
limbaje de programare I
Funcii recursive
Rezolvarea problemelor prin recursie
presupune scrierea unei funcii care este
apelat recursiv
Aceast funcie rezolv doar cazul cel mai
simplu, numit i cazul de baz
Dac funcia este apelat pentru cazul de
baz, ea returneaz un simplu rezultat
Dac este apelat pentru un caz mai
complex, ea divide problema n dou
module conceptuale
o parte pe care funcia poate s o rezolve
o alt parte pe care nu poate s o rezolve

Programarea calculatoarelor i 37
limbaje de programare I
Funcii recursive
Pentru ca recursia s fie fezabil, partea
care nu poate fi rezolvat imediat trebuie
s fie asemntoare problemei originale,
dar s fie un caz mai simplu al acesteia
Aceast nou problem este o variant a
celei originale, iar funcia va lansa o nou
copie a sa pentru a o trata
Este vorba, deci, de un apel recursiv sau de
un pas de recursie

Programarea calculatoarelor i 38
limbaje de programare I
Funcii recursive
Pasul de recursie trebuie s includ i o
instruciune return pentru c rezultatul su
va fi combinat cu partea pe care funcia
poate s o rezolve pentru a forma rezultatul
final care este transmis codului apelant
Pasul de recursie se execut n timp ce
apelul original este nc activ, acesta nefiind
finalizat
Un apel recursiv poate s genereze la
rndul su alte apeluri recursive pe msur
ce noua problem se divide la rndul su n
dou alte noi probleme

Programarea calculatoarelor i 39
limbaje de programare I
Funcii recursive
Pentru ca recursia s aib finalitate, de
fiecare dat funciile se apeleaz pe ele
nsele cu versiuni din ce n ce mai simple
ale problemei originale
Aceast secven trebuie conceput n aa
fel nct s convearg ctre cazul de baz
La acest punct, funcia recunoate cazul de
baz i se declaneaz o serie de return-uri
n secven invers apelurilor, pn la
apelul original
Programarea calculatoarelor i 40
limbaje de programare I
Funcii recursive
Factorialului unui numr ntreg nenegativ n, notat prin
n! este dat de produsul
n(n-1) (n-2) ...1
cu 0!=1.
Aceast valoare se poate calcula iterativ (nerecursiv)
folosind o bucl while:
int factorial = 1;
int counter = n;
while(counter >= 1)
{
factorial = factorial * counter;
counter--;
}

Programarea calculatoarelor i 41
limbaje de programare I
Funcii recursive
O definiie recursiv a acestei operaii
este dat prin relaia
n! = n (n-1)!
Pentru 5! putem scrie:
5! = 5 4 3 2 1
5! = 5 (4 3 2 1)
5! = 5 (4!)

Programarea calculatoarelor i 42
limbaje de programare I
Funcii recursive
5! Valoarea final 120
5!

5 * 4! Returneaz 5!=120
5 * 4!
Returneaz 4!=24
4 * 3!
4 * 3!

3 * 2! Returneaz 3!=6

3 * 2!

Returneaz 2!=2
2 * 1!
2 * 1!

1 Returneaz 1
1

Programarea calculatoarelor i 43
limbaje de programare I
Funcii recursive
int main()
{
int n;
cout << "Introduceti numarul pentru care se"
<< " calculeaza factorialul: ";
cin >> n;
cout << n << "! = " << Factorial(n) << endl;
return 0;
}
int Factorial(int val)
{
if(val <= 1) //cazul de baza
return 1;
else
return val * Factorial(val - 1);
}

Programarea calculatoarelor i 44
limbaje de programare I
Funcii recursive
Recursie i iteraie
Ambele tehnici se bazeaz pe cte o
structur de control
Iteraia folosete o structur
repetitiv
Recursivitatea folosete o structur
de selecie
Recursivitatea implementeaz
repetiia prin apelurile repetate ale
aceleiai funcii.
Programarea calculatoarelor i 45
limbaje de programare I
Funcii recursive
Recursie i iteraie
n ambele cazuri este nevoie de un test de
terminare
Iteraia se termin atunci cnd testul buclei devine
fals
Iteraia modific un contor care controleaz o
bucl
Recursia se termin atunci cnd se ajunge la cazul
de baz
Recursivitatea produce versiuni ale problemei
originale pn cnd se ajunge la cazul de baz
Att iteraia ct i recursia pot degenera n bucle
infinite dac testul de final nu este scris corect

Programarea calculatoarelor i 46
limbaje de programare I
Funcii recursive
Recursie i iteraie
Recursia are dezavantajul c invoc n mod
repetat mecanismul de apel al funciilor
Acesta presupune
ocuparea suplimentar a spaiului de memorie
timp de procesor pentru ca la fiecare apel se
creeaz un nou set al parametrilor formali
Recursivitatea este un mecanism important
din punct de vedere al ingineriei software
pentru c permite structurarea ntr-o
maniera mult mai judicioas a anumitor
secvene de program

Programarea calculatoarelor i 47
limbaje de programare I

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