dubleaza1(x)a e o copie, iar la final dispareDoar pentru matematică-informatică. Ce e un subprogram, cum îl apelezi, diferența dintre transferul prin valoare și prin referință și variabilele locale. Cu itemi oficiali în care rezultatul depinde de un singur &.

ții minte doar fișa asta și ești acoperit
Doar MI: la științele naturii, III.1 se scrie în pseudocod, fără subprogram.
Antet: tip nume(parametri). int f(int n) returnează; void f(int n) nu.
Prin valoare: int x. Subprogramul lucrează pe o copie, apelul nu vede schimbarea.
Prin referință: int &x. E aceeași variabilă. Așa furnizezi un rezultat printr-un parametru.
Truc: & = aceeași cutie.
Antetul costă: 2 p dacă rezultatul se returnează, 3 p dacă se furnizează prin parametru.
Variabile locale: declară tot în subprogram. La barem, 1 p merge cu corectitudinea globală.
Culorile din lecție:termencifră, datăidee-cheie
int x și int &x.Ai nevoie de suma cifrelor în trei locuri din program. În loc să scrii bucla de trei ori, îi dai un nume și o folosești oriunde.
int suma(int n)
{ int s=0;
while(n!=0)
{ s=s+n%10;
n=n/10;
}
return s;
}
int main()
{ int a=2027;
cout<<suma(a)<<" "<<a;
return 0;
}
Programul afișează 11 2027. Deși subprogramul îl aduce pe n la 0, a rămâne neschimbat.
Termen oficialÎn exemplu
int suma(int n)n, din anteta, din apelsreturn s;suma(a)| Termen oficial | În exemplu |
|---|---|
| antet | int suma(int n) |
| parametru formal | n, din antet |
| parametru efectiv | a, din apel |
| variabilă locală | s |
| rezultat | return s; |
| apel | suma(a) |
Subprogramul se scrie înaintea locului în care e apelat. Programa spune „proceduri și funcții”: în C/C++ procedura e o funcție void.
int f(int n)function f(n:integer):integer;void p(int n)procedure p(n:integer);int &xvar x:integerreturn s;f:=s;| C/C++ | Pascal | |
|---|---|---|
| Cu rezultat | int f(int n) | function f(n:integer):integer; |
| Fără rezultat | void p(int n) | procedure p(n:integer); |
| Prin referință | int &x | var x:integer |
| Returnare | return s; | f:=s; |
Ce rămâne în x după void f(int a) { a=a+1; } și x=3; f(x);?
Ce rămâne în x după void f(int &a) { a=a+1; } și x=3; f(x);?
Aici se decide totul.
void dubleaza1(int a)
{ a=a*2;
}
void dubleaza2(int &a)
{ a=a*2;
}
Pornind de la x=5:
dubleaza1(x)a e o copie, iar la final disparedubleaza2(x)a e chiar x, sub alt nume| Apel | x după apel | De ce |
|---|---|---|
dubleaza1(x) | 5 | a e o copie, iar la final dispare |
dubleaza2(x) | 10 | a e chiar x, sub alt nume |
Oficial, primul e transfer prin valoare, al doilea transfer prin referință.
int aint &af(x+1)f(x)| Prin valoare | Prin referință | |
|---|---|---|
| Scriere | int a | int &a |
| La apel poate fi | variabilă, constantă, expresie: f(x+1) | doar o variabilă: f(x) |
| Ce vede apelul după | valoarea veche | valoarea nouă |
| Când îl folosești | date de intrare | rezultate |
Tablourile sunt un caz aparte. La model 2026, I.2, antetul e int f(int s,int d,int v[]): tabloul se scrie fără &, dar subprogramul lucrează pe elementele originale.
&Aceste subprograme sunt recursive, adică se apelează pe ele însele; lecția de recursivitate explică mecanismul. Aici urmărește doar ce se întâmplă cu n.
void f(int &n)
{ if(n>0)
{ cout<<n;
n=n-1;
f(n);
cout<<n;
}
}
Se cere ce afișează x=3; f(x);. Toate apelurile lucrează pe aceeași variabilă.
n, care e 0 pentru toți: 0, 0, 0.Se afișează 321000 (varianta a, 4 p). Dacă antetul ar fi fost void f(int n), fiecare apel ar fi avut copia lui, iar la revenire s-ar fi afișat 0, 1, 2: adică 321012, una dintre variantele greșite.
void f(int x)
{ if(x%5!=0)
{ x=x*5/2;
f(x);
}
else x=x-1;
cout<<x;
}
Pentru f(9), parametrul e prin valoare. Atribuirile se văd doar în apelul curent.
f(55)f(22)f(9)| Apel | x la afișare | Ce se afișează, în ordine |
|---|---|---|
f(55) | 54 | primul |
f(22) | 55 | al doilea |
f(9) | 22 | al treilea |
Se afișează 545522 (varianta b, 4 p). Atenție la a doua linie: f(22) îl schimbă pe x în 55 înainte să apeleze, iar această valoare o afișează.
Model 2022, MI, I.2 are void f(int x,int y,int&z), cu r inițial 0. Doar f(18,19,r) lasă r=2 (varianta d, 4 p): parametrul z e prin referință, deci modificările ajung în r.
Subprogramul consecutiv primește n din [1,10⁴] și furnizează prin f numărul cu proprietatea (f-1)*f < n ≤ f*(f+1). Pentru n=19, f=4.
void consecutiv(int n,int &f)
{ f=1;
while(f*(f+1)<n)
f++;
}
Bucla crește f cât timp n e mai mare decât f*(f+1). Când se oprește, f*(f+1) e prima valoare care ajunge la n.
Barem (10 p)Puncte
| Barem (10 p) | Puncte |
|---|---|
| antet, câte 1 p: structură, parametru de intrare, parametru de ieșire | 3 |
| valoare determinată, câte 3 p: numere cu proprietatea cerută, cel mai mare sau cel mai mic dintre ele | 6 |
| variabile locale, corectitudine globală | 1 |
Subprogramul Plus are un singur parametru, n, din [10,10⁹). Înlocuiește fiecare secvență 25 cu 26 și furnizează rezultatul prin același parametru. Pentru n=202535250, după apel n=202635260.
void Plus(int &n)
{ int m=n,r=0,p=1,c;
while(m!=0)
{ c=m%10;
if(c==5 && m/10%10==2)
c=6;
r=c*p+r;
p=p*10;
m=m/10;
}
n=r;
}
Cifra 5 devine 6 doar dacă în stânga ei e un 2. Rezultatul se construiește cu c*p+r, deci zeroul de la final rămâne.
Barem: antet 2 p (structură, parametru de intrare-ieșire); valoare determinată 6 p, câte 1 p pentru identificarea unei cifre, perechea de cifre de pe poziții consecutive, înlocuirea sau alipirea unei cifre, secvențele înlocuite, ordinea cifrelor, secvențele păstrate, „inclusiv cifrele nule de la finalul numărului”; furnizarea rezultatului prin parametrul indicat 1 p; variabile locale și corectitudine globală 1 p.
De ce nu merge apelul f(5) dacă antetul e void f(int &a)?
int x=1;
void f()
{ int x=2;
cout<<x;
}
int main()
{ f();
cout<<x;
return 0;
}
Programul afișează 21. În f, numele x e al variabilei locale, care o acoperă pe cea globală.
| Locală | Globală | |
|---|---|---|
| Declarată | în subprogram | în afara subprogramelor |
| Vizibilă | doar în subprogram | în tot programul, de la declarare încolo |
| Valoare inițială | nedefinită, până o atribui | 0, dacă nu pui alta |
Oficial, programa cere „variabile globale și variabile locale, domeniu de vizibilitate”. În lucrările importate, niciun enunț nu întreabă direct despre asta. Totuși baremul de la III.1 are, în toate lucrările 2024–2027 importate, un punct pentru variabilele locale declarate, împreună cu corectitudinea globală. Deci la III.1 declară tot ce folosești în interiorul subprogramului.
| Unde | Ce se cere | Puncte |
|---|---|---|
| Subiectul I | subprogram dat, adesea recursiv: ce afișează, ce valoare are, ce apel e corect | 4 |
| II.2, uneori | valorile unui subprogram recursiv dat | 6 |
| III.1 | definiția completă a unui subprogram | 10 |
& lipsă la parametrul prin care se furnizează rezultatul.& în plus la parametrii de intrare: la unii itemi schimbă rezultatul, iar la III.1 nu respectă cerința.return cu valoare într-un subprogram void.Plus nu e plus. Identificatorii trebuie să respecte enunțul.cin în subprogram, când valorile vin prin parametri.