Sunteți pe pagina 1din 24

SUBPROGRAME (FUNCȚII)

Aspecte teoretice funcții


Una dintre regulile limbajului C/C++ este următoarea:Orice identificator, pentru a putea fi
folosit, trebuie să fie mai întâi declarat. Această regulă este valabilă și pentru funcții, astfel
că identifică următoarele noțiuni, aparent asemănătoare.
 definirea unei funcții înseamnă scrierea ei în întregime; este alcătuită din antetul
funcției și din corpul funcției;
 declararea unei funcții înseamnă să-i anunțăm existența;
Declararea funcției se face într-o instrucțiune declarativă și se mai numește și prototip al
funcției. Declararea funcției poate fi înlocuită de definirea ei.
Subprogramele reprezintă funcții definite de către utilizator. Ele sunt identificate prin
nume și pot fi apelate în interoriul unui program.
Un subprogram (o funcție) se definește în forma următoare:
tip_returnat nume_subprogram(lista_parametri_formali) // antetul programului
{
//instrucțiunea sau instrucțiunile care formează corpul subprogramului
}
tip_returnat = tipul rezultatului calculat și returnat de către subprogram
nume_subprogram = numele subprogramului și cu el va fi apelat
lista_parametrii formali = formată din una sau mai multe declarații de parametrii formali,
separate prin virgulă (câteodată această listă poate lipsi)
Subprogramele se scriu înainte de funcția “int main()”.
Să considerăm următorul exemplu, fără însemnătate practică:
#include <iostream>
using namespace std;
void exemplu()
{
cout << "Functii";
}

int main(){
exemplu();
return 0;
}
Programul este sintactic corect. Partea:
void exemplu(){
cout << "Functii";
}
reprezintă definirea exemplu F(), dar tot aici are loc și declararea. Dacă schimbăm ordinea
funcțiilor exemplu() și main() obținem:
#include <iostream>
using namespace std;

int main(){
exemplu();
return 0;
}
void exemplu(){
cout << "Functii";
}
De data aceasta programul nu mai este corect și la compilare obținem eroare.
Constatăm că identificatorul exemplu nu este declarat. El poate fi declarat precizând
prototipul funcției înaintea funcției main() (practic, înainte de a o apela), ca mai jos:
#include <iostream>
using namespace std;
void exemplu();

int main(){
exemplu();
return 0;
}
void exemplu(){
cout << "Functii";
}
Observăm că prototipul (declararea) este o instrucțiune C++ obișnuită, care se termină cu ;!!
În C++ variabile pot fi: locale, globale și dinamice.
Variabile locale
Variabilele locale se declară într-un anumit bloc al programului, în corpul unei funcții. Fie
programul de mai jos:
#include <iostream>
using namespace std;

void F(){
int n;
n = 10;
cout << n << endl;
}

int main(){
int a = 20;
F();
cout << a << endl;
return 0;
}
Variabilele n și a declarate în programul de mai sus sunt locale. Variabila n poate fi utilizată
numai în funcție F(), iar variabila a numai în funcția main(). Mai mult, cele două variabile ar
fi putut avea același nume și nu ar fi fost nicio confuzie.
Variabilele locale respectă următoarele reguli:
 li se alocă memorie în zona de stivă
 sunt vizibile numai în blocul în care au fost declarate
 durata de viață a lor este execuția instrucțiunilor din blocul în care au fost declarate
 sunt inițializate cu valori aleatorii. Mai precis, standardul C++ nu garantează
inițializarea lor cu o anumită valoare.
Observație: Parametrii formali ai unei funcții respectă proprietățile unei variabile locale. Nu
vom putea declara în blocul funcției variabile cu același nume ca al parametrilor formali.
Variabile globale
Variabilele globale se declară în afara oricărei funcții. La declarare, ele sunt inițializate cu 0.
#include <iostream>
using namespace std;
int n;
void F(){
cout << n << endl;
n = 1;
}
int m;

int main(){
cout << n << " " << m << endl;
n = 2; m = 3;
F();
cout << n << " " << m << endl;
return 0;
}
În programul de mai sus variabilele n și m sunt globale. Variabila n poate fi utilizată atât în
funcția main() cât și in F(), iar variabila m numai în main().
Variabilele globale respectă următoarele reguli:
 li se alocă memorie în zona de date
 sunt vizibile în toate funcțiile care urmează în codul sursă declarării lor
 durata de viață a lor este execuția întregului program
 sunt inițializate cu valoarea 0.
