Funcții - noțiuni de bază
Până acum, tot codul nostru a fost scris în funcția
main(). Dar pe măsură ce programele devin mai
complexe, avem nevoie să împărțim codul în
bucăți mai mici, fiecare cu un rol clar.
Aceste bucăți se numesc funcții (sau subprograme).
De ce avem nevoie de funcții?
Imaginează-ți că ai un program care verifică dacă un număr e prim în 5 locuri diferite. Fără funcții, copiezi aceleași 10 linii de 5 ori. Cu funcții, le scrii o singură dată și le apelezi de câte ori vrei.
Funcțiile ne ajută să:
- Evităm repetarea codului
- Organizăm programul în bucăți logice
- Testăm fiecare parte separat
- Citim codul mai ușor
Primul exemplu
#include <iostream>
using namespace std;
void salut() {
cout << "Buna ziua!" << endl;
}
int main()
{
salut();
salut();
salut();
return 0;
}Output:
Buna ziua!
Buna ziua!
Buna ziua!Ce se întâmplă?
- Am definit funcția
salut()- un bloc de cod cu un nume. - În
main(), am apelat funcția de 3 ori. - La fiecare apel, programul “sare” la codul funcției, îl execută, apoi revine.
Structura unei funcții
tip_returnat nume_functie(parametri) {
// corpul funcției
}
| Parte | Ce înseamnă |
|---|---|
tip_returnat |
Ce tip de valoare returnează funcția (void dacă
nu returnează nimic) |
nume_functie |
Numele pe care îl alegem (ca la variabile) |
parametri |
Datele pe care le primește funcția (opțional) |
corpul |
Instrucțiunile care se execută la apel |
Funcții
void (fără valoare returnată)
O funcție void face ceva dar nu
întoarce un rezultat. E ca un ordin: “afișează asta”, “desenează
aia”.
void afiseazaLinie() {
cout << "-------------------" << endl;
}
int main()
{
afiseazaLinie();
cout << "Titlu" << endl;
afiseazaLinie();
return 0;
}Output:
-------------------
Titlu
-------------------Funcții cu parametri
Parametrii sunt datele pe care le trimitem funcției. Funcția le folosește în corpul ei.
void afiseazaNume(char nume[]) {
cout << "Salut, " << nume << "!" << endl;
}
int main()
{
afiseazaNume("Ana");
afiseazaNume("Mihai");
afiseazaNume("Elena");
return 0;
}Output:
Salut, Ana!
Salut, Mihai!
Salut, Elena!Mai mulți parametri
void afiseazaSuma(int a, int b) {
cout << a << " + " << b << " = " << a + b << endl;
}
int main()
{
afiseazaSuma(3, 5);
afiseazaSuma(10, 20);
return 0;
}Output:
3 + 5 = 8
10 + 20 = 30Funcții care returnează o valoare
O funcție poate calcula ceva și
întoarce rezultatul cu return.
int dublu(int x) {
return x * 2;
}
int main()
{
int a = dublu(5);
cout << a << endl;
cout << dublu(13) << endl;
return 0;
}Output:
10
26Cum funcționează
return?
return valoare;oprește funcția și trimitevaloareînapoi la locul apelului.- Tipul valorii trebuie să corespundă cu tipul declarat al
funcției (
intreturneazăint).
int maxim(int a, int b) {
if (a > b)
return a;
else
return b;
}
int main()
{
cout << maxim(7, 12) << endl;
cout << maxim(100, 3) << endl;
return 0;
}Output:
12
100Funcții care returnează
bool
Foarte utile pentru verificări:
bool estePar(int n) {
if (n % 2 == 0)
return true;
else
return false;
}
int main()
{
if (estePar(8))
cout << "8 este par" << endl;
if (!estePar(7))
cout << "7 nu este par" << endl;
return 0;
}Output:
8 este par
7 nu este parPrescurtare: funcția estePar se
poate scrie și return n % 2 == 0; - expresia
n % 2 == 0 este deja true sau
false.
Ordinea în program
Funcțiile trebuie definite înainte de a fi
apelate. De obicei le punem deasupra lui
main():
#include <iostream>
using namespace std;
// Funcțiile aici, deasupra lui main
int patrat(int x) {
return x * x;
}
int main()
{
cout << patrat(5);
return 0;
}Declarare vs Definire
Alternativ, putem pune doar declarația (prototipul) deasupra și definiția dedesubt:
int patrat(int x); // declarație (prototip)
int main()
{
cout << patrat(5);
return 0;
}
int patrat(int x) { // definiție
return x * x;
}Ambele variante sunt corecte. La concursuri, cel mai simplu e
să pui funcțiile deasupra lui main.
Exemplu complet: verificare număr prim
#include <fstream>
using namespace std;
ifstream fin("date.in");
ofstream fout("date.out");
bool estePrim(int n) {
if (n < 2) return false;
for (int d = 2; d * d <= n; d++) {
if (n % d == 0) return false;
}
return true;
}
int main()
{
int n;
fin >> n;
for (int i = 2; i <= n; i++) {
if (estePrim(i))
fout << i << " ";
}
return 0;
}date.in:
30date.out:
2 3 5 7 11 13 17 19 23 29Funcția estePrim ascunde
complexitatea verificării. main rămâne curat și
ușor de citit.
Greșeli frecvente
1. Apelarea funcției fără paranteze
salut; // GREȘIT - nu apelează funcția
salut(); // CORECT2. Uitarea
lui return într-o funcție non-void
int dublu(int x) {
int rez = x * 2;
// lipsește: return rez;
}Funcția nu întoarce nimic - rezultatul e imprevizibil.
3. Tipul parametrilor nu corespunde
int suma(int a, int b) { return a + b; }
suma(3.5, 2.1); // trimitem double, funcția așteaptă int - se pierd zecimalele4. Funcția definită după
main()
int main()
{
salut(); // EROARE - salut nu e definit încă
return 0;
}
void salut() { cout << "Salut"; }Pune funcțiile deasupra lui
main.
Ce să reții
- O funcție este un bloc de cod cu un nume, pe care îl putem apela de mai multe ori.
void- funcție care nu returnează nimic.return- trimite o valoare înapoi la locul apelului.- Parametrii sunt datele pe care funcția le primește.
- Funcțiile se definesc deasupra lui
main(). - Cu funcții, codul devine mai curat, mai organizat și mai ușor de citit.