Sunteți pe pagina 1din 16

Definirea subprogramelor în C++

Cuprins

1. Definirea subprogramelor.........................................................................................................2
2. Clasificarea subprogramelor.....................................................................................................2
3. Părţile unei funcţii C/C++.........................................................................................................3
4. Transferul datelor între mediul apelant şi subprogramul apelat...........................................4
5. Transmiterea parametrilor de tip tablou unidimensional.......................................................6
6. Transmiterea parametrilor de tip tablou unidimensional.......................................................8
7. Funcţii predefinite în C/C++.....................................................................................................9
Funcţii matematice.............................................................................................................................9
Funcţii pentru numere aleatoare.......................................................................................................10
Funcţii de conversie.........................................................................................................................10
Funcţii referitoare la şiruri de caractere............................................................................................11
Funcţii referitoare la fişiere..............................................................................................................11
Alte funcţii.......................................................................................................................................11
8. Exerciţii şi probleme................................................................................................................12
9. Exemplu de test subprograme.................................................................................................14

Autor: Diana Vezentan profesor de informatică


Liceul de Informatică “Tiberiu Popoviciu“ Cluj+Napoca

1
1. Definirea subprogramelor

Ce sunt subprogramele?
 Subprogramele reprezintă părţi ale unui program ce se identifică prin nume
 Subprogramele se pot activa la cere prin intermediul acestor nume
 În limbajele C, C++ subprogramele se numesc funcţii

Când definim un subprogram?

• Dacă algoritmul cuprinde o secvenţă de operaţii ce se repetă


• Dacă problema iniţială e complexă, o împărţim în mai multe subprobleme, iar pentru rezolvarea
fiecărei subprobleme definim o funcţie
• Pentru a ascunde detaliile de implementare

Funcţii în limbajul C++

• Un program C++ este format din una sau mai multe funcţii
• Orice program C are o funcţie principală, main, de unde se lansează executarea programului
• Din funcţia main se pot apela alte funcţii care la rândul lor pot să activeze noi funcţii.
• Funcţiile fie calculează o valoare (ex: sqtr) fie execută anumite operaţii fără a returna o valoare
(ex: clrscr()).

2. Clasificarea subprogramelor
În C/C++ funcţiile pot fi de două tipuri:
• funcţii procedurale
• funcţii operanzi

Funcţii procedurale
Funcţiile procedurale sunt funcţii care pot returna zero, una sau mai multe valori prin intermediul
parametrilor.
Exemple:
a) funcţie care schimba continutul variabilelor a si b:
swap(a,b);
b) Functie care sterge ecranul
clrscr();
c) Funcţie care calculeaza suma dintre a si b in s
aduna (int a, int b, int&s);

Funcţii operanzi
Funcţiile operanzi sunt funcţii care returnează o valoare asociată numelui funcţiei
Exemple de funcţii operand predefinite în C/C++:
abs(x) – returnează modulul lui x
sqrtl(x) – returnează radicalul valorii x

Apelul unei funcţii


Apelul unei funcţii se poate face în două moduri: printr-o instrucţiune de apel sau ca operand într-o
expresie

2
1) Instrucţiunea de apel are forma:
nume(lista parametrilor efectivi);

Instrucţiunea de apel se foloseşte atunci când funcţia apelată nu returnează nici o valoare, ne
interesează doar prelucrările efectuate de funcţie
Exemplu:

void afisare(char cuv[20])


{int i;
for (i=1; i<=strlen(cuv); i++)
cout<<‘*’;
cout<<endl;
}
int main()
{char x[]=“exemplu”,a[20];
afisare(“salut”);
afisare(x);
cin>>a;
afisare(a);
return 0;
}
Observaţie: Funcţia afişare a fost apelată printr-o instrucţiune de apel.

2) Operand într-o expresie


Funcţia se apelează în cadrul expresiei astfel:
nume(lista parametrilor efectivi)

