InfoBook.ro ← Harta anului
Modul 05a · Subprograme
Modul 05a · Conținut 3.1

Cod scris o dată, folosit oricând

Subprogramele (funcțiile) sunt „rețetele" programării: le scrii o singură dată, le apelezi de câte ori vrei, cu ingrediente diferite. De aici începe programarea modulară — și jumătate din subiectul III de BAC.

🎯 Obiectiv 1Cunoști cele 4 componente: antet, parametri, corp, valoare de întoarcere.
🎯 Obiectiv 2Alegi corect între void (acțiune) și return (rezultat) și înțelegi parametrii formali vs efectivi.
🎯 Obiectiv 3Stăpânești transmiterea prin valoare vs referință (&) și variabilele locale vs globale.
1

Ce e un subprogram — analogia „rețetei"

O colecție de instrucțiuni care îndeplinesc o sarcină, grupate sub un nume. Ca o rețetă de prăjitură: o scrii o dată, o folosești mereu — cu ingrediente diferite.

1️⃣ Antetul

Numele funcției + lista de parametri. Cartea de vizită.

2️⃣ Parametrii

„Ingredientele" pe care le primește la fiecare apel.

3️⃣ Corpul

Instrucțiunile care se execută efectiv.

4️⃣ Valoarea de întoarcere

Rezultatul trimis înapoi. Opțional — poate lipsi (void).

▶ Primul tău apel de funcție: dublu(5), pas cu pas

▸ programul principal — main()

▸ funcția — dublu()

 
Variabile
Ecran
 
2

Două tipuri: void vs return

Procedural (void) = execută o acțiune (afișează), fără să întoarcă nimic. Operand (return) = calculează și returnează o valoare pe care o poți folosi mai departe.

▶ Funcție void: stelute(3) — acțiune, fără rezultat

▸ programul principal

▸ funcția — stelute()

 
Variabile
Ecran
 

▶ Funcție cu return: maxim(7, 3) — rezultatul se întoarce în main

▸ programul principal

▸ funcția — maxim()

 
Variabile
Ecran
 
Cod mort: orice instrucțiune scrisă după return nu se execută niciodată. Când void? Când vrei să afișezi / desenezi / modifici. Când return? Când ai nevoie de rezultat: rez = calcul(n), if (estePrim(n)).
3

Parametri formali vs efectivi

Formali = numele din definiția funcției. Efectivi = valorile trimise la apel. La apel, efectivii se copiază în formali, în ordinea pozițiilor.

▶ cmmdc(12, 8) — Euclid devine funcție reutilizabilă

▸ programul principal

▸ funcția — cmmdc()

 
Variabile
Ecran
 
Observă la primul pas al apelului: 12 (efectiv) se copiază în a (formal), 8 în b — strict după poziție. Numele din main (n1, n2) și numele din funcție (a, b) pot fi complet diferite: funcția lucrează pe propriile ei copii.
4

Transmiterea: prin valoare vs prin referință

Același apel dubleaza(n) — două efecte total diferite. Privește memoria în paralel.

Prin VALOARE — copie

1void dubleaza(int x) {
2 x = x * 2; // modifică COPIA
3}
4int n = 5;
5dubleaza(n);
6cout << n; // tot 5!
main: n
5
funcție: x

🐍 Python — la fel, tot pe copie:

1def dubleaza(x):
2 x = x * 2 # modifică copia locală
3n = 5
4dubleaza(n)
5print(n) # tot 5!

Prin REFERINȚĂ (&) — original

1void dubleaza(int &x) {
2 x = x * 2; // modifică ORIGINALUL
3}
4int n = 5;
5dubleaza(n);
6cout << n; // 10! MODIFICAT
main: n
5
funcție: x ≡ n
5

🐍 Python — NU are & pentru numere; primești prin return:

1def dubleaza(x):
2 return x * 2
3n = 5
4n = dubleaza(n) # n primește 10
5print(n) # 10! „modificat"
Apasă „Pas" și compară cele două lumi la fiecare moment.

Exemplul clasic — swap (interschimbarea)

1void interschimba(int &a, int &b) {
2 int aux = a;
3 a = b;
4 b = aux;
5}
6int x = 3, y = 7;
7interschimba(x, y);
8cout << x << " " << y; // 7 3
1# Python — nu ai nevoie de funcție:
2x, y = 3, 7
3x, y = y, x # swap direct!
4 
5# dacă totuși vrei funcție:
6def swap(a, b):
7 return b, a
8x, y = swap(x, y)
Python n-are referințe la scalari: int și float sunt imutabile — funcția primește mereu o copie. Dar listele sunt mutabile: def f(lst): lst[0] = 99 modifică originalul! Fără &, fără avertisment — ține minte diferența.
5

