Extras din curs
In cazul în care apelul functiei precede definitia, trebuie dat, la începutul textului sursa, un prototip al functiei, care sa anunte ca definitia functiei va urma si sa furnizeze tipul rezultatului returnat de functie si tipul parametrilor, pentru a permite compilatorului sa faca verificarile necesare.
Prototipul unei functii are un format asemanator antetului functiei si serveste pentru a informa compilatorul asupra:
• tipului valorii furnizate de functie;
• existenta si tipurile parametrilor functiei
Spre deosebire de un antet de functie, un prototip se termina prin ;
tip nume( lista tipurilor parametrilor formali);
Din prototip intereseaza numai tipurile parametrilor, nu si 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 functiile prezente într-un program C prima functie lansata în executie este main(), independent de pozitia pe care o ocupa în program.
Apelul unei functii g(), lansat din alta functie f() reprezinta un transfer al controlului din functia f(), din punctul în care a fost lansat apelul, în functia g(). Dupa terminarea functiei g() sau la întâlnirea instructiunii return se revine în functia f() în punctul care urmeaza apelului g(). Pentru continuarea calculelor în f(), la revenirea din g() este necesara salvarea starii variabilelor (contextului) din f() în momentul transferului controlului. La revenire în f(), contextul memorat a lui f() va fi refacut.
O functie apelata poate, la rândul ei, sa apeleze alta functie; nu exista nici o limitare privind numarul de apeluri înlantuite.
3. Comunicarea între functii prin variabile externe.
Efecte laterale ale functiilor.
Comunicarea între functii se poate face prin variabile externe tuturor functiilor; acestea îsi pot prelua date si pot depune rezultate în variabile externe. În exemplul cu simplificarea fractiei vom folosi variabilele externe a, b si c . Functia cmmdc() calculeaza divizorul comun maxim dintre a si b si depune rezultatul în c. Întrucât nu transmite date prin lista de parametri si nu întoarce vreun rezultat, functia va avea prototipul void cmmdc():
#include <stdio.h>
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 / %lun”, a, b);
}
Definitia functiei cmmdc()din Exemplul 11, este:
void cmmdc()
{ unsigned long r;
do {
r=a%b;
a=b;
b=r;
} while (r);
c=a;
}
Daca se executa acest program, se constata un rezultat ciudat, si anume, orice fractie, prin simplificare ar fi adusa la forma 1/0 ! Explicatia consta în faptul ca functia cmmdc() prezinta efecte laterale, si anume modifica valorile variabilelor externe a, b si c; la iesirea din functie a==c si b==0, ceeace explica rezultatul.
Asadar, un efect lateral (sau secundar),reprezinta modificarea de catre functie a unor variabile externe.
În multe situatii aceste efecte sunt nedorite, duc la aparitia unor erori greu de localizat, facând programele neclare, greu de urmarit, cu rezultate dependente de ordinea în care se aplica functiile care prezinta efecte secundare. Astfel într-o expresie în care termenii sunt apeluri de functii, comutarea a doi termeni ar putea conduce la rezultate diferite!
Vom corecta rezultatul, limitând efectele laterale prin interzicerea modificarii variabilelor externe a si b, ceea ce presupune modificarea unor copii ale lor în functia cmmdc()sau din programul de apelare
void 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 asigura transmiterea rezultatului catre functia apelanta.
Solutia mai naturala si mai putin expusa erorilor se obtine realizând comunicatia între functia cmmdc() si functia main() nu prin variabile externe, ci prin parametri, folosind o functie care întoarce ca rezultat cmmdc.
Transmiterea parametrilor prin valoare, mecanism specific limbajului C, asigura pastrarea intacta a parametrilor actuali x si y, desi parametrii formali corespunzatori: u si v se modifica! Parametrii actuali x si y sunt copiati în variabilele u si v, astfel încât se modifica copiile lor nu si x si y.
In fisierul sursa functiile pot fi definite în orice ordine.Mai mult, programul se poate întinde în mai multe fisiere sursa. Definirea unei functii nu poate fi totusi partajata în mai multe fisiere.
O functie poate fi apelata într-un punct al fisierului sursa, daca în prealabil a fost definita în acelasi fisier sursa, sau a fost anuntata.
Preview document
Conținut arhivă zip
- Functii si variabile in C si C++.doc