Observaţie: Când funcţia se apelează ca operand într-o expresie atunci nu se foloseşte ; după numele
funcţiei.

Exemplu:
int maxim(int a, int, b)
{
if(a>b) return a;
return b;
}
int main()
{ int x=20, y=30, z;
z = maxim(x,y);
cout<<z<<endl;
int v, w;
cin>>v>>w;
cout<<“valoarea maxima este ”<<maxim(v,w)<<endl;
}
Observaţie: Funcţia maxim a fost apelată ca operand într-o expresie.

3. Părţile unei funcţii C/C++

3
O funcţie C/C++ este formată dintr- un antet şi un corp. Forma generală a unei funcţii C/C++ este
următoarea:

tip_rezultat nume_functie ([lista parametrilor formali]) //antet


{
declaratii variabile locale //corp
instructiuni
}

Antetul unei funcţii


• Antetul cuprinde tipul valorii returnate de funcţie, numele funcţiei şi parametrii formali cuprinşi
între două paranteze rotunde:

tip_rezultat nume_functie ([lista parametrilor formali])

• Este posibil ca funcţia să nu aibă parametrii, în acest caz apar doar cele două paranteze rotunde
• Tipul returnat de funcţie poate fi orice tip cu excepţia tipului tablou
• Tipul returnat poate fi void
• Parametrii formali pot fi de tip tablou
• Valoarea returnată de funcţie se specifică prin:
return expresie;
Corpul unei funcţii
• Corpul unei funcţii C/C++ este o instrucţiune compusă cuprinsă între acolade:
• Forma generală a corpului unei funcţii este:
{…}

Exemplu:
int maxim (int a, int b, int c) //antet
{int m=a; //corp
if (b>m) m=b;
if (c>m) m=c; return m;
}

4. Transferul datelor între mediul apelant şi subprogramul apelat

Pentru comunicarea dintre subprogramul apelat şi mediul apelant se folosesc parametri. Parametri
care apar în antet se numesc parametri formali. La activarea subprogramului se stabilesc valori
concrete cu care se va executa subprogramul la acel apel. Aceşti parametri se numesc parametri
actuali.

Ce legătură trebuie să existe între parametri formali şi cei actuali?

Parametri actuali trebuie să corespundă cu parametri formali ca număr, ordine şi tip. Există două
moduri de transfer al parametrilor: prin valoare şi prin referinţă.

Transferul prin valoare


La apelarea unei funcţii, se alocă spaţiu de memorie pe stivă pentru copii ale valorile parametrilor
actuali. La încheierea execuţiei funcţiei, zona de memorie alocată pe stivă pentru apel este eliberată.

4
5
Exemplu: Ce se afişează?

void schimba(int x, int y)


{
int aux;
aux=x;
x=y;
y=aux;
cout<<“x= “<<x<<“ y= “<<y<<endl;
}

int main()
{int a=3,b=4;
schimba(a,b);
cout<<“a= “<<a<<“ b=“<<b<<endl;
}

Rezultat
x=4 y=3
a=3 b=4

Explicaţia rezultatului

• Funcţia lucrează cu copiile parametrilor, copiile au fost interschimbate, la ieşirea din funcţie zona
de memorie alocată pe stivă a fost eliberată, copiile s-au pierdut.
• Funcţia nu poate modifica valorile parametrilor actuali deoarece nu cunoaşte adresa la care sunt
memoraţi ei.

Transferul prin referinţă

Tipul referinţă

• Este o facilitate suplimentară a limbajului C++


• O variabilă referinţă conţine adresa unei alte variabile, este un alt nume asociat variabilei, un
sinonim
• Tip &var_referinta= variabila_referita;

Exemplu:

int x=10;
int &r=x;//r este o referinta pentru x;
cout<<x;
cout<<r;

