TRANSFERUL PARAMETRILOR UNEI FUNCŢII
Funcţiile comunică
între ele prin argumente (parametrii).
Există următoarele
moduri de transfer (transmitere) a parametrilor către funcţiile
apelate:
q Transfer prin
valoare;
q Transfer prin
pointeri;
q Transfer prin referinţă.
TRANFERUL
PARAMETRILOR PRIN VALOARE
În exemplele
anterioare, parametrii de la funcţia apelantă la funcţia
apelată au fost transmişi prin valoare. De la programul
apelant către funcţia apelată, prin apel, se transmit valorile
partametrilor efectivi, reali. Aceste valori vor fi atribuite, la apel,
parametrilor formali. Deci procedeul de transmitere a parametrilor prin valoare
constă în încărcarea valorii
parametrilor efectivi în zona de memorie a parametrilor formali (în stivă).
La apelul unei funcţii, parametrii reali trebuie să corespundă -
ca ordine şi tip - cu cei formali.
Limbajul C
este numit limbajul apelului prin valoare, deoarece, de fiecare dată când o funcţie transmite argumente unei funcţii apelate, este
transmisă, de fapt, o copie a parametrilor efectivi. În acest mod,
dacă valoarea parametrilor formali (iniţializaţi cu valorile
parametrilor efectivi) se modifică în interiorul funcţiei apelate,
valorile parametrilor efectivi din funcţia apelantă nu vor fi
afectate.
Exemplu:
void calcule(int
x,int y)
{x=x+2;
y=y+3;
cout<<x<<”
“<<y;
}
void
main()
{int a=2,b=3;
calcule(a,b);//va afisa 4 si 6
cout<<endl<<a<<”
“<<b;// va afisa 2 3, valorile pt a si b raman neschimbate
}
TRANSFERUL
PARAMETRILOR PRIN POINTERI
În unele cazuri, parametrii
transmişi unei funcţii pot fi pointeri (variabile care conţin
adrese). În aceste cazuri, parametrii formali ai funcţiei apelate vor fi
iniţializaţi cu valorile parametrilor efectivi, deci cu valorile unor
adrese. Astfel, funcţia apelată
poate modifica conţinutul
locaţiilor spre care pointează argumentele (pointerii).
Exerciţiu: Să se
citească 2 valori întregi şi să se interschimbe cele două
valori. Se va folosi o funcţie de interschimbare.
#include <iostream.h>
void schimbă(int *x, int *y)
{int aux;
aux=*x;
*x=*
y;
*y=aux;
}
void
main()
{int a=2,b=3,*pa=&a,*pb=&b;
schimbă(&a,&b);//se poate apela si astfel: schimbă(pa,pb);
cout<<endl<<a<<”
“<<b;// va afisa 3 2, valorile pt a si b raman neschimbate
}
Dacă parametrii funcţiei
schimbă ar fi fost
transmişi prin valoare, această funcţie ar fi interschimbat
copiile parametrilor formali, iar în funcţia main modificările asupra
parametrilor transmişi nu s-ar fi păstrat.
TRANSFERUL PARAMETRILOR PRIN
REFERINŢĂ
În acest mod de transmitere
a parametrilor, unui parametru formal i se poate asocia (atribui) chiar
obiectul parametrului efectiv. Astfel, parametrul efectiv poate fi modificat
direct prin operaţiile din corpul funcţiei apelate.
Exemplul devenit clasic pentru
explicarea apelului prin referinţă este cel al funcţiei de
permutare (interschimbare) a două variabile.
Parametri funcţiei schimb sunt
transmişi prin valoare: parametrilor formali x, y li se atribuie (la
apel) valorile parametrilor efectivi a, b. Funcţia schimb permută
valorile parametrilor formali x şi y, dar
permutarea nu are efect asupra parametrilor efectivi a şi b.
Fie funcţia schimb definită astfel:
void
schimb (double x, double y)
{
double t=x; x=y; y=t; }
void
main()
{
double a=4.7, b=9.7;
. . .
. . . . . . . .
schimb(a,
b); // apel funcţie
. . .
. . . . . . . .
cout<<a<<”
“<<b;//va afisa tot 4.7 si 9.7
}
Pentru ca funcţia de
interschimbare să poată permuta valorile parametrilor efectivi, în
limbajul C/C++ parametrii formali trebuie să fie referinte către valorile care trebuie interschimbate:
void schimb(double &x, double &y)
{ int
t=x; x=y; y=t; }
void
main()
{
double a=4.7, b=9.7;
schimb(a,b);
cout<<a<<” “<<b;//afiseaza 9.7 4.7
}
În acest caz, x
şi y sunt sinonime cu a şi b (nume diferite pentru aceleaşi
grupuri de locaţii de memorie). Interschimbarea valorilor variabilelor de
x şi y înseamnă interschimbarea valorilor variabilelor a şi b
Comparând
cele trei moduri de transmitere a parametrilor către o funcţie, se
poate observa:
1.
La apelul prin valoare
transferul datelor este unidirecţional,
adică valorile se transferă numai de la funcţia apelantă
către cea apelată. La apelul prin
referinţă transferul datelor este bidirecţional, deoarece o modificare a parametrilor formali
determină modificarea parametrilor efectivi, care sunt sinonime (au nume
diferite, dar referă aceleaşi locaţii de memorie).
2.
La transmiterea parametrilor prin
valoare, ca parametrii efectivi pot apare expresii sau nume de
variabile. La transmiterea parametrilor prin
referinţă, ca parametri efectivi nu pot apare expresii, ci doar nume de variabile.(altfel eroare
logica. Nu va fi semnalata si o eroare de sintaxa!) La transmiterea
parametrilor prin pointeri, ca parametri
efectivi pot aparea expresii de pointeri.
3.
Transmiterea parametrilor unei funcţii prin referinţă
este specifică limbajului C++.
Fie functia urmatoare:
void calcule(int v[20],int
n)
{for(int I=1;I<=n;I++)
v[I]=2*I;
}
void main()
{int a[20],nr;
nr=5;
for(int k=1;k<=nr;k++)
a[k]=k;
calcule(a,nr);
for(k=1;k<=nr;k++)
cout<<a[k]<<” “;//afiseaza 2 4 6 8 10
}
La revenirea in
main se pastreaza modificarile survenite in functia calcule asupra vectorului. Explicatie:
numele unui vector este un poiner constant ceea ce inseamna ca atunci cand se
transmit tablouri in functii, mecanismul de tranmitere a parametrilor va fi cel
de transmitere prin pointeri.