Observație: Într-un program putem avea și variabile globale și variabile locale, ba chiar
variabile globale și locale cu același nume.
Observație: Dacă într-un program avem variabile cu același nume, dar cu domenii de
vizibilitate diferite, are prioritate variabila cu domeniul de vizibilitate cel mai mic. În
particular, dacă ave o variabilă globală și una locală cu același nume are prioritate variabila
locală.
Observație: Dacă declarăm o variabilă în expresia de inițializare a unei instrucțiuni for, ea va
fi vizibilă numai în expresiile de control ale instrucțiunii for și în blocul subordonat acesteia.
De exemplu:
for(int i =1 ; i <= 10 ; i ++)
cout << i << " " ;
Să ne amintim că parametri din antetul unei funcții se numesc parametri formali, iar cei din
apelul funcției se numesc parametri efectivi.
Corespondența dintre parametri formali și cei efectivi
Fie următorul program, în care funcția cmmdc returnează cel mai mare divizor comun al
parametrilor:
#include <iostream>
using namespace std;

int cmmdc(int a , int b){


while(a != b)
{
if(a>b)
a=a-b;
else b=b-a;
}
return a;
}

int main(){
int x = 12, y = 18;
cout << cmmdc(x , y) << endl; // 6
return 0;
}
Să observăm că între parametri formali și cei actuali trebuie să existe o anumită
corespondență, astfel:
1. numărul parametrilor formali și cel al parametrilor actuali trebuie să fie același ;
2. tipul parametrilor formali trebuie să fie același cu cel al parametrilor actuali, sau să se
poată face o conversie implicită:
o cmmdc(x , y) – parametri actuali sunt variabile de tip int
3. numele parametrilor formali nu trebuie să fie același cu numele parametrilor actuali
corespunzători;
Parametrii formali ai unei funcții se comportă la fel ca niște variabile locale:
 li se alocă memorie pe stivă, ca variabilelor locale.
 devin variabile locale pentru funcție, iar numele acestor variabile este identic cu
numele parametrilor din antetul funcției
 la revenirea din apelul funcției, conținutul parametrilor, la fel ca al variabilelor locale,
se pierde

Mecanismele de transmitere a parametrilor în C++


Există două modalități de transmitere a parametrilor:
 transmiterea prin valoare
 transmiterea prin referință
Transmiterea prin valoare
În cazul transmiterii parametrilor prin valoare, parametrii formali ai unei funcții sunt copii ale
valorilor parametrilor actuali. Acest lucru înseamnă că:
 parametri actuali pot fi expresii ale căror valori corespund ca tip cu parametri formali
(sau pot fi convertite implicit la tipul parametrilor formali).
 pe stivă se memorează valoare expresiei (sau variabilei) date ca parametru actual.
 la ieșirea din apelul funcției modificările realizate în funcție asupra parametrilor
formali nu au efect asupra parametrilor actuali. Parametrii actuali sunt nemodificați!
 acesta este modul implicit de transmitere a parametrilor.
Exemplu:
#include <iostream>
using namespace std;

int cmmdc(int a , int b){


cout << "La inceputul functiei cmmdc, a = " << a << " si b = " << b << endl;
while(b != 0)
{
int r = a % b;
a = b;
b = r;
}
cout << "La finalul functiei cmmdc, a = " << a << " si b = " << b << endl;
return a;
}

int main(){
int x = 24, y = 18;
cout << cmmdc(x , y) << endl;
cout << "După apelul functiei cmmdc, x = " << x << " si y = " << y << endl;
return 0;
}
Constatăm că deși în funcția cmmdc parametrii formali a și b se modifică, în main(), după
apelul funcției cmmdc(), parametrii actuali x și y au valorile anterioare.
Transmiterea prin referință
Este mecanismul specific C++ prin care putem modifica într-o funcție variabile din afara
funcției. În cazul transmiterii parametrilor prin referință, parametrii formali ai unei funcții
sunt referințe ale parametrilor actuali. Acest lucru înseamnă că:
 parametri actuali pot fi doar variabile, sau expresii ale căror rezultate sunt similare
variabilelor: elemente de tablou, câmp al unei structuri, pointer dereferențiat, etc.
 pe stivă se memorează adresa variabilei date ca parametru actual.
 toate modificările realizate în apelul funcției asupra parametrilor formali se fac de fapt
asupra parametrilor actuali. Parametrii actuali sunt modificați la ieșirea din apel!
 pentru a preciza că un parametru este transmis prin referință va fi precedat de
caracterul & în antetul funcției.
Exemplu:
#include <iostream>
using namespace std;

void dublare(int & n)


{
n = 2 * n;
}

int main(){
int x = 24;
cout << "x = " << x << endl;
dublare(x);
cout << "x = " << x << endl;
return 0;
}
Constatăm că, la ieșirea din apel, valoarea variabilei x este modificată. Mai mult, un apel de
forma dublare(10); reprezintă o eroare de sintaxă, deoarece parametrul actual trebuie să fie
variabilă.

