Teoriechevron_rightFuncții (Subprograme) și Funcții fără tip (void)

Teorie: Funcții (Subprograme) și Funcții fără tip (void)

Componentele unei funcții (tip returnat, nume, parametri). Diferența dintre funcțiile cu tip și void.

Nivel: Mediuschedule 40 min

functionsFuncții (Subprograme). Componente și Funcții fără tip (void)

În programare, o funcție (sau subprogram) este un bloc de cod reutilizabil, proiectat să îndeplinească o singură sarcină specifică. Când avem un program complex (cum ar fi la Subiectul III de la Bacalaureat), este mult mai eficient să-l împărțim în funcții mai mici.

Folosind funcții, evităm scrierea repetată a aceluiași cod, facem programul mai ușor de citit, de înțeles și de depanat (găsit erori).

view_in_ar1. Componentele unei Funcții (Antetul / Semnătura)

Orice funcție este definită prin antetul ei (prima linie) și corpul ei (instrucțiunile dintre acolade). Antetul specifică exact cum comunică funcția cu restul programului.

Tip_Returnat Nume_Functie(Lista_Parametri) {
// Corpul funcției...
}

1. Tipul Returnat

Specifică ce tip de dată "întoarce" funcția (ex: int, float, bool). Dacă funcția întoarce o valoare, trebuie să folosească instrucțiunea return.

2. Numele Funcției

Este un identificator (asemănător cu numele variabilelor) folosit pentru a "apela" (chema) funcția din main sau din alte părți.

3. Parametrii

"Datele de intrare" ale funcției, separate prin virgulă. Fiecare parametru trebuie să aibă specificat tipul lui (ex: int a, int b).

Exemplu de funcție cu tip (întoarce un rezultat):

// Primește 2 numere întregi și returnează suma lor (tot un întreg)
int suma(int a, int b) {
  int s = a + b;
  return s; // Valoarea 's' ia locul apelului funcției
}

block2. Funcții fără tip (void)

Dacă o funcție nu trebuie să "întoarcă" nicio valoare către programul care a apelat-o (de exemplu, o funcție care doar afișează un mesaj pe ecran, sau care modifică vectori prin referință), ea se declară cu tipul special void ("gol" în engleză).

Exemplu de funcție void (Afișează un divizor)

// Tipul 'void' înseamnă că nu avem 'return valoare;' la final
void afiseazaMesaj(int x) {
  cout << "Numărul este: " << x << endl;
  // Se poate folosi un 'return;' simplu (fără valoare) pentru a forța ieșirea din funcție, dar nu e obligatoriu la final.
}

Cum apelăm o funcție CU tip (int, bool)

Trebuie să capturăm rezultatul într-o variabilă sau să-l afișăm direct:

int x = suma(5, 3);
cout << suma(10, 20);

Cum apelăm o funcție FĂRĂ tip (void)

O apelăm pur și simplu ca pe o instrucțiune de sine stătătoare. Nu îi putem atribui o valoare!

afiseazaMesaj(50); // Corect
int x = afiseazaMesaj(50); // EROARE

integration_instructions3. Sintaxa declarațiilor (Prototipul) și a apelurilor

Declararea (Prototipul) vs Definiția

În C++, o funcție trebuie să fie "cunoscută" de compilator înainte de a fi apelată. Avem două variante:

  • Varianta 1 (Cea mai simplă): Scriem definiția completă a funcției (cu tot cu acolade și cod) deasupra funcției main().
  • Varianta 2 (Prototipul): Scriem doar declarația (prototipul) deasupra lui main(), urmată de punct și virgulă ;. Apoi, scriem definiția completă dedesubtul lui main(). Aceasta este utilă când avem multe funcții.
// Prototipul (Declarația)
int calculeazaProdus(int x, int y);

int main() {
  cout << calculeazaProdus(5, 4); // Apelul
  return 0;
}

// Definiția completă
int calculeazaProdus(int x, int y) {
  return x * y;
}

Apelul funcțiilor

Apelul înseamnă momentul când funcția este executată. Sintaxa este Nume_Functie(argument1, argument2).
Atenție: La apel, transmitem valori (sau variabile), NU tipul lor! Nu scriem niciodată calculeazaProdus(int 5, int 4) la apel.

visibility4. Domeniul de vizibilitate. Variabile Globale vs Locale

Locul unde declari o variabilă determină unde poate fi ea "văzută" și folosită în program. Acesta se numește domeniu de vizibilitate (scope).

Variabile Locale

Declarate în interiorul unei funcții (sau unui bloc de cod { ... }). Ele "trăiesc" și pot fi folosite doar acolo. Când funcția se termină, variabilele locale sunt distruse.

void test() {
  int x = 5; // Variabilă locală
}
// Aici, 'x' NU există.

Variabile Globale

Declarate în afara oricărei funcții (de obicei sus, sub #include). Ele pot fi văzute și modificate de orice funcție din program.

int G = 10; // Variabilă globală
void test() {
  G++; // Funcția 'vede' și modifică pe G
}

Comunicarea prin variabile globale și Efecte Colaterale

Deși funcțiile comunică în mod normal prin parametri (la intrare) și prin return (la ieșire), ele pot comunica și modificând direct variabile globale. Când o funcție modifică o variabilă globală, se spune că produce un efect colateral (side effect). Această practică trebuie folosită cu prudență, deoarece face programul greu de urmărit, însă la Bacalaureat este des întâlnită (ex: modificarea unui vector global într-o funcție void).

all_inclusive5. Recursivitatea (Introducere)

O funcție se numește recursivă dacă, în timpul execuției ei, se autoapelează (se cheamă pe ea însăși). Recursivitatea este o alternativă elegantă (dar uneori periculoasă) la buclele for sau while.

Orice funcție recursivă corectă are două elemente vitale:

  • Condiția de oprire (Cazul de bază): Când trebuie să se oprească din auto-apelare. Fără ea, funcția s-ar apela la infinit (provocând eroarea Stack Overflow).
  • Autoapelul: Apelul către ea însăși, dar cu date modificate (care o apropie pas cu pas de condiția de oprire).

Exemplu Clasic: Factorialul (N!)

// 5! = 5 * 4! (Calculat recursiv)
int fact(int n) {
  // 1. Condiția de oprire
  if (n == 0) {
    return 1;
  }
  // 2. Autoapelul (cu un pas mai aproape de 0)
  return n * fact(n - 1);
}

warningReguli vitale la Subiectul III (Bacalaureat)

  • Când folosești void: La Subiectul 3, cerința îți spune clar: "Subprogramul X furnizează prin parametrul P valoarea..." (atunci folosești `void` și parametru prin referință `&`) SAU "Subprogramul X returnează valoarea..." (atunci funcția va avea tip, ex: `int`, și vei folosi `return`).
  • Ordinea parametrilor: Numele și ordinea parametrilor trebuie să respecte EXACT cerința din subiect. Dacă cerința spune `f(n, a)`, nu poți declara funcția cu parametrii invers (`f(a, n)`).
  • Un singur return: Când o funcție cu tip (ex: `int`) ajunge la o instrucțiune `return`, ea se oprește instantaneu, chiar dacă era într-o buclă `for` sau `while`. Acest lucru este foarte util pentru a ieși rapid din funcții când am găsit ceea ce căutam.
syncSe încarcă statusul...