Pentru o dată transmisă prin referinţă, la apelarea unei funcţii, se alocă spaţiu de memorie pe stivă
pentru adresa de memorie a parametrului actual. Subprogramul va lucra direct cu zona de memorie în
care se găseşte data. Atât modulul apelant cît şi modulul apelat lucrează asupra aceleaşi date şi orice
modificare efectuată de funcţie se va reflecta şi în modulul apelant.

6
Exemplu: Realizaţi o funcţie care interschimbă valorile parametrilor.

void schimba(int & x, int &y)


{
int aux;
aux=x;
x=y;
y=aux;
cout<<“x= “<<x<<“ y= “<<y<<endl;
}

int main()
{int a=3,b=4;
schimba(a,b);
cout<<“a= “<<a<<“ b=“<<b<<endl;
}

Rezultat
x=4 y=3
a=4 b=3

Explicaţia rezultatului

• Funcţia lucrează cu adresele parametrilor, variabilele au fost interschimbate


• Funcţia modifică valorile parametrilor actuali deoarece cunoaşte adresa la care sunt memoraţi ei,
toate prelucrările sunt făcute asupra variabilelor originale

5. Transmiterea parametrilor de tip tablou unidimensional

Parametri de tip tablou de transmit automat în C/C++ prin referinţă. Numele unui tablou este un
pointer către primul element al tabloului, de aceea un parametru formal de tip tablou unidimensional se
poate specifica prin oricare din formele:

tip *, tip [], tip[max]

Exemplul 1: parametru formal de tip vector


void afisare(int a[], int n) {….}
La apelul unei funcţii se specifică doar numele tabloului.

Exemplul 2: parametru actual de tip vector


afisare(x,n);

7
Exerciţiu: Realizaţi o funcţie care citeşte elementele unui vector, o funcţie care afişează elementele
unui vector şi apelaţi aceste funcţii pentru două tablouri.

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


{
int i;
cout<<"Dati numarul de elemente:";
cin>>n;
cout<<"dati elementele tabloului:";
for(i=1;i<=n;i++)
cin>>x[i];
}

void afisare_tablou(int x[], int n)


{
int i;
cout<<"Elementele tabloului sunt:"<<endl;
for(i=1;i<=n;i++)
cout<<x[i]<<' ';
cout<<endl;
}

int main()
{
int a[10],b[20],n,m;
citire_tablou(a,n);
citire_tablou(b,m);
afisare_tablou(a,n);
afisare_tablou(b,m);
}

Exerciţiu: Ce se afişează?

void ghici(int a[],int n)

{
int i;
for(i=1;i<n;i++)
a[i+1]=a[i];
}
int main()
{
int a[10],n;
citire_tablou(a,n);
ghici(a,n);
afisare_tablou(a,n);
}

8
Explicaţia rezultatului

Funcţia are acces la adresa tabloului, transformările se fac asupra originalului, de aceea după apel
valorile din tablou sunt modificate

6. Transmiterea parametrilor de tip tablou unidimensional

Parametri de tip tablou bidimensional se transmit automat în C/C++ prin referinţă. Pentru un
parametru formal de tip matrice avem următoarele forme:

tip a[][max] sau tip a[max1][max2]

Observaţie: Prima dimensiune a unui parametru formal de tip matrice poate lipsi

Exemplul 1: parametru formal de tip matrice


void citire_matrice(int a[][20],int &n,int &m)
{….}
Pentru un parametru actual de tip matrice se specifică doar numele matricei

Exemplul 2: parametru actual de tip matrice


citire_matrice(x,n,m);

Exerciţiu: Realizaţi o funcţie care citeşte elementele unei matrici cu n linii şi m coloane, o funcţie
care afişează elementele o matrice şi o funcţie care realizează suma a două matrici. Afişaţi suma celor
două matrici, în cazul în care această sumă se poate calcula.

#include <iostream>
using namespace std;

void citire(int a[][20],int &n,int &m)