Transmiterea ca parametri a tablourilor


Tablourile au un comportament special în ceea ce privește transferul parametrilor. Mai precis:
Tablourile se transmit prin valoare, dar orice modificare a valorilor elementelor tabloului dat
ca parametru formal va afecta elementul corespunzător al tabloului dat ca parametru actual.
Exemplu:
#include <iostream>
using namespace std;

void dublare(int & x)


{
x = 2 * x;
}

void transf(int n, int x[])


{
for(int i = 0 ; i < n ; i ++)
dublare(x[i]);
}

void afisare(int n, int x[])


{
for(int i = 0 ; i < n ; i ++)
cout << x[i] << " ";
cout << endl;
}

int main(){
int n = 5, v[5];
for(int i = 0 ; i < n ; i ++)
v[i] = i;
afisare(n , v); // tabloul memorează {0, 1, 2, 3, 4}
transf(n, v);
afisare(n , v); // tabloul memorează {0, 2, 4, 6, 8}
return 0;
}
Analizând programul anterior, constatăm că:
 am transmis prin referință funcției dublare() un element al tabloului.
 funcția transf() are doi parametri transmiși prin valoare (inclusiv tabloul).
 la ieșirea din apelul funcției transf() elementele tabloului sunt modificate, deși tabloul
a fost transmis prin valoare.
Pentru a preciza că un parametru formal este tablou unidimensional avem următoarele
posibilități (luăm ca exemplu funcția afișare de mai sus):
void afisare(int n, int x[]); // nu se precizează dimensiunea reală a tabloului
void afisare(int n, int x[10]); // se precizează dimensiunea reală a tabloului
void afisare(int n, int *x); // parametrul este un pointer la tipul elementelor tabloului
Toate variantele de mai sus sunt echivalente.
Pentru un tablou multidimensional, regula este că prima dimensiune a parametrului nu trebuie
să fie în concordanță cu cea a parametrului actual. Toate celelalte dimensiuni ale parametrului
formal trebuie să fie identice cu dimensiunile corespunzătoare ale parametrului actual. De
exemplu, pentru o matrice următoarele secvențe sunt corecte:
void F(int n, int m, int A[][25]); //prototipul funcției
...
int n , m , A[25][25]; //declarații de variabile
F(n,m,A); //apelul funcției
sau
void F(int n, int m, int A[25][25]); //prototipul funcției
...
int n , m , A[25][25]; //declarații de variabile
F(n,m,A); //apelul funcției
Următoare secvență este însă greșită, deoarece a doua dimensiune a parametrului actual
(numărul de coloane) nu corespunde cu cea a parametrului formal:
void F(int n, int m, int A[][25]); //prototipul funcției
...
int n , m , A[20][20]; //declarații de variabile
F(n,m,A); //apelul funcției
Parametri de intrare, de ieșire și de intrare/ieșire
Așa cum am văzut deja, parametri sunt folosiți pentru a transfera date între subprograme.
Astfel prin intermediul parametrilor o funcție poate să primească date pe care să le prelucreze
sau poate să întoarcă rezultate în funcția care a făcut apelul.
Din acest punct de vedere, parametrii unei funcții pot fi:
 parametri de intrare – prin intermediul lor funcția primește date pe care să le
prelucreze. De obicei sunt parametri transmiși prin referință. Valoarea cu care intră în
funcție este importantă, valoarea pe care o au la finalul apelului nu este importantă.
 parametri de ieșire – prin intermediul lor funcția întoarce în programul apelant
rezultate. De obicei sunt parametri transmiși prin referință, cu excepția tablourilor.
Valoare pe care o au la intrarea în funcție nu este importantă; este importantă însă
valoarea pe care o au la finalul apelului, deoarece reprezintă probabil rezultatul.
 parametri de intrare-ieșire – prin intermediul lor funcția primește date de intrare, le
prelucrează și tot prin intermediul lor întoarce în programul apelant rezultatul. De
obicei sunt parametri transmiși prin referință, cu excepția tablourilor. Pentru acești
parametri este importantă atât valoarea cu care intră în apel, cât și valoarea de la
ieșirea din apel.
Pentru exemplificare să vedem câteva variante pentru o funcție care determină suma cifrelor
unui număr natural, precum și modul de apelare:
Parametri de intrare – funcția are un singur parametru, de intrare, transmis prin valoare, prin
care primește un număr pentru care determină suma cifrelor. Rezultatul va fi returnat de către
funcție, iar apelul se va face într-o expresie.
int suma(int n)
{
int s = 0;
while(n)
{s = s + n % 10; n /= 10;}
return r;
}
int main(){
int n;
cin >> n;
cout << suma(n);
return 0;
}
Parametri de ieșire – funcția are doi parametri:
 un parametru de intrare, transmis prin valoare, prin care primește un număr pentru care
