Sunteți pe pagina 1din 10

PREZENTARE TEORETICA

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
}
Tip_returnat Reprezint tipul rezultatului calculat i returnat de funcie i poate
fi: int, char, char*, long, float, void, etc.

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.

Lista_parametrilor_formali Reprezint o list de declaraii de variabile separate prin virgul.


Aceast list poate s fie i vid.

Instruciune Este o instruciune vid, simpl sau 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);


unde:
parametru efectiv = parametru actual = parametru real = parametru de apel
lista parametrilor efectivi = poate fi vid, poate fi o expresie sau mai multe desprite prin
virgul

Efectul instructiunii de apel este:

crearea tabelei de parametrii actuali;


crearea variabilelor locale functiei;
executarea corpului de instructiuni al functiei;
desfintarea tabelei de parametrii si a variabilelor locale;
revenirea la instruciunea urmatoare din program

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 Exemplul 3.2


1. include <iostream> #include <iostream>
using namespace std;
using namespace std; void f1 (int k)
void f1 () {
{ for (int i=1; i<=k ; i++)
cout << "abc"; cout << "abc"<< " ";
} }
int main () int main ()
{ {
f1(); f1(5);
} }
Se va afisa:abc Se va afia:abc abc abc abc abc
Funcia nu returneaz o Funcia nu returneaz o valoareFuncia are un parametru
valoareFuncia nu are formal de tip intApelul funciei este o instruciune de apel
parametriApelul funciei este o simpl i se face cu ajutorul unui parametru actual care este
instruciune de apel simpl de acelai tip cu tipul parametrului formal corespunztor

Exemplul 3.3 Exemplul 3.4


1. include <iostream>
#include <iostream>
#include <math.h>
# include <math.h>
using namespace std;
using namespace std;
int prim (int x)
int prim (int x)
{
{
int nr_div=0;
for (int i=2; i<=sqrt(x); i++)
for (int i=2; i<=sqrt(x); i++)
if (x%i==0)
if (x%i==0)
return 0;
nr_div++;
return 1;
if (nr_div==0)
}
return 1;
int main ()
else
{
return 0;
int N;
}
cout << "N="; cin >> N;
int main ()
if (prim(N))
{
cout << "PRIM";
int N;
else
cout << "N="; cin >> N;
cout << "NU E PRIM";
if (prim(N))
}
cout << "PRIM";
else
cout << "NU E PRIM";
}
Funcia returneaz o valoare de tip n cazul n care se ntlnete un divizor a lui x se
int Funcia are un parametru formal de execut instruciunea return 0. Astfel apelul funciei se
tip int Rezultatul funciei este este ncheie.
utilizat n cadrul unei expresii. 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).
OBS: n cazul n care tipul returnat de funcie lipsete din definiia funciei, acesta este
implicit
int i nu void.
Exemplul 3.5 Exemplul 3.6 Exemplul 3.7

#include <iostream> #include <iostream> #include <iostream>


using namespace std; using namespace std; using namespace std;
p( ) p( ) void p( )
{ { {
cout << " abcd"; return 25; cout << "void";
} } }
int main () int main () int main ()
{ { {
cout << p(); cout << p( ); cout << p();
} } }

Compilatorul genereaz Compilatorul genereaz Compilatorul genereaz eroare deoarece o


eroare deoarece lipseste eroare deoarece lipseste functie cu tipul returnatvoidnu se poate
tipul returnat de functie tipul returnat de functie apela in cadrul unei functii, in cazul de
fata cout

#include <iostream> #include <iostream>


using namespace std; using namespace std;
int p( ) void p( )
{ {
return 25; cout << "abcd";
} }
int main () int main ()
{ {
cout << p( ); p();
} }

Se afieaz 25 Se afieaz abcd

4. Prototipul unei funcii


Pentru a apela o funcie, aceasta trebuie initial 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 acesta este urmat de ;.
Exemplul 4.1.
# include <iostream> PROTOTIPUL FUNIEI
using namespace std;
APELUL FUNCIEI
int max (int, int);
DEFINIIA FUNCIEI
int main () antetul funciei
{
cout << max(10, 20); corpul functiei
}

int max (int a, int b)