{
int i,j;
cout<<"dati numarul de linii:";
cin>>n;
cout<<"dati numarul de coloane";
cin>>m;
cout<<"Dati elementele matricei:"<<endl;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
cin>>a[i][j];
}

void afisare(int a[][20],int n, int m)


{
int i,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
cout<<a[i][j]<< ' ';
cout<<endl;

9
}
}

void suma(int a[][20],int b[][20],int c[][20],int n,int m)


{
int i,j;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
c[i][j]=a[i][j]+b[i][j];
}

int main()
{
int a[20][20],b[20][20],c[20][20],n1,n2,m1,m2;
citire(a,n1,m1);
citire(b,n2,m2);
if(n1!=n2||m1!=m2)
cout<<"suma nu se poate efectua!";
else
{
cout<<"sumamatricilor este:"<<endl;
suma(a,b,c,n1,m1);
afisare(c,n1,m1);
}
return 0;
}

7. Funcţii predefinite în C/C++

Compilatorul C/C++ pune la dispoziţie o bibliotecă ce cuprinde sute de funcţii. În continuare am


prezentat câteva dintre aceste funcţii grupate după prelucrările pe care le efectuează.

Funcţii matematice

Funcţia Tipul Tipul Fişierul Semnificaţia rezultatului


argumentului rezultatului antet
fabs(x) Real sau întreg double math.h Valoarea absolută a lui x
abs(n) int int math.h Valoarea absolută a lui n
labs(n) long long math.h Valoarea absolută a lui n
sqrt(x) Real sau întreg double math.h Radical din x, x>=0
sin(x) Real sau întreg double math.h Sinusul valorii x exprimat în radiani
cos(x) Real sau întreg double math.h Cosinusul valorii x exprimat în radiani
tan(x) Real sau întreg double math.h Tangenta valorii x exprimată în radiani
asin(x) Real sau întreg double math.h Unghiul exprimat în radiani al cărui
sinus este x
acos(x) Real sau întreg double math.h Unghiul exprimat în radiani al cărui
cosinus este x
atan(x) Real sau întreg double math.h Unghiul exprimat în radiani a cărui
tangentă este x
log(x) Real sau întreg double math.h Logaritm natural din x, x>0

10
log10(x) Real sau întreg double math.h Logaritm în baza 10 din x, x>0
exp(x) Real sau întreg double math.h Valoarea funcţiei exponenţiale pt. x
fmod(x,y) Întreg, întreg double math.h Restul împărţirii întregi a lui x la y
pow(x,y) Real sau întreg double math.h x ridicat la puterea y (dacă x<0, y
trebuie să fie întreg)
pow10(p) int double math.h Calculează 10 la puterea p
poly(x,g,tab) x=real,g=întreg, double math.h Returnează valoarea unui polinom în
tab=tablou de punctul x; g=gradul polinomului, tab=
nr reale tabloul coeficienţilor

Funcţii pentru numere aleatoare

Funcţia Tip Tipul Fişierul Semnificaţia rezultatului


argument rez antet
randomize() void void stdlib.h Iniţializează generatorul de numere aleatoare
random(n) int int stdlib.h Un număr pseudoaleator din intervalul [0,n-1]
rand() void int stdlib.h Un număr pseudoaleator din intervalul
[0,RAND_MAX]. RAND_MAX = 32767

Funcţii de conversie

Funcţia Tipul Tipul Fişierul Semnificaţia rezultatului


arg rez antet
atof(sir_car) char* double math.h Conversia unui şir de caractere într-o valoare
double. Dacă şirul nu corespunde unei valori
double, rezultatul este 0
atoi(sir_car) char* int stdlib.h Conversia unui şir de caractere într-o valoare
întreagă. Dacă şirul nu corespunde unei valori int,
rezultatul este 0
atol(sir_car) char* long stdlib.h Conversia unui şir de caractere într-o valoare
întreagă. Dacă şirul nu corespunde unei valori
long, rezultatul este 0
ceil(x) double double math.h Cel mai mic întreg mai mare sau egal cu x
Ceil(123.45)=124, ceil(-123.45)=-123
floor(x) double double math.h Cel mai mare întreg mai mic sau egal cu x
Floor(123.54)=123, floor(-123.54)=-124
tolower(car) int int ctype.h Modifică o literă mare (A-Z) într-o literă mică (a-z)
toupper(car) int int ctype.h Modifică o literă mică (a-z) într-o literă mare (A-Z)

