FunctiiFunctie = Bloc de instructiuni, care are asociat un nume,
- poate fi apelat (executat), prin intermediul numelui sau, din
orice loc al aplicatiei, unde numele este cunoscut;
- poate avea o lista de parametrii (argumente), prin
intermediul careia se transmit valorile de apel, folosite in
general ca date initiale ce se prelucreaza in functie
-poate returna o valoare, prin intermediul instructiunii
return
Sintaxa declaratie functie = se anunta existent numelui si a modului de
apelare (tipul retunat, numarul si tipul parametrilor)
tip_returnat nume_functie(lista_tipuri_argumente);
Exemplu: int val_max(int,int);
Funcții
Sintaxa definitie functie = se defineste continutul functiei, respective blocul de instructiuni care descriu prelucrarea datelor
tip_returnat nume_functie(lista_argumente)
{
bloc de instrunctiuni
}
Exemplu: int val_max(int a,int b)
{
if(a>b)
return a;
return b;
}
Sintaxa apel functie = in orice loc al aplicatie in care numele de functieeste cunoscut, se poate executa blocul functei prin apelare sa:
. . . . . .
. . . nume_functie(lista_argumente_REALE)...
. . . . . .
Exemplu: int main()
{
int n1 = 6, n2 = 9;
cout << val_max(n1,n2);
return 0;
}
Funcții
Functii de tip void = funcții care NU returneaza o valoare= tipul returnat este void.
Corpul functiei poate sa nu contina instructiune de return.
Daca se doreste iesirea fortata din functie, atunci se da instructiunea return fara argument.
Sintaxa: void nume_functie(lista_argumente)
Exemplu: void afisare_rez(int a)
{ cout << a << endl;
}
int main()
{ int n1=6, n2=9;
afisare_rez(val_max(n1,n2));
return 0;
}
Funcții
Argumente formale. Argumente reale
Argumentele formale = variabilele definite in lista de parametrii ai
functiei.
reprezinta variabile locale definite in
interiorul blocului functiei
Exemplu:
int val_max(int a,int b)
{
if(a>b)
return a;
return b;
}
int main()
{
int n1=6, n2=9;
cout<<val_max(n1,n2);
return 0;
}
Funcții. Argumente formale. Argumente reale
Argumentele formale = variabilele definite in lista de parametrii ai
functiei.
reprezinta variabile locale definite in
interiorul blocului functiei
Argumentele reale = parametrii de apel = variabilele care sunt
transferate care functie in momentul apelului
valorile care vor fi prelucrate efectiv in functie
Exemplu:
int val_max(int a,int b)
{
if(a>b)
return a;
return b;
}
int main()
{
int n1=6, n2=9;
cout<<val_max(n1,n2);
return 0;
}
Funcții. Argumente formale. Argumente reale
In momentul apelului de functie:
1. Se salveaza in stiva:
- adresa de revenire din apel (= adresa
urmatoarei instructiuni dupa apel)
- valorile variabilelor reale (transmise la apel)
2. Se aloca variabilele locale pentru parametrii formali
3. Se copiaza valorile parametrilor reali in variabilele parametrii
formali
4. Salt la adresa functiei, se executa instructiunile blocului functiei
5. Alocare in stiva variabile locale proprii functiei
STIVA program
Variabile locale
Valori variabile apel (reale)
Spatiu pentru rezultat return
Adresa de revenire
Mecanismul apelului de functie
Funcții. Mecanismul apelului de funcție
La revenirea din apelul de functie:
1. Daca functia returneaza valoare
salveaza in stiva (zona temporara) valoarea
2. Se distrug variabilele locale,
inclusive cele care reprezinta parametrii formali
3. Se evalueaza expresia in care este implicat rezultatul functiei
4. Salt la adresa de revenire pentru continuarea executarii programului
dupa apelul de functie
5. Eliberarea restului de stiva
STIVA program
Variabile locale
Valori variabile apel (reale)
Spatiu pentru rezultat return
Adresa de revenire
Funcții. Mecanismul apelului de funcție
Functii recursive
= functie care se autoapeleaza
Recursivitatea poate fi simpla sau multipla
Exemplu: int factorial(n)
{
if (n)
return n*factorial(n-1);
return 1;
}
Observatii: Recursivitatea se utilizeaza in aplicatii diverse: - implementarea tehnicii „divide et impera” - inversarea ordinii de parcurgere
Funcții. Funcții recursive.
Valori implicite pentru argumentele unei functii.
= Valorile cu care se initializeaza in mod implicit argumentele formaleale unei functii, atunci cand la apel lipsesc argumentul reale.
• Numai argumentele de la sfarsitul listei de parametrii pot fi definite (initializate) implicit (arg. fara initializare implicita si cei cu initializare implicita nu pot fi amestecate).
• Regula ramane valabila si la apel: daca unul dintre argumente se doreste sa fie transmis explicit, atunci toti cei anteriori lui vor fi transmisi explicit (transferul arg reale catre cele formale se face in ordinea listei, nu putem sari peste unul dintre ele, care sa fie initialiatimplicit, apoi sa continuam cu urmatorul)
Funcții. Valori implicite pentru argumentele unei functii
Sintaxa: tip_returnat nume_fct(tip1 v1, tip2 v2=val2, tip3 v3=val3){
. . . . . .
}
Apel: nume_fct(w1,w2,w3);// v1=w1,v2=w2,v3=w3
nume_fct(w1,w2);// v1=w1,v2=w2,v3=val3
// NU se poate v1=w1,v2=val2,v3=w2
nume_fct(w1); v1=w1,v2=val2,v3=val3
Funcții. Valori implicite pentru argumentele unei functii
Exemplu:
double dist2pct( double x1, double x2,
double y1=0, double y2=0,
double z1=0, double z2=0)
{
double dx=x1-x2, dy=y1-y2, dz=z1-z2;
return sqrt(dx*dx+dy*dy+dz*dz);
}
astfel s-a implementat o functie generala pentru calcularea distanteiintre puncte din 3 spatii: 1D, 2D, 3D
dist2pct(5,10); // pct 1D
dist2pct(1,2,5,9); //pct 2D
dist2pct(1,2,3,5,6,7); pct 3D
Funcții. Valori implicite pentru argumentele unei functii
Pointeri la functii
O functie este stocata intr-o zona de memorie separata, adresa sa de
inceput se poate stoca intr-un pointer, numit pointer la functie.
Sintaxa: tip_returnat (*nume_pFct)(tip_arg1,tip_arg2…)
Se utilizeaza atunci cand sunt mai multe functii similare (ac. tip returnat
ac. lista de arg) si se doreste apelarea lor “generalizata” printr-un
mecanism de selectie, fara a schimba sintaxa (numele) de apel.
Funcții. Pointeri la functii
Exemplu 1:
float adun(float a, float b)
{ return a+b;
}
float inm(float a, float b)
{ return a*b;
}
int main()
{ int op=2;
float (*pfct)(float,float); //definire
switch op
{ case 1: pfct=adun; //atribuire val; initializare
break;
case 2: pfct=inm;
break;
}
cout<<“rezultat=”<<pfct(3,5)<<endl; // apel
}
Funcții. Pointeri la functii
Exemplu 2: Calculul integralei functiilor:
#include <math.h>
double sinxp();
double trapez(double a,double b,int n,double(*f)())
{ double h,s;
int i;
h=(b-a)/n;
for(s=0.0,i=1;i<n;i++)
s+=(*f)(a+i*h);
s+=((*f)(a)+(*f)(b))/2.0;
s*=h;
return s;
}
Funcții. Pointeri la functii
Exemplu 2: Calculul integralei functiilor:
int main()
{ int n=N;
double In,I2n,vabs;
In=trapez(a,b,n,sinxp);
do { n*=2;
I2n=trapez(a,b,n,sinxp);
if((vabs=In-I2n)<0) vabs=-vabs;
In=I2n;
} while(vabs > eps);
printf(“%6.2lf\n”, I2n);
}
Funcții. Pointeri la functii
Tema: Sa se implementeze o functie care calculeaza lungimea unui
drum care trece prin n puncte de coordonate (xi, yi).
Functia trebuie sa fie capabila sa calculeze lungimea
respectiva folosind diferite metrici: Euclidiana, Manhattan
(taxicab),Cebisev (chessboard)
Funcții. Pointeri la functii
Supraincarcarea functiilor
= definirea mai multor functii cu acelasi nume, in acelasi domeniu de
definitie (scope).
La apel, diferentierea lor se face pe baza
numarului si tipului argumentelor
Funcții. Supraincarcarea functii
Obs.:
1. Diferentierea functiilor cu acelasi nume NU se poate face pebaza tipului returnat
2. Mecanismul de supraincarcarea functiilor se poate aplicafunctiilor definite in acelasi domeniu, in caz contrar functiadefinita in domeniul local o ascunde pe cea definita in domeniulglobal (mecanism similar variabilelor)
Ex.: int fct(char*);
void g()
{ extern int fct(int);
fct(“abc”); // EROARE nu exista ac. fct
}
Funcții. Supraincarcarea functii
Diferentierea functiilor supraincarcate la apel
1. Daca prin tipul si/sau numarul argumentelor de apel (reale) se poate determina o functie care se potriveste perfect (are exact acelasi numar si aceleasi tipuri de argumente), atunci se executa respectiva functie.
2. Altfel, se cauta functia cu “cea mai buna potrivire” prin aplicarea regulilor de promovare implicita a tipului (cast automat) argumentelor de apel catre tipul parametrilor formali ai functiilor.
3. Daca nici prin promovarea implicita nu se poate determina o functie de apel se obtina eroare la compilare (caz fericit). Daca definirea functiilor nu se face cu atentie si nu se are in vedere modul de selectie la apel, e posibil sa apara erori de calcul nesemnalate (caz nefericit) , adica se va apela o alta functie in locul celei dorite.
Funcții. Supraincarcarea functii
Exemplu: int fct(int,int);
double fct(int,int); EROARE,dif numai tip ret
double fct(double,double);
int main()
{ int a=1,b=3;
float c=1.2;
double d=2.3,e=4.5;
char t=‘a’;
a=fct(a,b); // fct(int,int)
a=fct(d,e); // fct(double,double),tip a
// nu conteaza
a=fct(c,d); // fct(double,double)
// float -> double
a=fct(t,b); // fct(int,int)
// char -> int
a=fct(t,d); // TEMA
a=fct(a,d); // TEMA
} // Tema: similar cu 3 param, apel fct(int,int,double)
Funcții. Supraincarcarea functii
Lansarea in executie a unei aplicatii
1. Lansarea fara parametrii:
nume_aplicatie
In aceasta situatie, functia main a programului are lista vida de
argumente:
int main ()
{ . . . .
Funcții. Lansarea in executie a unei aplicatii