{
if (a>b)
return a;
else
return b;
}

5. Variabile locale i variabile globale


5.1 . Funcia main
n C++ funcia main determin prima instruciune pe care o va executa programul. Aceasta 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 si n cadrul
celorlalte funcii. Aceste variabile se numesc locale i sunt accesibile doar in funcia in care au
fost declarate.
In cadrul unei funcii se pot apela i alte funcii, cu conditia ca acestea sa fi fost definite naintea
eventualului apel sau este prezent un prototip de funcie naintea funciei apelate
5.3. Variabile globale
Variabilele globale
sunt declarate n afara oricrei funcii i sunt vizibile (pot fi utilizate) n tot programul (n
programul principal i n subprograme) din momentul declarrii lor.

Exemplul 5.1 Exemplul 5.2 Exemplul 5.3


1. include <iostream> 1. include <iostream> 1. include <iostream>

using namespace std; using namespace std; using namespace std;


int N; int N; int N;
void f1() void f1() void f1(int p)
{ { {
int x=5; int x=5; int x=p;
N=10; cout << endl << x; cout << x;
cout << endl<<N; P=2; }
cout << endl << x; } int main ()
} int P=9; {
int main () int main () f1(77);
{ {f1(); }
N=4; cout << x;
cout << N; P=7;
f1(); }
}
N este variabil global si Compilatorul genereaz eroare Se afieaz 77
poate fi accesat n cadrul deoarece
oricrei funcii. N este variabil global.
Poate fi accesat n cadrul
x este variabil local, funcia main ncearc s acceseze oricrei funcii.
vizibil doar n cadrul variabila locala x care este vizibil x este variabil local.
funciei f1() doar n funcia f1(). Poate fi accesat doar n
variabila P este accesat n f1() cadrul funciei f1()
Se va afia: nainte de a fi declarat. p este parametru formal.
4 Poate fi accesat doar n
10 f1().
5
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
1. include <iostream> Variabila N este definit att ca variabil global ct i ca variabil local
n f1().
using namespace std; Se va afisa: 2 10
int N=10; Funcia f1() acioneaz asupra variabilei locale N.
void f1() Funcia main() acioneaz supra variabilei globale N.
{
int N=2;
cout << N<<" ";
}
int main ()
{
f1();
cout << N;
}

ntrebare. Cum gestioneaz compilatorul cele dou variabile omonime ?


Rspuns:
Variabilelor globale li se rezerv spaiu de memorie 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
locale sunt vizibile doar n interiorul subprogramului n care au fost declarate.

6. Parametrii formali i parametrii actuali


Parametrii formali apar n antetul subprogramului i sunt utilizai de subprogram pentru
descrierea abstract a unui proces de calcul .
Parametrii 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:

Apel prin valoare


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)
Parametrii transmisi prin valoare se pot modifica in corpul functiei dar dupa
terminarea apelului functiei au aceasi valoare pe care au avut-o inainte de apel.
Se utilizeaz atunci cnd dorim ca subprogramul s lucreze cu acea valoare, dar s nu
poat modifica parametrul efectiv corespunztor din blocul apelator.

Se pot transmite prin valoare:


a)Valorile reinute de variabile. n acest caz parametrii efectivi trebuie s fie numele
variabilelor.