11
Funcţii referitoare la şiruri de caractere

Funcţia Tipul arg Tipul Fişierul Semnificaţia rezultatului


rez antet
strcmp(sir1,sir2) char*,char* int string.h Dacă sir1<sir2 => un nr negativ
Compară 2 şiruri de dacă sir1>sir2 => un nr pozitiv
caractere dacă sir1=sir2 => zero
strcpy(destinaţie,surs char*,char* char* string.h Copiază şirul sursă în şirul destinaţie
ă)
strlen(sir) char* size_t string.h Calculează lungimea unui şir
strstr(s1,s2) char*,char* char* string.h Întoarce un pointer la elementul din
s1 unde începe s2

Funcţii referitoare la fişiere


Funcţia Tipul arg Tipul Fişierul Semnificaţia rezultatului
rez antet
remove(nume_fişier) char* int stdio.h Şterge un fişier specificat prin nume
sau cale. Fişierul trebuie închis
înainte de ştergere. Dacă ştergerea s-
a efectuat atunci întoarce 0, altfel –1
rename(nume_vechi,n char*,char* int stdio.h Redenumeşte un fişier. Dacă
ume_nou) redenumirea s-a efectuat atunci
întoarce 0, altfel –1

Alte funcţii
Funcţia Tipul arg Tipul Fişierul Semnificaţia rezultatului
rez antet
delay(x) unsigned void dos.h Suspendă execuţia programului pentru x
milisecunde
exit() int void stdlib.h Termină imediat execuţia programului
indiferent de funcţia care apelează exit
gotoxy(x,y) int,int void conio.h Poziţonează cursorul în coloana x şi linia y (în
fereastra curentă în mod text). Pentru valori
invalide nu se execută nimic
getch() void int conio.h Citeşte un caracter de la tastatură fără să-l
afişeze pe ecran. Returnează valoarea
caracterului citit
getche() void int conio.h Citeşte un caracter de la tastatură şi îl afişează
pe ecran. Returnează valoarea caracterului citit
kbhit() void int conio.h Întoarce o valoare diferită de 0 dacă a fost
apăsată o tastă. Pentru a afla ce tastă a fost
apăsată se apelează getch sau getche

12
8. Exerciţii şi probleme

Scrieţi antetele şi definiţia completă pentru subprogramele următoare – selecţie de


probleme din variantele de subiecte de Bacalaureat.

1. Subprogramul divizor, cu trei parametri, prin care primeşte 3 numere naturale nenule cu cel mult 9
cifre fiecare şi returnează numărul divizorilor comuni tuturor celor 3 numere.
Exemplu: dacă numerele primite ca parametri sunt 24, 20 şi 12, subprogramul returnează valoarea 3
(divizorii comuni sunt 1, 2 şi 4).

Rezolvare:
Antet:
int divizor(int a,int b, int c)
Subprogram:
int divizor(int a, int b,int c)
{
int x=0,d,minim;
minim=a;
if(minim>b)
minim=b;
if(minim>c)
minim=c;
for(d=1;d<=minim;d++)
if(a%d==0 &&b%d==0&&c%d==0)
x++;
return x;
}
int main()
{
cout<<divizor(24,20,12);
return 0,
}

2. Subprogramul Nr are un singur parametru, k, prin intermediul căruia primeşte un număr


