Subprograme: definire și apel
Antetul, corpul, valoarea returnată și cum citești o cerință de tip „scrieți subprogramul" din enunțul de bac.
De ce
Un subprogram (funcție) este o bucată de program cu un nume, care poate fi apelată de oriunde. Rezolvă trei probleme:
Repetiția. Dacă testezi de cinci ori dacă un număr e prim, scrii algoritmul o dată și îl apelezi de cinci ori.
Claritatea. if (esteprim(x)) se înțelege dintr-o privire. Cinci linii cu bucle nu se înțeleg la fel de repede.
Cerința examenului. La Subiectul III scrie explicit „scrieți definiția completă a subprogramului …", deci nu ai de ales.
Forma
tip nume(listă de parametri) {
// corpul
return valoare;
}int patrat(int x) {
return x * x;
}int: tipul valorii returnate.patrat: numele cu care va fi apelată.int x: parametrul, adică ce primește funcția.return: ce trimite funcția înapoi. Tot el o și oprește.
Apelul:
int a = patrat(5); // a devine 25
cout << patrat(a + 1); // se calculează întâi a+1Unde se scrie
O funcție trebuie să fie cunoscută înainte de a fi apelată. Cel mai simplu este s-o scrii înaintea lui main:
#include <iostream>
using namespace std;
int patrat(int x) {
return x * x;
}
int main() {
cout << patrat(7);
return 0;
}Funcții fără rezultat
Dacă funcția face ceva, dar nu are ce întoarce, tipul ei este void:
void afiseazaVector(int v[], int n) {
for (int i = 1; i <= n; i++)
cout << v[i] << " ";
cout << "\n";
}O apelezi ca pe o instrucțiune separată: afiseazaVector(v, n);. Dacă vrei să ieși mai devreme din ea, scrii return; fără valoare.
return oprește funcția
După ce se execută un return, restul funcției nu se mai execută. Pe asta se sprijină un tipar util:
bool esteprim(int n) {
if (n < 2) return false;
for (int d = 2; d * d <= n; d++)
if (n % d == 0)
return false; // am aflat răspunsul, ies imediat
return true;
}Funcția are trei return-uri, dar la fiecare apel se execută exact unul.
Orice drum prin funcție trebuie să ajungă la un return. Dacă o ramură nu returnează nimic, funcția întoarce o valoare imprevizibilă. Compilatorul, în cel mai bun caz, îți dă doar un avertisment.
Parametri și argumente
Parametrii sunt numele din antet. Argumentele sunt valorile date la apel.
int suma(int a, int b) { return a + b; } // a, b sunt parametri
...
cout << suma(3, x); // 3 și x sunt argumenteArgumentele trebuie să corespundă parametrilor ca număr și ca tip, în aceeași ordine. suma(3) nu compilează.
Variabile locale
O variabilă declarată în interiorul unei funcții există numai acolo:
int sumaCifrelor(int n) {
int s = 0; // s există doar în această funcție
while (n > 0) {
s += n % 10;
n /= 10;
}
return s;
}Două funcții pot avea fiecare câte un s, fără nicio legătură între ele. La fel, n de aici este o copie: bucla îl distruge, dar variabila din main rămâne neatinsă. Revenim la asta în lecția despre parametri.
Cum arată cerința la bac
Enunțul dă antetul și îți cere corpul. De exemplu:
> Subprogramul nrdiv primește prin parametrul n un număr natural nenul și returnează numărul divizorilor lui n.
Din text extragi tot ce-ți trebuie:
- numele:
nrdiv - parametrul:
n, număr natural - ce returnează: un număr → tipul este
int
int nrdiv(int n) {
int cati = 0;
for (int d = 1; d * d <= n; d++)
if (n % d == 0) {
cati++;
if (d != n / d) cati++;
}
return cati;
}Câteva reguli de punctaj care se uită des:
Respectă numele și ordinea parametrilor din enunț. Corectorul verifică antetul.
Nu citi și nu afișa nimic în subprogram, dacă enunțul nu cere. Un subprogram care face cin >> n în loc să folosească parametrul este greșit, chiar dacă „merge".
Nu folosi variabile globale dacă enunțul nu le menționează.
Descompunerea unei probleme
Se citesc n numere. Să se afișeze câte dintre ele au suma cifrelor un număr prim.
Cu două subprograme, programul principal rămâne scurt și se citește ușor:
int sumaCifrelor(int n) { ... }
bool esteprim(int n) { ... }
int main() {
int n, x, cate = 0;
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> x;
if (esteprim(sumaCifrelor(x)))
cate++;
}
cout << cate;
return 0;
}esteprim(sumaCifrelor(x)) se citește exact ca enunțul. Așa îți dai seama că ai descompus bine problema: numele funcțiilor spun ce face programul, fără să te uiți în corpul lor.
De reținut
- Antetul dă tipul returnat, numele și parametrii. Corpul face treaba.
returnîntoarce valoarea și oprește funcția pe loc.- Fiecare drum prin funcție trebuie să ajungă la un
return. - Variabilele locale există doar în funcția lor.
- La bac: respectă antetul din enunț, nu citi și nu afișa în subprogram.