Exemplu:
#include<iostream.h>
void test(int n)
{
n++;
cout<<n<<endl; tiprete n=8
}
void main()
{
int n=7;
test(n);
cout<<n<<endl; tiprete n=7
}
Parametrul n este transmis prin valoare. n funcia main() acest parametru este iniializat
cu valoarea 7. Cnd apelm funcia test(), se rezerv spaiu pe stiv, spaiu care are
numele parametrului formal (n acest caz, tot n) i care este iniializat cu valoarea
memorat de variabila n a programului principal. Altfel spus, pe stiv se copie valoarea
parametrului efectiv de apel. n funcie, variabila n (care este local acestei funcii) este
incrementat i devine 8, valoare care va fi tiprit. La ieirea din funcie, variabila n din
stiv se pierde, adic nu mai are spaiu alocat, prin urmare valoarea 8 este pierdut. n
main() se tiprete valoarea variabilei n (local acesteia) care are valoarea 7.
Se observ c, n momentul apelului funciei test(), pe stiv sunt alocate dou variabile
cu acelai nume n. Prima variabil este variabila local funciei main() care se salveaz
pe stiv n momentul apelului pentru a putea reface contextul funciei main() dup
ncheierea apelului. A doua variabil este parametrul formal tip valoare n, vizibil numai
n funcia test() i iniializat n momentul apelului cu valoarea 7. Indiferent ce valori
primete acest n n corpul funciei test(), dup ncheierea execuiei acestei funcii,
spaiul su este de alocat din stiv, adic variabila respectiv este distrus. Din acest
motiv, dup execuia funciei test(), coninutul stivei este cel din dreapta. Se reface
contextul din care s-a lansat apelul funciei test(), adic se recupereaz din stiv
valoarea variabilei locale n=7 i adresa de revenire, adic adresa instruciunii cout.
b) Expresii. n acest caz, parametrii efectivi sunt expresii, care pot conine i funcii i
care mai nti se evalueaz. Exemplu:
#include<iostream.h>
#include<math.h>
void test(int n)
{
cout<<n<<endl;
}
void main()
{
test(5); se va tipri 5
test(7+(int)sqrt(45)); se va tipri 13
}
n funcie se creeaz o variabil numit n, reinut pe stiv, care la primul apel va primi
valoarea 5 i la al doilea apel valoarea 13.
La ieirea din funcie coninutul acestei variabile se pierde.
Transmiterea parametrilor prin valoare se utilizeaz cnd nu dorim ca subprogramul
apelat s poat modifica parametrii efectivi de apel. Acesta este modul implicit de
transmitere a parametrilor n limbajul C. Dac nu ar exista dect transmiterea prin
valoare, ar fi imposibil s modificm valoarea anumitor valori care sunt declarate n
blocul apelator.

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.
Parametrii transmisi prin referinta se folosesc pentru transmiterea de rezultate in
afara functiei. Ei se pot modifica in corpul functiei dar dupa terminarea apelului functiei
au valoarea pe care au primit-o in timpul apelului functiei.
n C++, implicit, apelul se face prin valoare. Pentru a specifica un apel prin referin, n
lista parametrilor formali, numele parametrului formal va trebui precedat de simbolul &

#include <iostream> #include <iostream> #include <iostream>


using namespace std; using namespace std; using namespace std;
int a,b; int a,b; int a,b;
void afis(int a, int b) void afis(int &a, int &b) void afis(int &m, int n)
{ { {
a=a+1; a=a+1; m=m+1;
b=b+4; b=b+4; n=n+4;
cout<<a<<" "<<b<<endl; cout<<a<<" "<<b<<endl; cout<<m<<" "<<n<<endl;
} } }

int main() int main() int main()


{ { {
a=1; a=1; a=1;
b=2; b=2; b=2;
afis(a,b); afis(a,b); cout <<a<<" " <<b<< endl;
cout <<a<<" " <<b<< endl; cout <<a<<" " <<b<< endl; afis(a,b);
} } cout <<a<<" " <<b;
}

Se va afisa: Se va afisa: Se va afisa:


2 6 (rezultatul apelului 2 6 (rezultatul apelului 1 2 (rezultatul inaintea apelului functiei
functiei afis) functiei afis) afis)
1 2 (rezultatul de dupa 2 6 (rezultatul de dupa 2 6 (rezultatul apelului functiei afis)
apelul functiei afis) apelul functiei afis) 2 2 (rezultatul de dupa apelul functiei
afis: variabila a isi pastreaza
valoarea dupa apel fiind parametru
transmis prin referinta pe cand
variabila b revine la valoarea pe care o
avea inainte de apel fiind
parametru transmis prin valoare)

Exemplul 7.1
1. include <iostream> APEL PRIN VALOARE

using namespace std; APEL PRIN REFERIN


void schimba_valoare (int x, int y)
{ Se va afia:
int z=x;
x = y; M=1 N=5
y = z;
} M=5 N=1
void schimba_referinta (int &a, int &b)
{
int aux=a;
a=b;
b=aux;
}
int 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;
}

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