Functii si variabile in C si C++**

download Functii si variabile in C si C++**

of 11

description

kk

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