determină suma cifrelor
 un parametru de ieșire, transmis prin referință, prin care întoarce rezultatul
Funcția se apelează într-o instrucțiune de sine stătătoare.
void suma(int n, int & s)
{
s = 0;
while(n)
{s = s + n % 10; n /= 10;}
}
int main(){
int n,s;
cin >> n;
suma(n, s);
cout << s;
return 0;
}
Parametri de intrare ieșire – funcția are un singur parametru, transmis prin referință, prin
care primește un număr natural. Funcția determină suma acestuia și îl întoarce prin
intermediul aceluiași parametru. Funcția se apelează într-o instrucțiune de sine stătătoare.
void suma(int & n)
{
int s = 0;
while(n)
{s = s + n % 10; n /= 10;}
n = r;
}
int main(){
int n;
cin >> n;
suma(n);
cout << n;
return 0;
}
Considerăm problema: Se dau două numere naturale n și m. Să se determine produsul
dintre suma cifrelor lui  n și suma cifrelor lui  m.
Programul următor rezolvă problema de mai sus.
#include <iostream>
using namespace std;

int suma(int n)
{
int s = 0;
while(n)
{s = s + n % 10; n /= 10;}
return s;
}

int main(){
int n , m;
cin >> n >> m;
cout << suma(n) * suma(m);
return 0;
}
Funcția care calculează suma cifrelor unui număr este int suma(int n).
 funcția are un antet: int suma(int n), din care deducem că:
o funcția se numește suma;
o funcția are un parametru, n, de tip int. Parametrul este important, deoarece prin
el se precizează care este numărul pentru care se determină suma cifrelor. Vom
vedea mai târziu că o funcție poate avea mai mulți parametri. Parametrii care
apar în antetul funcției se numesc parametri formali;
o parametrii unei funcții se mai numesc și argumente;
o funcția are un anumit tip, aici int, care precizează care este tipul rezultatului;
 funcția are un bloc de instrucțiuni, corpul funcției, delimitat de acolade {}, care
precizează operațiile prin care se obține rezultatul. Mai mult:
o corpul funcției are propriile variabile (aici s). Aceste variabile se
numesc variabile locale;
o în corpul funcției, parametrul se comportă ca o variabilă locală. NU putem
avea o variabilă locală cu același identificator ca parametrul;
o în corpul funcției nu se cunosc valorile parametrilor formali. Funcția trebuie să
determine rezultatul corect indiferent de valoarea lor;
o rezultatul determinat în cadrul funcției este întors în programul apelant prin
instrucțiunea return. Rezultatul este calculat în mod obișnuit în variabila s.
Prin instrucțiunea return s;, valoarea curentă a variabilei s este returnată în
programul apelant;
 în funcția main găsim apelul funcției suma:
o apelul funcției se face într-o expresie: cout << suma(n) + suma(m);. Pentru
operația de adunare, operanzii vor fi rezultatele apelurilor celor două funcții;
o parametrii n, respectiv m, întâlniți în apel, se numesc parametri
efectivi sau parametri actuali. Valorile parametrilor
actuali sunt cunoscute;
Considerăm problema: Se citește un tablou cu elemente numere întregi. Să se ordoneze
crescător elementele tabloului și apoi să se afișeze.
O rezolvare C/C++ care folosește funcții este următoarea:
#include <iostream>
using namespace std;

void citire(int & n, int x[])


{
cin >> n;
for(int i = 0 ; i < n ; ++ i)
cin >> x[i];
}

void sortare(int n, int x[])


{
bool sortat = false;
while(! sortat)
{
sortat = true;
for(int i = 0 ; i < n - 1 ; i++)
if(x[i] > x[i+1])
{
int aux = x[i];
x[i] = x[i+1];
x[i+1] = aux;
sortat = false;
}
}
}

void afisare(int n, int x[])


{
for(int i = 0 ; i < n ; ++ i)
cout << x[i] << " ";
}
int main(){
int k, v[1005];
citire(k , v);
sortare(k , v);
afisare(k , v);
return 0;
}
Față de cele de mai sus, putem observa următoarele:
 funcțiile citire, sortare și afisare nu returnează valori și au un tip al rezultatului
special, void. Tipul void este un tip de date care nu conține valori și poate fi folosit
tocmai în asemenea situații. Am putea spune că sunt de tip procedură;
 apelul acestor funcții se face în instrucțiuni de sine stătătoare;
 funcțiile au câte doi parametri, numărul de elemente ale tabloului și tabloul propriu
