Sunteți pe pagina 1din 9

SUBPROGRAME C++

1. Introducere
Subprogramele sunt pri ale unui program, identificabile prin nume, care se pot activa la
cerere prin intermediul acestor nume.
Prezena subprogramelor implic funcionarea n strns legtur a dou noiuni: definiia unui
subprogram i apelul unui subprogram.
Definiia unui subprogram reprezint de fapt descrierea unui proces de calcul cu ajutorul
variabilelor virtuale (parametri formali) iar apelul unui subprogram nu este altceva dect execuia
procesului de calcul pentru cazuri concrete (cu ajutorul parametrilor reali, (efectivi, actuali) ).

2. Structura unui subprogram C++


Un subprogram (funcie) are o definiie i attea apeluri cte sunt necesare.

Definiia unei funcii are forma general:


tip_returnat nume_funcie (lista parametrilor formali)
{
instruciune; // corpul funciei
}
Reprezint tipul rezultatului calculat i returnat de funcie i poate fi:
int, char, char*, long, float, void, etc.
Tip_returnat

n cazul n care tipul rezultatului este diferit de void, corpul funciei


trebuie s conin cel puin o instruciune return. nstruciunea return
va specifica valoarea calculat i returnat de funcie care trebuie s fie
de acelai tip ca i tip_returnat.

Nume_funcie

Reprezint numele dat funciei de ctre cel ce o definete, pentru a o


putea apela.
Reprezint o list de declaraii de variabile separate prin virgul.

Lista_parametrilor_formali

Instruciune

Aceast list poate s fie i vid.


Este o instruciune vid sau o instruciune simpl sau o instruciune
compus.

3. Apelul unei funcii . Revenirea dintr-o funcie


3.1 Apelul unei funcii care nu returneaz o valoare are forma general:

nume_funcie (lista parametrilor efectivi);

parametru efectiv = parametru actual = parametru real = parametru de apel


lista parametrilor efectivi = fie vid, fie o expresie sau mai multe desprite prin virgul
O funcie care returneaz o valoare poate fi apelat fie printr-o instruciune de apel simpl
(cazul funciilor care nu returneaz valori) i n plus poate fi apelat ca operand al unei expresii. n
cazul n care funcia se apelaz print-o instruciune de apel simpl, rezultatul funciei se pierde. Cnd
funcia se apeleaz ca operand, valoarea returnat va fi utilizat n expresie.
La apelul unei funcii, valorile parametrilor efectivi se atribuie parametrilor formali
corespunztori. n cazul n care unul din tipul unui paramatru efectiv difer de tipul parametrului
formal corespunztor, parametrul efectiv va fi convertit spre parametru formal (dac este posibil, altfel
compilatorul genereaz eroare).
n momentul n care se ntlnete un apel de funcie, controlul execuiei programul este
transferat primei instruciuni din funcie, urmnd a se executa secvenial instruciunile funciei.
Revenirea dintr-o funcie se face n unul din urmtoarele cazuri:
- dup execuia ultimei instruciuni din corpul funciei
- la ntlnirea unei instruciuni return
Instruciunea return are formatele:
- return ;
- return expresie ;
Exemplul 3.1
# include <iostream.h>

Exemplul 3.2
# include <iostream.h>

void f1 ()
{
cout << "abc";
}

void f1 (int k)
{
for (int i=1; i<=k ; i++)
cout << "abc"<< " ";
}
void main ()
{
clrscr();
f1(3);
}
Se va afia:
abc abc abc

void main ()
{
clrscr();
f1();
}
Se va afisa:
Abc
Funcia nu returneaz o valoare
Funcia nu are parametri
Apelul funciei este o
instruciune de apel simpl

Funcia nu returneaz o valoare


Funcia are un parametru formal de
tip int
Apelul funciei este o
instruciune de apel sinpl i se
face cu ajutorul unui parametru
actual care este de acelai tip cu
tipul parametrului formal
corespunztor

Exemplul 3.3
# include <iostream.h>
# include <math.h>

Exemplul 3.4
# include <iostream.h>
# include <math.h>

int prim (int x)


