Documente Academic
Documente Profesional
Documente Cultură
Ce este o funcţie?
O funcţie este un grup de instrucţiuni apelabil (invocabil) din alte părţi ale programului. De
exemplu, main este o funcţie.
A apela o funcţie înseamnă a o executa.
Funcţiile ajută la modularizarea programului, la structurarea acestuia în unităţi logice.
O funcţie se declară în felul următor:
int main()
{
int x, y;
cout << "Da-mi doua numere intregi: ";
cin >> x >> y;
cout << "Suma lor este " << suma(x, y);
return 0;
}
int main()
{
// Se va afisa de 5 ori textul:
// Hello functions!
afiseazaText();
return 0;
}
Puteţi declara şi defini o funcţie în acelaşi loc, dar numai înainte de main, altfel compilatorul nu
va recunoaşte funcţia.
Funcţiile void nu pot fi folosite în expresii, deoarece expresiile au în componenţa lor operatori
care aşteaptă valori, ori o funcţie void nu returnează nicio valoare.
O funcţie poate avea orice număr de parametri.
Variabilele declarate într-o funcţie sunt locale, adică sunt vizibile numai în respectiva funcţie.
Ele nu pot fi folosite în afara ei (valabil şi pentru parametri).
Argumentele funcţiei sunt datele (variabile, expresii, constante, etc.) transmise funcţiei şi primite
de parametrii acesteia.
De exemplu, în apelul suma(x, y); argumentele sunt variabilele x şi y.
Parametrii unei funcţii pot avea valori implicite (default). Parametrii default trebuie poziţionaţi la
sfârşitul listei de parametri.
După ce aţi declarat un parametru implicit, nu mai aveţi voie să declaraţi parametri normali în
continuare acestuia, ci doar parametri impliciţi.
#include <iostream>
using namespace std;
int main()
{
cout << "Aria cercului de raza 2 este " << arieCerc(2.0) << '\n'; // PI
== 3.14
cout << "Aria cercului de raza 2 este " << arieCerc(2.0, 3.141592);
return 0;
}
Se va afişa
Aria cercului de raza 2 este 25.12
Aria cercului de raza 2 este 25.1327
Când nu transmiteţi o valoare parametrului implicit, compilatorul va folosi valoarea implicită,
dată de voi.
#include <iostream>
using namespace std;
void modifica(int a)
{
a = a + 5;
cout << "a are valoarea: " << a << '\n';
}
int main()
{
int x = 1;
cout << "x inainte de apel: " << x << '\n';
modifica(x);
cout << "x dupa apel: " << x;
return 0;
}
Output:
x inainte de apel: 1
a are valoarea: 6
x dupa apel: 1
O funcţie poate returna decât o singură valoare printr-un return, ca la matematică.
Uneori vrem ca o funcţie să poată returna mai multe valori. Un mod prin care putem obţine acest
lucru este transmiterea prin referinţă (pass by reference).
Atunci când transmiteţi prin referinţă, parametrii funcţiei alterează direct conţinutul variabilelor
argumente (nu mai există nicio copie).
Ca să transmiteţi prin referinţă folosiţi ampersand (&) între tipul parametrului şi numele acestuia.
Parametrii referinţă acceptă numai variabile. NU acceptă constante (deoarece nu pot fi alterate)!
#include <iostream>
using namespace std;
int main()
{
int x = 1;
cout << "x inainte de apel: " << x << '\n';
modifica(x);
cout << "x dupa apel: " << x;
return 0;
}
Output:
x inainte de apel: 1
a are valoarea: 6
x dupa apel: 6
#include <iostream>
using namespace std;
int main()
{
int w[] = {1, 2, 3, 4}, k = 4;
modifica(w, k);
return 0;
}
Output:
6 7 8 9
Observaţi cum se transmite un vector ca parametru.
Numărul de elemente poate lipsi (valabil doar pentru prima dimensiune).
Dacă aş fi avut o matrice de 2 x 3, atunci aş fi scris:
void modifica(int v[][3], ...) ...
Veţi înţelege mai bine aceste lucruri după ce veţi învăţa ceva despre pointeri.
Funcţii recursive
O funcţie care se autoapelează se numeşte recursivă.
Aveţi grijă ca funcţia să aibă o condiţie de terminare, altfel puteţi crea o repetiţie infinită.
Parametrii funcţiilor şi variabilele locale sunt încărcate, stocate, pe Stivă (o regiune din memorie
structurată pe principiul stivei, LIFO), iar în cazul unei funcţii recursive infinite, Stiva se poate
umple repede (stack overflow) cauzând un crash al programului.
Factorialul unui număr poate fi calculat cu o funcţie recursivă (deşi se poate face acelaşi lucru şi
cu un loop).
#include <iostream>
using namespace std;
int fact(int n)
{
if (n == 0) // Conditia de terminare
return 1;
else
return n * fact(n - 1);
}
int main()
{
cout << fact(0) << '\n';
cout << fact(3) << '\n';
cout << fact(8) << '\n';
return 0;
}
Output:
1
6
40320
Ca să înţelegeţi mai bine mecanismul recursivităţii vizionaţi acest clip de pe Youtube:
Funcţii inline
Atunci când o funcţie este apelată, parametrii şi variabilele locale sunt încărcate pe Stivă.
Acest proces consumă resurse şi timp de execuţie.
Pentru funcţiile ce efectuează puţine operaţii, apelarea poate costa mai mult timp şi spaţiu de
execuţie decât dacă aceste operaţii ar fi executate direct în cod.
Din acest motiv există keyword-ul inline.
Cu inline programatorii pot cere compilatorului să insereze blocul funcţiei în punctul apelării,
în loc să creeze instrucţiunile de apel.
O funcţie se declară inline în felul următor:
#include <iostream>
using namespace std;
int main()
{
cout << myPI();
return 0;
}
Nu declaraţi inline funcţii recursive sau funcţii complexe!
Mărimea programului poate creşte considerabil.
Compilatoarele moderne de astăzi optimizează automat codul sursă.
Unele dintre ele vor refuza inline, chiar dacă programatorul le cere explicit (de exemplu,
compilatoarele care optimizează mărimea programului), altele vor face automat inline anumite
funcţii (compilatoarele optimizate pentru viteză), chiar dacă programatorul nu cere acest lucru.