Functii si variabile in C si C++**
-
Upload
bilinschi-luca-ionel -
Category
Documents
-
view
15 -
download
0
description
Transcript of Functii si variabile in C si C++**
Functii si variabile in C si C++
Funcii.1. Apelarea funciilor.
In C noiunea de funcie este esenial, deoarece asigur un mecanism de abstractizare a controlului: rezolvarea unei pri a problemei poate fi ncredinat unei funcii, moment n care suntem preocupai de ce face funcia, fr a intra n detalii privind cum face funcia anumite operaii. nsi programul principal este o funcie cu numele main(), iar programul C este reprezentat de o mulime de definiri de variabile i de funcii.
Funciile pot fi clasificate n:
funcii care ntorc un rezultat
funcii care nu ntorc nici un rezultat (similare procedurilor din Pascal).
Apelul (referirea sau utilizarea) unei funcii se face prin:
nume_funcie (list_parametri_efectivi)Acesta poate apare ca o instruciune, n cazul funciilor care nu ntorc un rezultat:
nume_funcie (list_parametri_efectivi);De exemplu:
printf(x=%5.2lf\n,x);
mesaj();
Pentru funciile care ntorc un rezultat apelul de funcie poate apare ca operand ntr-o expresie.
De exemplu:
y=sin(x);
nr_zile=bisect(an)+365;
Se remarc faptul c lista de argumente (sau de parametri efectivi) poate fi vid.
Funciile comunic ntre ele prin lista de argumente i prin valorile ntoarse de funcii. Comunicarea poate fi realizat i prin variabilele externe, definite n afara tuturor funciilor.
Exemplul 11: O fracie este cunoscut prin numrtorul x i numitorul y, valori ntregi fr semn. S se simplifice aceast fracie.Simplificarea se va face prin cel mai mare divizor comun al numerelor x i y. Vom utiliza o funcie avnd ca parametri cele dou numere, care ntoarce ca rezultat , cel mai mare divizor comun a lor. Funcia main() apeleaz funcia cmmdc() transmindu-i ca argumente pe x i y. Funcia cmmdc() ntoarce ca rezultat funciei main(), valoarea celui mai mare divizor comun. Programul, n care vom ignora deocamdat definirea funciei cmmdc(), este:
#include
void main(void)
{ unsigned long x, y, z;
scanf(%lu%lu, &x, &y);
printf(%lu / %lu =, x, y);
z=cmmdc(x,y);
x/=z;
y/=z;
printf(%lu / %lu\n, x, y);}
2. Definiii de funcii.
n utilizarea curent, o funcie trebuie s fie definit nainte de a fi apelat. Aceasta impune o definire a funciilor programului n ordinea sortrii topologice a acestora: astfel mai nti se vor defini funciile care nu apeleaz alte funcii, apoi funciile care apeleaz funcii deja definite. Este posibil s eliminm aceast restricie, lucru pe care l vom trata ulterior.
O funcie se definete prin antetul i corpul funciei.
Funciile nu pot fi incluse unele n altele; toate funciile se declar pe acelai nivel cu funcia main.
In versiunile mai vechi ale limbajului, n antetul funciei parametrii sunt numai enumerai, urmnd a fi declarai ulterior. Lista de parametri, n acest caz, este o enumerare de identificatori separai prin virgule.
tip_rezultat nume_functie( lista_de_parametri_formali )
{ declarare_parametri_formali;
alte_declaratii;
instructiuni;
}
In mod uzual parametrii funciei se declar n antetul acesteia. Declararea parametrilor se face printr-o list de declaraii de parametri, cu elementele separate prin virgule.
tip_rezultat nume_functie( tip nume, tip nume,... )
{ declaratii;
instructiuni;
}O funcie este vizibil din locul n care a fost declarat spre sfritul fiierului surs (adic definiia funciei precede apelul).
Definirea funciei cmmdc() se face folosind algoritmul lui Euclid.
unsigned long cmmdc(unsigned long u, unsigned long v)
{ unsigned long r;
do {r=u%v;
u=v;
v=r;
} while (r);
return u;
}
In cazul n care apelul funciei precede definiia, trebuie dat, la nceputul textului surs, un prototip al funciei, care s anune c definiia funciei va urma i s furnizeze tipul rezultatului returnat de funcie i tipul parametrilor, pentru a permite compilatorului s fac verificrile necesare.
Prototipul unei funcii are un format asemntor antetului funciei i servete pentru a informa compilatorul asupra:
tipului valorii furnizate de funcie;
existena i tipurile parametrilor funciei
Spre deosebire de un antet de funcie, un prototip se termin prin ;tip nume( lista tipurilor parametrilor formali);
Din prototip intereseaz numai tipurile parametrilor, nu i numele acestora, motiv pentru care aceste nume pot fi omise.
void f(void); /*functie fara parametri care nu intoarce nici un rezultat*/
int g(int x, long y[], double z);
int g(int, long[], double);/*aici s-au omis numele parametrilor*/
Dintre toate funciile prezente ntr-un program C prima funcie lansat n execuie este main(), independent de poziia pe care o ocup n program.
Apelul unei funcii g(), lansat din alt funcie f() reprezint un transfer al controlului din funcia f(), din punctul n care a fost lansat apelul, n funcia g(). Dup terminarea funciei g() sau la ntlnirea instruciunii return se revine n funcia f() n punctul care urmeaz apelului g(). Pentru continuarea calculelor n f(), la revenirea din g() este necesar salvarea strii variabilelor (contextului) din f() n momentul transferului controlului. La revenire n f(), contextul memorat a lui f() va fi refcut.
O funcie apelat poate, la rndul ei, s apeleze alt funcie; nu exist nici o limitare privind numrul de apeluri nlnuite.3. Comunicarea ntre funcii prin variabile externe.
Efecte laterale ale funciilor.
Comunicarea ntre funcii se poate face prin variabile externe tuturor funciilor; acestea i pot prelua date i pot depune rezultate n variabile externe. n exemplul cu simplificarea fraciei vom folosi variabilele externe a, b i c . Funcia cmmdc() calculeaz divizorul comun maxim dintre a i b i depune rezultatul n c. ntruct nu transmite date prin lista de parametri i nu ntoarce vreun rezultat, funcia va avea prototipul void cmmdc():
#include
unsigned long a, b, c; // variabile externe
// definirea functiei cmmdc()
void main(void)
{ scanf(%lu%lu, &a, &b);
printf(%lu / %lu = , a, b);
cmmdc();
a/=c;
b/=c;
printf(%lu / %lu\n, a, b);}Definiia funciei cmmdc()din Exemplul 11, este:
void cmmdc()
{ unsigned long r;
do {
r=a%b;
a=b;
b=r;
} while (r);
c=a;
}
Dac se execut acest program, se constat un rezultat ciudat, i anume, orice fracie, prin simplificare ar fi adus la forma 1/0 ! Explicaia const n faptul c funcia cmmdc() prezint efecte laterale, i anume modific valorile variabilelor externe a, b i c; la ieirea din funcie a==c i b==0, ceeace explic rezultatul.
Aadar, un efect lateral (sau secundar),reprezint modificarea de ctre funcie a unor variabile externe.
n multe situaii aceste efecte sunt nedorite, duc la apariia unor erori greu de localizat, fcnd programele neclare, greu de urmrit, cu rezultate dependente de ordinea n care se aplic funciile care prezint efecte secundare. Astfel ntr-o expresie n care termenii sunt apeluri de funcii, comutarea a doi termeni ar putea conduce la rezultate diferite!
Vom corecta rezultatul, limitnd efectele laterale prin interzicerea modificrii variabilelor externe a i b, ceea ce presupune modificarea unor copii ale lor n funcia cmmdc()sau din programul de apelarevoid cmmdc(void)
{ unsigned long r, ca, cb;
ca=a;
cb=b;
do{
r=ca%cb;
ca=cb;
cb=r;
} while (r);
c=ca;
Singurul efect lateral permis n acest caz modificarea lui c asigur transmiterea rezultatului ctre funcia apelant.
Soluia mai natural i mai puin expus erorilor se obine realiznd comunicaia ntre funcia cmmdc() i funcia main() nu prin variabile externe, ci prin parametri, folosind o funcie care ntoarce ca rezultat cmmdc.
Transmiterea parametrilor prin valoare, mecanism specific limbajului C, asigur pstrarea intact a parametrilor actuali x i y, dei parametrii formali corespunztori: u i v se modific! Parametrii actuali x i y sunt copiai n variabilele u i v, astfel nct se modific copiile lor nu i x i y.
In fiierul surs funciile pot fi definite n orice ordine.Mai mult, programul se poate ntinde n mai multe fiiere surs. Definirea unei funcii nu poate fi totui partajat n mai multe fiiere.
O funcie poate fi apelat ntr-un punct al fiierului surs, dac n prealabil a fost definit n acelai fiier surs, sau a fost anunat.
Exemplul 12:
#include
#include
unsigned long fact(unsigned char);// prototipul anunta functia
void main()
{ printf("5!=%ld\n", fact(5));// apel functie
printf("10!=%ld\n", fact(10));
getch();
}
long fact(unsigned char n)
// antet functie
{ long f=1;
// corp functie
short i;
for (i=2; i