zis. Pentru parametrul formal de tip tablou nu trebuie să fie precizată dimensiunea
declarată a tabloului;
 numele parametrilor actuali nu trebuie să fie aceiași cu cei ai parametrilor formali.
Trebuie însă să corespundă numărul lor, tipul lor și ordinea;
 parametrul actual de tip tablou nu conține []:
o dacă am fi avut apelul citire(k , v[]); am fi obținut o eroare de sintaxă,
sintagma v[] neavând înțeles;
o dacă am fi avut apelul citire(k , v[k]); am fi obținut de asemenea eroare de
sintaxă, v[k] fiind elementul de indice k din tabloul v, deci o variabilă de
tip int, nu tablou;
 observați prezența caracterului & înaintea parametrului formal n din antetul
funcției citire. Acesta transformă parametrul formal într-un alias al parametrului
actual, iar modificările făcute asupra parametrului formal n au loc de fapt asupra
parametrului actual k din main;
Exemple de funcții elementare care returnează valori și întorc valorile prin parametrii
Funcție care calculează suma cifrelor unui număr
int suma(int n) void suma(int n, int &s)
{ {
int s=0,u; int u;
while(n!=0) s=0;
{ while(n!=0)
u=n%10; {
s=s+u; u=n%10;
n=n/10; s=s+u;
} n=n/10;
return s; }
} }
Funcție care calculează oglinditul unui număr
int oglindit(int n) void oglindit(int n, int &og)
{ {
int u,og; int u;
og=0; og=0;
while(n!=0) while(n!=0)
{ {
u=n%10; u=n%10;
og=og*10+u; og=og*10+u;
n=n/10; n=n/10;
} }
return og; }
}
Funcție care calculează prima cifră a unui număr
int prima(int n) void prima(int n, int &p)
{ {
while(n>9) while(n>9)
{ {
n=n/10; n=n/10;
} }
return n; p=n;
} }
Funcție care verifică dacă un număr este prim
int prim(int n) void prim(int n,int &ok)
{ int ok=1; { int ok=1;
for(int d=2;d*d<=n;d++) for(int d=2;d*d<=n;d++)
if(n%d==0) ok=0; if(n%d==0) ok=0;
return ok;} }
Funcție care calculează suma divizorilor unui număr
int suma_div(int n) void suma_div(int n, int &s)
{ int s=0; { int s=0;
for(int d=1;d<=n;d++) for(int d=1;d<=n;d++)
if(n%d==0) s=s+d; if(n%d==0) s=s+d;
return s;} }
Funcție care calculează numărul divizorilor unui număr
int nr_div(int n) void nr_div(int n, int &k)
{ int k=0; { int k=0;
for(int d=1;d<=n;d++) for(int d=1;d<=n;d++)
if(n%d==0) k=k+1; if(n%d==0) k=k+1;
return k;} }
Funcție care calculează cmmdc dintre două numere
int cmmdc(int a,int b) void cmmdc(int a,int b, int &d)
{ while(a!=b) {int d;
if(a>b) a=a-b; while(a!=b)
else b=b-a; if(a>b) a=a-b;
return a;} else b=b-a;
d=a;}

Probleme rezolvate care folosesc funcții elementare


1.Enunț.
Se citește de la tastatură un număr natural n. Să se afișeze în ordine crescătoare primele n
numere prime despărțite prin spațiu.
Date de intrare
n=6
Se va afișa
2 3 5 7 11 13
Rezolvare

#include <iostream>
using namespace std;
int prim(int n)
{ int ok=1;
for(int d=2;d*d<=n;d++)
if(n%d==0) ok=0;
return ok;}
int main()
{ int n,x,k;
cin>>n;
k=0;x=2;
while(k<n)
{
if(prim(x)==1) {cout<<x<<" ";k=k+1;}
x=x+1;
}
return 0;
}

2.Enunț.
Se citește de la tastatură un număr natural n. Să se afișeze în ordine crescătoare primele n
numere palindroame nenule despărțite prin spațiu.
Date de intrare
n=11
Se va afișa
1 2 3 4 5 6 7 8 9 11 22
Rezolvare

#include <iostream>
using namespace std;
void oglindit(int n, int &og)
{
int u;
og=0;
while(n!=0)
{
u=n%10;
og=og*10+u;
n=n/10;
}
}
int main()
{ int n,x,k,og;
cin>>n;
k=0;x=1;
while(k<n)
{
oglindit(x,og);
if(x==og) {cout<<x<<" ";k=k+1;}
x=x+1;
}
return 0;
}