Variabile locale vs globale (scope)

Locală = trăiește doar cât rulează funcția. Globală = vizibilă peste tot. Cine „vede" ce?

⚙ C++

1int x = 10; // GLOBALĂ
2void schimba() {
3 int x = 99; // LOCALĂ!
4 cout << x; // 99
5}
6schimba();
7cout << x; // tot 10!

🐍 Python — aceeași regulă:

1x = 10 # GLOBALĂ
2def schimba():
3 x = 99 # LOCALĂ — altă variabilă!
4 print(x) # 99
5schimba()
6print(x) # tot 10!
7# global x ar modifica-o — de evitat!
🌍 ZONA GLOBALĂ
x = 10
📦 ZONA LOCALĂ — schimba()
x = 99

↑ ascunde x-ul global cât timp funcția rulează

Alege o perspectivă — vezi ce variabile sunt vizibile din fiecare zonă.
Regula de aur: folosește cât mai puține variabile globale. Trimite datele prin parametri și primește-le prin return — programele devin ușor de testat și fără efecte-surpriză.
6

Exerciții rezolvate — patru șabloane de aur

Modele pe care le vei rescrie de zeci de ori. Observă: fiecare problemă = o funcție cu treabă clară.

1 · return — este prim?

1bool estePrim(int n) {
2 if (n < 2) return false;
3 for (int d = 2; d*d <= n; d++)
4 if (n % d == 0) return false;
5 return true;
6}

🐍 Python

1def este_prim(n):
2 if n < 2: return False
3 d = 2
4 while d * d <= n:
5 if n % d == 0: return False
6 d += 1
7 return True

return în mijlocul buclei = ieșire imediată. Apel: if (estePrim(n)) …

2 · void — triunghi de stele

1void triunghi(int n) {
2 for (int i = 1; i <= n; i++) {
3 for (int j = 1; j <= i; j++)
4 cout << "* ";
5 cout << endl;
6 }
7}

🐍 Python

1def triunghi(n):
2 for i in range(1, n + 1):
3 print("* " * i)

Funcție „void" în Python = funcție fără return (returnează None).

3 · return — suma cifrelor

1int sumaCifre(int n) {
2 int s = 0;
3 while (n) { s += n % 10; n /= 10; }
4 return s;
5}

🐍 Python

1def suma_cifre(n):
2 s = 0
3 while n > 0:
4 s += n % 10
5 n //= 10
6 return s

n e transmis prin VALOARE → funcția „consumă" copia, originalul rămâne intact.

4 · referință — ordonare 3 valori

1void ordonare(int &a, int &b, int &c) {
2 if (a > b) swap(a, b);
3 if (a > c) swap(a, c);
4 if (b > c) swap(b, c);
5}

🐍 Python — fără &: returnezi valorile ordonate

1def ordonare(a, b, c):
2 return sorted([a, b, c])
3 
4a, b, c = ordonare(a, b, c)

& obligatoriu în C++ — altfel ordonează copiile și main nu vede nimic!

7

Test interactiv — subprograme

10 întrebări, exact conceptele de mai sus. Țintește 10/10.

8

Fișa de sinteză

Programarea modulară pe scurt.

Subprogram = instrucțiuni cu nume: antet + parametri + corp + valoare de întoarcere.
void = acțiune fără rezultat; return = rezultat folosibil în expresii. După return: cod mort.
Formali (din definiție) vs efectivi (de la apel) — corespondență strict pe poziții.
Prin valoare = copie, originalul intact; prin referință (&) = modifici originalul (swap!).
Python: scalarii sunt imutabili (mereu copie), listele sunt mutabile (se modifică originalul).
Locală trăiește cât funcția; globală peste tot — dar minimizeaz-o: parametri + return.
Proiectare modulară: sparge problema în funcții mici, fiecare cu o singură treabă clară.
La BAC (subiectul III): ți se cere exact asta — un subprogram cu antet impus. Exersează antetele!
Exersează pe pbinfo.ro — scrie fiecare soluție ca funcție separată:
#1360 · ușoară

Suma Gauss

Calculați suma 1+2+...+n printr-o funcție separată.

Rezolvă pe pbinfo.ro →
#49 · ușoară

Factorial

n! = 1·2·...·n — exemplul clasic de subprogram.

Rezolvă pe pbinfo.ro →
#332 · ușoară

Expresie2

S = 1·2 + 2·3 + ... + n·(n+1), printr-o funcție.

Rezolvă pe pbinfo.ro →
#4523 · ușoară

AfisFactoriale

Afișați 1!, 2!, …, n! — apelează funcția de mai multe ori.

Rezolvă pe pbinfo.ro →
← anteriorModul 04 · Vectori — bază urmează →Modul 05b · Funcții C++ & biblioteci