{
int nr_div=0;
for (int i=2; i<=sqrt(x); i++)
if (x%i==0)
nr_div++;
if (nr_div==0)
return 1;
else
return 0;
}

int prim (int x)


{
for (int i=2; i<=sqrt(x); i++)
if (x%i==0)
return 0;
return(1);
}
void main ()
{
int N;
cout << "N="; cin >> N;

void main ()
{
int N;
cout << "N="; cin >> N;

if (prim(N))
cout << "PRIM";
else
cout << "NU E PRIM";

if (prim(N))
cout << "PRIM";
else
cout << "NU E PRIM";

}
Funcia returneaz o valoare de
tip int
Funcia are un parametru de tip
int
Rezultatul funciei este este
utilizat n cadrul unei expresii.

n cazul n care se ntlnete un


divizor a lui x se execut
instruciunea return 0. Astfel
apelul funciei se ncheie. Dac x
este numr prim, instruciunea
return 0 nu se execut niciodat i
n acest caz, dup terminarea
execuiei instruciunii for, se
execut instruciunea return 1 (care
determin ncheierea execuiei
funciei).

n cazul n care tipul returnat de funcie lipsete din definiia funciei, acesta este implicit int i
nu void.
Exemplul 3.5
P( )
{
cout << " un int";
}
void main ()
{
clrscr();
cout << p();
}
Compilatorul genereaz
WARNING
Se va afia un numr
ntreg

Exemplul 3.6
p( )
{
return 25;
}
void main ()
{
clrscr();
cout << p();
}
Se afieaz 25

Exemplul 3.7
void p( )
{
cout << "void";
}
void main ()
{
clrscr();
cout << p();
}
Compilatorul
genereaz eroare

4. Prototipul unei funcii


Pentru a apela o funcie, aceasta trebui mai nti definit. Astfel apelul unei funcii trebuie
precedat de definiia funciei respective.
O a doua posibilitate de apelare a funciei const n scrierea prototipului funciei nainte ca acesta
s fie apelat.
Prototipul funciei conine informaii asemntoare cu cele din antetul funciei. Pot lipsi numele
parametrilor formali (conteaz doar tipul i ordinea acestora), n plus acesa este urmat de ;.
Exemplul 4.1.
# include <iostream.h>
int max (int, int);
void main ()
{
cout << max(10, 20);
}
int max (int a, int b)
{
if (a>b)
return a;
else
return b;
}

PROTOTIPUL FUNIEI

APELUL FUNCIEI

DEFINIIA FUNCIEI
antetul funciei
si
- corpul functie

5. Variabile locale i variabile globale


5.1. Funcia main.
n C, numele de funie main determin prima instruciune pe care o va executa programul.
Acesta este unica diferen dintre main i celelalte funcii. Din acest motiv se poate spune c orice se
poate face n main se poate face i n celelalte funcii.

5.2.

Variabile locale

La fel cum se declar variabilele n cadrul funciei main, la fel se pot declara varibile n cadrul
celorlalte funcii. Aceste variabile se numesc locale i sunt accesibile doar de funcia care le-a declarat.
La fel n cadrul unei funcii se pot apela i alte funcii, ca i n main, dac acestea au fost definite
naintea eventualului apel sau dac este prezent un prototip de funcie naintea funciei apelante i o
definiie de funcie n cadrul programului respectiv sau n fiierele incluse n programului respectiv.

5.3.

Variabile globale

Variabilele globale sunt declarate nafara oricrei funcii i pot sunt vizibile (pot fi utilizate) n
tot programul (n programul principal i n subprograme) din momentul declarrii lor.
Exemplul 5.1
# include <iostream.h>
int N;
void f1()
{
int x=5;
N=10;
cout << endl<<N;
cout << endl << x;
}

Exemplul 5.2
# include <iostream.h>
int N;
void f1()
{
int x=5;
cout << endl << x;
P=2 //eroare
}
int P=9;
4

Exemplul 5.3
# include
<iostream.h>
int N;
void f1(int p)
{
int x=p;
cout << x;
}
void main ()

void main ()
{
N=4;
cout << N;
f1();
}

void main ()
{
f1();
cout << x;
P=7;//corect
}

{
f1(3);
}

N este variabil global. Poate


Compilatorul genereaz eroare
Se afieaz 3
fi accesat n cadrul oricrei funcii.
deoarece funcia main ncearc s
N este variabil global.
acceseze variabila x care este vizibil
x este variabil local, vizibil
Poate fi accesat n cadrul oricrei
doar n funcia f1().
doar n cadrul funciei f1()
funcii.
Compilatorul genereaz eroare
Se va afia:
x este variabil local.
deoarece P este accesat n f1()
Poate fi accesat doar n cadrul
4
nainte de a fi declarat.
funciei f1()
10
p este parametru formal.
5
Poate fi accesat doar n f1().

5.4.

Regula de omonimie

n cazul n care exist o variabil local care are acelai nume cu o variabil global, aceste
dou variabile se numesc variabile omonime.
Variabilele locale sunt prioritare (ascund) variabilele globale
omonime.
Exemplul 5.4
Int N=10;
Void f1()
{
int N=2;
cout << N;
}
void main ()
{
f1();
cout << N;
}

Variabila N este definit att ca variabil


global ct i ca variabil local n f1().
Se va afisa:
2 10
Funcia f1() acioneaz asupra variabilei
locale N.
Funcia main() acioneaz supra variabilei
globale N.

ntrebare. Cum gestioneaz compilatorul cele dou variabile omonime ?


Rspuns:
Variabilelor globale li se rezerv spaiu de memorare la nceputul execuiei programului, ntr-o
zon de memorie numit zon de date. Acest spaiu va fi ocupat pn la ncheierea execuiei
programului.
Variabilelor locale li se rezerv spaiu ntr-o zon special de memorie numit stiva. La ncheierea
execuiei subprogramului, coninutul stivei este eliberat. Din acest motiv, variabilele globale sun vizibile doar n
interiorul subprogramului n care au fost declarate.

6. Parametri formali i parametri actuali


Parametri formali apar n antetul subprogramului i sunt utilizai de subprogram pentru
descrierea abstract a unui proces de calcul .
Parametri actuali apar n instruciunea de apelare a uni subprogram i sunt folosii la execuia
unui proces de calcul pentru valori concrete.
Parametrii formali nu sunt variabile. O variabil este caracterizat de nume, tip, i adres.
Legarea unui parametru formal la o adres se realizeaz n timpul execuiei instruciunii de apelare a
subprogramului.

7. Apel prin valoare i apel prin referin


Exist dou tipuri de apel al subprogramelor:
A. Apel prin valoare
B. Apel prin referin
7.1. Apel prin valoare se transmite o copie a parametrului actual.
Valorile transmise la apelul unui subprogram sunt memorate n stiv. Datorit faptului c, dup
terminarea execuiei unui subprogram, stiva este eliberat, n cazul apelului prin valoare parametrul
actual nu se modific (se opereaz asupra unei copii a parametrului efectiv)
7.2. Apel prin referin - se transmite adresa parametrului actual.
n cazul apelului prin referin, subprogramul, cunoscnd adresa parametrului actual,
acioneaz direct asupra locaiei de memorie indicat de aceasta, modificnd valoarea parametrului
actual.
n C, implicit apelul este prin valoare. Pentru a specifica un apel prin referin, n lista
parametrilor formali, numele parametrului formal va trebui precedat de cuvntul simbolul &.
Exemplul 7.1
void schimba_valoare (int x, int y)
{
int
z=x;
x = y;
y = z;
}
void schimba_referinta (int &a, int &b)
{
int aux=a;
a=b;
b=aux;
}
void main ()
{
int M=1, N=5;
schimba_valoare(M,N);
cout << "M="<<M<< "
" << "N="<<N<<endl;
schimba_referinta(M,N);
cout << "M="<<M<< "
" << "N="<<N<<endl;
}

APEL PRIN VALOARE

APEL PRIN REFERIN

Se va afia:
M=1 N=5
M=5

N=1

8. Transmiterea tablourilor unei funcii


n C numele unui tablou reprezint adresa primului element din tablou, celelalte elemente fiind memorate
la adresele urmtoare de memorie. Din acest motiv, n cazul transmiterii unui tablou unei funcii se transmite de
fapt o adres, realizndu-se un apel numit pointer care determin modificarea parametrului actual.
Exemplul 8.1
# include <iostream.h>
void Genereaza (int A[100], int &x)
{
cout << "Nr. de elemente=";
cin >> x;
for (int i=0; i<x; i++)
A[i]=random (20);
}
void main ()
{
int T[100], N;
Genereaza (T, N);
for (int i=0; i<N; i++)
cout << T[i]<< " ";
}

Funcia modific parametrul


actual T prin intermediul
parametrului formal A deoarece
se relizeaz apelul prin
pointer.
Funcia modific valoarea
parametrului actual N prin
intermediul parametrului x
deoarece se realizeaz apelul
prin referin.

Datorit faptului c funcia folosete doar adresa primului element pentru a accesa celelalte elemente ale
vectorului, n cadrul prototipului sau antetului funciei este suficient dac se specific faptul c parametrul este
un vector, nefiind necesar precizarea numrului de elemente ale vectorului.
Exemplul 8.2.
# include <iostream.h>
void Genereaza (int A[], int &x)
{
cout << "Nr. de elemente=";
cin >> x;
for (int i=0; i<x; i++)
A[I]=random (20);
}

Funcia modific parametrul


actual T prin intermediul
parametrului formal A deoarece
se relizeaz apelul prin
pointer.

void main ()
{
int T[100], N;
Genereaza (T, N);
For (int i=0; i<N; i++)
Cout << T[i]<< " ";
}

Funcia modific valoarea


parametrului actual N prin
intermediul parametrului x
deoarece se realizeaz apelul
prin referin.

O matrice este gestionat n memoria intern ca o succesiune de elemente. Liniile sunt memorate
succesiv. Astfel pentru a reine o matrice este suficient dac se cunosc: adresa de nceput a primului element din
matrice i lungimea unei linii (adic numrul de coloane). Astfel la transmiterea unei matrice ntr-o funcie este
suficient dac se precizeaz numele matrice respective (adresa de primului element) i dimensiunea unei linii
(numrul de coloane).
Exemplul 8.3.
void Genereaza (int A[][10], int &x, int &y)
{
cout << "Nr. de linii: ";
cin >> x;
cout << "Nr. de coloane: ";
cin >> y;
for (int i=0; i<x; i++)
for (int j=0; j<y; j++)
A[i][j]=random (20);
}
void Afiseaza (int A[][10], int x, int y)
{
for (int i=0; i<x; i++)
{
for (int j=0; j<y; j++)
{
cout.width(5);
cout << A[i][j];
}
cout<<endl;
}
}
void main ()
{
int T[10][10], N, M;
Genereaza (T, N, M);
Afiseaza (T, N, M);
}

9. TRANSMITEREA IRURILOR DE CARACTERE UNEI FUNCII


Datorit faptului c pentru a memora un ir de caractere compilatorul pstreaz doar adresa de nceput a
irului de caractere iar restul caracterelor sunt memorate folosind octeii urmtori pn la ntlnirea unui \0, n
cazul unui parametru de tip ir de caractere, funcia primete adresa de nceput a irului, modificnd astfel
parametrul actual.
Exemplul 9.1.
void modifica (char * p)
{
p[2]='x';
}
void afiseaza (char * p)
{
cout << endl << p;
}
void main ()
{
char s[20]="abcd";
modifica(s);
afiseaza(s);
}

10. TRANSMITEREA STRUCTURILOR UNEI FUNCII


Exemplul 10.1.
struct persoana
{
char nume[20];
int varsta;
};
void Citeste (persoana &x)
{
cout << "Numele:";
gets(x.nume);
cout << "Varsta:";
cin >>x.varsta;
}

Modificarea membrilor structurii necesita apelul


prin referin

Pentru a afia o structur este suficient apelul


prin valoare

void Afiseaza (persoana x)


{
cout << "NUMELE: " << x.nume;
cout << endl;
cout << "VARSTA: " << x.varsta;
}
void main ()
{
clrscr();
persoana P;
Citeste (P);
Afiseaza(P);
}

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