3.Enunț.
Se citește de la tastatură un număr natural n și n valori naturale. Să se calculeze cmmdc al
tuturor celor n numere citite.
Date de intrare
n=5 și numerele 10, 15, 25, 100, 1000
Se va afișa
5
Rezolvare

#include <iostream>
using namespace std;
int cmmdc(int a,int b)
{ while(a!=b)
if(a>b) a=a-b;
else b=b-a;
return a;}

int main()
{ int n,x,d,i,a,b;
cin>>n>>a>>b;
d=cmmdc(a,b);
for(i=3;i<=n;i++)
{ cin>>x;
d=cmmdc(d,x);
}
cout<<d;
return 0;
}

4.Enunț
Să se afișeze toate numerele naturale de 3 cifre cu proprietatea ca sunt prime și oglinditul lor
este de asemenea prim. Afișarea se va face cu un spațiu între numere.
Rezolvare

#include <iostream>
using namespace std;
int oglindit(int n)
{
int u,og;
og=0;
while(n!=0)
{
u=n%10;
og=og*10+u;
n=n/10;
}
return og;
}
int prim(int n)
{ int ok=1;
for(int d=2;d*d<=n;d++)
if(n%d==0) ok=0;
return ok;}
int main()
{ int n,x;
for(n=100;n<=999;n++)
{ x=oglindit(n);
if(prim(n)==1 && prim(x)==1) cout<<n<<" ";
}
return 0;
}

5.Enunț
Se citesc 2 numere naturale a și b, a<b. Să se afișeze numărul din intervalul închis [a,b] care
are cel mai mulți divizori. Dacă mai multe numere au număr maxim de divizori, se va afișa
cel mai mic.
Date de intrare
a=10, b=20
Se va afișa
12
Rezolvare

#include <iostream>
using namespace std;
int nr_div(int n)
{ int k=0;
for(int d=1;d<=n;d++)
if(n%d==0) k=k+1;
return k;}
int main()
{ int a,b,n,k,mx=0,nr;
cin>>a>>b;
for(n=a;n<=b;n++)
{ k=nr_div(n);
if(k>mx)
{
mx=k;
nr=n;
}
}
cout<<nr;
return 0;
}

Aplicații cu funcții propuse pentru examenul de bacalaureat


1.
Subprogramul putere are trei parametri:
 n, prin care primește un număr natural din intervalul [1,109];
 d și p, prin care furnizează divizorul prim, d, care apare la cea mai mare putere, p, în
descompunerea în factori primi a lui n; dacă există mai mulți astfel de divizori se afișează
cel mai mare dintre ei.
Scrieți definiția completă a subprogramului.
Exemplu: dacă n=10780, atunci, în urma apelului,

2.
Două numere distincte a și b sunt numite d-fii ai unui număr natural n dacă a∙b=n.
Subprogramul fii are un singur parametru, n, prin care primește un număr natural (n
[1,109]). Subprogramul afișează pe ecran toate perechile distincte de numere naturale cu
proprietatea că sunt d-fii ai lui n. Fiecare pereche este afișată încadrată între paranteze
rotunde, numerele din pereche fiind afișate în ordine strict descrescătoare, separate printr-un
spațiu. Scrieți definiția completă a subprogramului.
Exemplu: dacă n=12 se afișează pe ecran, nu neapărat în această ordine, (12 1)(6 2)(4 3)
iar dacă n=16 se afișează pe ecran (16 1)(8 2)

3.
Subprogramul factori are doi parametri, n şi m, prin care primește câte un număr natural din
intervalul [1,109]. Subprogramul returnează numărul valorilor prime care se regăsesc atât în
descompunerea în factori primi a lui n, cât și în descompunerea în factori primi a lui m.
Scrieți definiția completă a subprogramului.
Exemplu: dacă n=750 şi m=490, atunci subprogramul returnează 2

4.
Două numere a și b sunt numite generatoare ale unui număr natural n dacă a∙b+[a/b]=n,
unde s-a notat cu [c] partea întreagă a numărului real c.
Subprogramul generatoare are un singur parametru, n, prin care primește un număr natural
(n [2,109]). Subprogramul afișează pe ecran toate perechile distincte de numere naturale cu
proprietatea că sunt generatoare ale lui n și că primul număr din pereche este par. Numerele
din fiecare pereche sunt separate prin simbolul minus (-), iar perechile sunt separate prin câte
un spațiu. Dacă nu există astfel de perechi, se afișează pe ecran mesajul nu exista. Scrieți
definiția completă a subprogramului.
Exemplu: dacă n=2020 se afișează pe ecran
2-1010 4-505 10-202 20-101 96-21 200-10 606-3 808-2 1010-1