natural de cel puţin 3 cifre şi cel mult 9 cifre, cu toate cifrele nenule. Subprogramul furnizează tot
prin intermediul parametrului k, valoarea obţinută prin eliminarea primei şi ultimei cifre a numărului
transmis la apel.
Exemplu: dacă subprogramul primeşte prin intermediul parametrului k valoarea 12438, în urma
apelului subprogramului Nr, k va primi valoarea 243.

Rezolvare:
Antet:
void Nr(int &k)
Subprogram:

void Nr(int &k)


{ int x,e=1;
k=k/10;
x=k;
k=0;

13
while(x>9)
{
k=k+(x%10)*e;
e=e*10;
x/=10;
}
}
int main()
{
int a;

a=12348;
Nr(a);
cout<<a;
return 0;
}
3. Tabloul unidimensional V, declarat global, memorează exact 50 de numere întregi:
V1, V2,...,V50. Subprogramul Calcul primeşte prin intermediul parametrului k un număr natural
nenul (k≤50) şi furnizează prin intermediul parametrului S suma tuturor elementelor pozitive, din
tabloul V, cu indici mai mari sau egali cu k sau 0 dacă toate elementele menţionate sunt negative.

Rezolvare:
Antet:
void Calcul(int k,int &S)
Subprogram:

int V[51]={0,1,2,3,4,5};
{
int i;
S=0;
for(i=k;i<=5;i++)
if(V[i]>0)
S+=V[i];
}

int main()
{
int S;
Calcul(2,S);
cout<<S;
return 0;
}
4. Funcţia f primeşte prin intermediul parametrului n un număr natural nenul (2≤n≤200), iar prin
intermediul parametrului a un tablou unidimensional care conţine n valori întregi nenule (fiecare dintre
aceste valori întregi având cel mult patru cifre). Funcţia returnează valoarea -1 dacă numărul de valori
negative din tabloul a este strict mai mare decât numărul de valori pozitive din tablou, valoarea 0 dacă
numărul de valori negative din a este egal cu numărul de valori pozitive din tablou şi valoarea 1 dacă
numărul de valori pozitive din tabloul a este strict mai mare decât numărul de valori negative din a.

Rezolvare:
Antet:

14
int f(int n,int a[])
Subprogram:
int f(int n,int a[])
{
int i,neg=0,poz=0;
for(i=1;i<=n;i++)
if(a[i]>0)
poz++;
else
if(a[i]<0)
neg++;
if(neg>poz)
return -1;
if(neg==poz)
return 0;
return 1;
}

int main()
{
int a[20],n,i;
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
cout<<f(n,a);
return 0;
}

9. Exemplu de test subprograme


Se citeşte un vector a cu n elemente naturale. Să se scrie subprograme pentru următoarele
prelucrări:
a) Să se afişeze elementele din a care sunt numere perfecte. (Acest subprogram va
apela un alt subprogram care calculează suma divizorilor mai mici decât un număr
dat ca parametru). Un număr este perfect dacă este egal cu suma divizorilor săi mai
mici decât el.
b) Să se afişeze perechile de elemente vecine care sunt prime între ele. Se va apela un
subprogram care calculează cmmdc pentru două numere. Două numere sunt prime
între ele dacă cmmdc-ul lor este egal cu 1.
c) Să se verifice dacă tabloul este ordonat crescător/ descrescător. Afişaţi mesaje
corespunzătoare.
d) Să se genereze un nou vector b care conţine elementele din a care au număr impar
de cifre. Să se afişeze b.

Exemplu:
Pentru n=8 şi vectorul a=(10, 5, 6, 212, 8128, 5, 145, 28), se vor obţine rezultatele:
a) Numerele pătrate perfecte sunt: 6, 8128, 28
15
b) Perechile de elemente vecine prime între ele sunt: (5,6) (8128,5) (145,28)
c) Tabloul nu este ordonat
d) Vectorul b este: (5,6,212, 5,145)

Timp de lucru: 50 minute


Punctaj: oficiu 2p
a) 2p
b) 2p
c) 2p
d) 2p

16

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