5.
Un număr este scris în baza de numerație b (b≤10) dacă cifrele sale aparțin intervalului [0,b-
1].
Subprogramul baza are un singur parametru, n, prin care primește un număr natural (n
[0,109]). Subprogramul returnează cea mai mică bază din intervalul [2,10] căreia i-ar putea
corespunde scrierea lui n. Scrieți definiția completă a subprogramului.

Exemplu: dacă n=50731, subprogramul returnează numărul 8.

6.
Subprogramul prodprim are doi parametri:
• n, prin care primește un număr natural
• p, prin care furnizează produsul divizorilor primi ai lui n.
Scrieți definiția completă a subprogramului.
Exemplu: dacă n=2000, în urma apelului p=10, deoarece

7.
Subprogramul putere are doi parametri, n și p, prin care primește câte un număr natural (n
[2,109], p [0,109]). Subprogramul returnează puterea la care apare numărul p în
descompunerea în factori primi a lui n, dacă p este număr prim, sau valoarea -1 în caz contrar.
Scrieți definiția completă a subprogramului.
Exemplu: dacă n=80 și p=2, subprogramul returnează numărul 4 (80=24*5).

8.
Subprogramul suma are un singur parametru, n, prin care primește un număr natural
Subprogramul returnează suma divizorilor primi ai lui n. Scrieți definiția
completă a subprogramului.

Exemplu: pentru n=12 subprogramul returnează 5 (divizorii primi ai lui 12 sunt 2 și 3).

9.
1. Subprogramul suma are doi parametri:
• n, prin care primește un număr natural din intervalul [0,109];
• s, prin care furnizează suma cifrelor impare distincte din scrierea acestuia.
Scrieți definiția completă a subprogramului.
Exemplu: dacă n=4713835, după apel s=16 (16=7+1+3+5), iar dacă n=48, după apel s=0.
10.
____________________________________________________
Subprogramul produs are doi parametri:

• n, prin care primește un număr natural (nє [0,109]);


• p, prin care furnizează produsul cifrelor pare distincte din scrierea acestuia, sau -1 dacă nu
există astfel de cifre.
Scrieți definiția completă a subprogramului.
Exemplu: dacă n=1622325, după apel p=12 (12=6∙2), iar dacă n=122325, după apel p=2.

11.

Subprogramul patrate are doi parametri, x și y, prin care primește câte un număr natural
(1≤x≤y≤109). Subprogramul afişează pe ecran o expresie aritmetică reprezentând suma
numerelor din intervalul [x,y] care au proprietatea că sunt pătrate perfecte, urmate de valoarea
acestei sume. Termenii sumei sunt într-o ordine oarecare și sunt separați prin câte un simbol
plus (+), iar valoarea sumei este precedată de simbolul egal (=), ca în exemplu. Dacă nu există
niciun astfel de termen, se afișează pe ecran mesajul nu exista.
Scrieți definiția completă a subprogramului.
Exemplu: dacă x=10 și y=50 se poate afișa pe ecran 16+25+36+49=126

12.
Subprogramul pDoi are un singur parametru, n, prin care primește un număr natural (n
[1,109]). Subprogramul returnează cea mai mare valoare din intervalul [1,n], cu proprietatea
că este o putere a lui 2.
Scrieți definiția completă a subprogramului.
Exemplu: dacă n=20, subprogramul returnează 16.

13.
Subprogramul putere are trei parametri:
• n, prin care primește un număr natural din intervalul [2,109];
• d și p, prin care furnizează divizorul prim, d, care apare la cea mai mică putere, p, în
descompunerea în factori primi a lui n; dacă există mai mulți astfel de divizori se afișează cel
mai mic dintre ei.
Scrieți definiția completă a subprogramului.

Exemplu:
dacă n=10780, atunci, în urma apelului, d=5 şi p=1 .

14.

Două numere a și b (a<b) sunt numite divizori pereche ai unui număr natural n dacă a∙b=n.
Subprogramul perechi are un singur parametru, n, prin care primește un număr natural (n
[2,109]). Subprogramul afișează pe ecran toate perechile distincte de numere naturale cu
paritate diferită cu proprietatea că sunt divizori pereche ai lui n. Fiecare pereche este afișată
încadrată între paranteze drepte, numerele din pereche fiind afișate în ordine strict crescătoare,
separate printr-un spațiu, iar dacă nu există astfel de perechi, se afișează pe ecran mesajul nu
exista. Scrieți definiția completă a subprogramului.

Exemplu: dacă n=12 se afișează pe ecran, nu neapărat în această ordine, [1 12][3 4]


iar dacă n=9 se afișează pe ecran nu exista

15.
Subprogramul divPrimMax are doi parametri:
• n, prin care primește un număr natural (n [2,109]);
• p, prin care furnizează cel mai mare divizor prim al lui n.
Scrieți definiția completă a subprogramului.

Exemplu: dacă n=2000, în urma apelului p=5, deoarece 2000=24 * 53.

Rezolvări aplicații cu funcții propuse pentru examenul de bacalaureat


1.

void putere(int n, int &d, int &p)


{
int pu,f=2,mx=0,m=n,k=0;
while(m>1)
{
pu=0;
while(m%f==0)
{
m/=f;
pu++;
}
if(pu>mx)
mx=pu;
f++;
}
f=2;
while(n>1)
{
pu=0;
while(n%f==0)
{
n/=f;
pu++;
}
if(pu==mx)
d=f;
f++;
}
p=mx;
}

2.__________________________________________________

void fii(int n)
{
int i;
for(i=1;i*i<n;i++)
if(n%i==0) cout<<"("<<n/i<<" "<<i<<")"<<" ";
}

3.

int factori(int n, int m)


{
int pu,f=2,k=0;
while(m>1)
{
pu=0;
while(m%f==0)
{
m/=f;
pu++;
}
if(pu!=0 && n%f==0)
k++;
f++;
}
return k;
}

4.

void generatoare(int n)
{ int a,b,k;k=0;
for(a=1;a<=n;a++)
for(b=1;b<=n;b++)
if(a%2==0 && a*b+a/b==n)
{
k++;cout<<a<<"-"<<b<<" ";
}
if(k==0) cout<<"nu exista";
}

5.

int baza(int n)
{ int mx,u;
mx=0;
while(n!=0)
{
u=n%10;
if(u>mx) mx=u;
n=n/10;
}
return mx+1;
}

6.

void prodprim(int n, int &p)


{ int f,k;
p=1;f=2;
while(n!=1)
{
k=0;
while(n%f==0)
{
k++;
n=n/f;
}
if(k>0) p=p*f;
f++;
}
}

int putere(int n, int p)


{ int f,k,nr;
nr=-1;
f=2;
while(n!=1)
{
k=0;
while(n%f==0)
{
k++;
n=n/f;
}
if(f==p)
if(k>0) nr=k;
f++;
}
return nr;
}

8.

int suma(int n)
{ int f,s,k;
f=2;s=0;
while(n!=1)
{
k=0;
while(n%f==0)
{
k++;
n=n/f;
}
if(k>0) s=s+f;
f++;
}
return s;
}

9.

void suma(int n, int &s)


{
int frecventa[10];
for(int i=0; i<=9; i++)
frecventa[i]=0;
s=0;
while(n!=0)
{
if(n%2==1)
frecventa[n%10]++;
n=n/10;
}

for(int i=1;i<=9; i=i+2)


if(frecventa[i]>0) s=s+i;
}

10 .

void produs(int n,int &p)


{ int c,k,m,u;
p=1;
for(c=0;c<=9;c=c+2)
{m=n;k=0;
while(m!=0)
{
u=m%10;
if(u==c) k++;
m=m/10;
}
if(k>0) p=p*c;}
if(p==1) p=-1;
}

11.

#include <iostream>
#include <cmath>
using namespace std;
void patrate(int x,int y)
{
int s=0,i,v[1000],n;
n=0;
for(i=x;i<=y;i++)
if(sqrt(i)==int(sqrt(i)))
{
n++;v[n]=i;
s=s+i;
}
if(n==0) cout<<"nu exista";
else
{ for(i=1;i<n;i++)
cout<<v[i]<<"+";
cout<<v[n];
cout<<"="<<s;}
}

12.

int pDoi(int n)
{
int p=1;
while(p<=n) p=p*2;
return p/2;
}

13.

void putere(int n, int &d, int &p)


{
int pu,f=2,mn=100000000,k=0;

while(n>1)
{
pu=0;
while(n%f==0)
{
n/=f;
pu++;
}
if(pu!=0)
if(pu<mn)
{
d=f;
mn=pu;
}
f++;
}
p=mn;
}

14.

void perechi(int n)
{
int i,k;
k=0;
for(i=1;i*i<=n;i++)
if(n%i==0)
if(i%2!=(n/i)%2)
{
k++;
cout<<"["<<i<<" "<<n/i<<"]"<<" ";
}
if(k==0) cout<<"nu exista";
}

15.

void putere(int n, int &p)


{
int pu,f=2;
while(n>1)
{
pu=0;
while(n%f==0)
{
n/=f;
pu++;
}
if(pu>0)
p=f;
f++;
}
}

S-ar putea să vă placă și