Sunteți pe pagina 1din 9

Laborator functii

Un program conine una sau mai multe funcii. Fiecare funcie are un nume. Numele
funciei principale este main, iar numele celorlalte funcii sunt definite de utilizator.

Definitia unei functii


Forma general a unei funcii este:
specificator_de_tip nume_functie (lista_parametri)
{
corpul functiei
}
Specificator_de_tip indic tipul de date returnat de funcie. O funcie poate returna orice
tip de date, cu excepia tablourilor. Lista_parametri este o list de nume de variabile i a tipurilor
asociate acestora, separate prin virgul, care primesc valorile argumentelor la apelul funciei.
Unei funcii i pot lipsi parametrii, caz n care lista de parametri este vid. Totui, chiar dac
funcia nu are parametri, parantezele sunt necesare.
n cazul declaraiilor de variabile, mai multe variabile pot fi declarate ca fiind de acelai
tip folosind o list de nume de variabile, separate prin virgul. Spre deosebire de acestea, toi
parametrii unei funcii trebuie declarai individual, fiecare declaraie trebuind s conin numele
i tipul parametrului. Ca atare, lista de declarare a parametrilor unei funcii are forma:
f(tip numevar1, tip numevar2,..., tip numevarN)
Declararea unei functii
Declaratia unei functii informeaza compilatorul despre existenta functiei si formatul
acesteia. Mai exact, o declaratie de functie specifica numele functiei, tipul rezultatului returnat de
functie si parametrii acesteia:
tip nume( lista_parametri);

Apelul functiilor
Apelul unei functii se poate realize in doua moduri: printr-o instructiune de apel sau ca
operand intr-o expresie.
Format general instructiune de apel al unei functii:
nume(lista_parametri);

In cazul in care se doreste utilizarea valorii returnata de functie ca operand intr-o expresie, se va
apela functia in cadrul expresiei, astfel:
nume(lista_parametri)

Revenirea dintr-o funcie


Revenirea dintr-o funcie se poate realiza n dou moduri:
- dup execuia ultimei instruciuni din corpul funciei;
- la ntlnirea instruciunii return.
Instruciunea return este instruciunea de revenire din funcie. Ea are formatele:
- return
- return expresie
Formatul al doilea se folosete n corpul unei funcii care returneaz o valoare la
revenirea din ea. Valoarea expresiei din instruciunea return este chiar valoarea returnat de
funcie.
n cazul n care tipul acestei expresii difer de tipul din antet, valoarea expresiei se
convertete automat spre tipul din antet, nainte de a reveni din funcie. Se folosete revenirea din
funcie fr instruciunea return sau cu ajutorul instruciunii return fr a fi urmat de o expresie
atunci cnd funcia nu returneaz nici o valoare.
Exemplu:
#include <stdio.h>
int sum(int a, int b);

/*prototipul sau declaratia functiei; a si b


sunt parametrii formali ai functiei. Numele
parametrilor formali pot lipsi*/

void main ()
{
int r;
r=sum(17,23); //17 si 23 sunt argumentele functiei
printf("Valoarea lui r este:%d\n ",r);
int x,y;
x=17;
y=23;
printf("Suma variabilelor x si y este: %d\n",sum(x,y));
}
int sum(int a, int b)
{
return a+b;
}

//definitia functiei

Exercitiu:
1. S se scrie un program care calculeaz media aritmetic dintre minimul i maximul
unui ir de numere dintr-un tablou unidimensional de ntregi. Se vor implementa
functii pentru gasire minim si maxim, pentru calcul medie aritmetica si pentru afisare
tablou.

Parametrii locali, parametrii formali i parametrii actuali


n utilizarea funciilor se pot deosebi dou tipuri de parametri, n funcie de specificul lor:
- parametrii formali;
- parametrii actuali;
Variabilele care sunt declarate n interiorul unei funcii se numesc variabile locale i sunt
accesibile doar n interiorul funciei respective. Valorile reinute n aceti parametri se pierd odat
cu ieirea din blocul respectiv.
Exemplu: funcie pentru calculul minimului dintr-un ir de numere:
int getmin (int n, int a[])
{
int min, i; // min, i - variabile locale
min = a[0];
for (i = 1; i < n; i++)
if (min > a[i])
min = a[i];

return min;

Argumentele (parametrii) cu care este definit o funcie sunt numii parametrii formali.
Dup ce a fost definit funcia, parametrii formali pot fi folosii n funcia respectiv ca i
variabile locale obinuite. Ei sunt numii formali deoarece funcia nu va fi apelat cu
parametrii respectivi, ci cu parametrii de tipurile respective (ei sunt precizai pentru a se cunoate
prototipul funciei respective).
Parametrii actuali sunt parametrii cu care se apeleaz propriu-zis o funcie.
n exemplul urmtor se pot observa cele dou tipuri de parametrii:
float medie (int a, int b) // a, b - parametrii formali
{
float c;
// c variabil local
c = (a + b) / 2;
return c;
}
int main (void)
{
int y, z;
// x, y, z - variabile locale
float x;
x = calcul (y, z);// y, z - parametrii actuali
printf (Rezultatul este %f, x);
return 0;
}

Transmiterea parametrilor prin valoare, transmiterea prin


adres
n general, este necesar transmiterea valorilor calculate ntr-o funcie, pentru a putea fi
folosite ntr-o alt funcie. Transmiterea valorilor se poate face n dou moduri:
- prin valoare;
- prin adres;

Transmiterea parametrilor prin valoare


Transmiterea parametrilor prin valoare const n copierea valorii unui argument ntr-un
parametru formal al unei funcii. n cazul transmiterii prin valoare, modificrile efectuate asupra
parametrului formal NU au efect asupra argumentului funciei. Transmiterea parametrilor prin
valoare este cea mai folosit metod de transfer din limbajul C.
Exemplu: Se doreste implementarea unei functii care interschima valorile a doi parametric
primiti.
void schimb(int x, int y)
{
int aux;
aux=x;
x=b;
y=aux;
}
void main()
{
int a=10,b=5;
printf(a=%d, b=%d\n,a,b);
schimb(a,b);
printf(a=%d, b=%d\n,a,b);
}

Care va fi rezultatul programului anterior? Cele doua variabile, a si b, isi vor schimba valorile in
urma apelului functiei schimb()?

Transmiterea parametrilor prin adres


n limbajul C exist i instrumente prin care se poate simula un transfer prin referin.
Pentru a transfera un obiect V ca parametru prin referin, se transfer un pointer ctre V;
parametrul formal va fi un pointer ctre valoarea obiectului V.
Transmiterea parametrilor prin referin const n copierea adresei unui argument ntr-un
parametru. n funcia n care se face apelarea, este folosit adresa respectiv pentru accesarea
argumentului folosit efectiv la apelare.

n transmiterea prin adres, modificrile efectuate asupra unui parametru formal


afecteaz argumentul cu care se face apelarea funciei (parametrul actual). Pentru a folosi
transmiterea prin referin, argumentele funciei trebuie declarate ca pointeri.
Exemplu:
void schimb(int *x, int *y)
{
int aux;
aux=*x;
*x=*y;
*y=aux;
}
void main()
{
int a=10,b=5;
printf(a=%d, b=%d\n,a,b);
schimb(&a,&b);
printf(a=%d, b=%d\n,a,b);
}

Care va fi rezultatul programului anterior? Cele doua variabile, a si b, isi vor schimba
valorile in urma apelului functiei schimb()?

Transmiterea de argumente in functia main()


n situatiile n care se doreste transmiterea a unor informatii (optiuni, date initiale, etc)
catre un program, la lansarea n executie a acestuia, este necesara definirea unor parametri catre
functia main. Se utilizeaza trei parametrii speciali: argc,argv si env. Trebuie inclus
headerul stdarg.h.
Prototipul functiei main cu parametri n linia de comanda este:
main (int argc, char *argv[ ], char *env[ ])

Daca nu se lucreaza cu un mediu de programare integrat, argumentele transmise catre functia


main trebuie editate (specificate) n linia de comanda prin care se lanseaza n executie programul
respectiv. Linia de comanda tastata la lansarea n executie a programului este formata din grupuri
de caractere delimitate de spatiu sau tab. Fiecare grup este memorat ntr-un sir de caractere. Daca
se lucreaza cu un mediu integrat (de exemplu, BorlandC), selectia comanzii Arguments. din
meniul Run determina afisarea unei casete de dialog n care utilizatorul poate introduce
argumentele functiei main.
Adresele de nceput ale acestor siruri sunt memorate n tabloul de pointeri argv[], n
ordinea n care apar n linia de comanda (argv[0] memoreaza adresa sirului care constituie
numele programului, argv[1] - adresa primului argument, etc.).

Parametrul ntreg argc memoreaza numarul de elemente din tabloul argv (argc>=1).

Parametrul env[] este un tablou de pointeri catre siruri de caractere care pot specifica
parametri ai sistemului de operare.

Functia main poate returna o valoare ntreaga. n acest caz n antetul functiei se specifica la tipul
valorii returnate int, sau nu se specifica nimic (implicit, tipul este int), iar n corpul functiei
apare instructiunea return valoare_intreaga;. Numarul returnat este transferat sistemului de
operare (programul apelant) si poate fi tratat ca un cod de eroare sau de succes al ncheierii
executiei programului.
Exercitiu: Sa se implementeze un program care afiseaza argumentele transmise catre functia
main.
#include <stdio.h>
#include <stdarg.h>
void main(int argc, char *argv[], char *env[])

Exercitii functii:
1. Functie care verifica daca un numar dat este prim sau nu. Program
pentru afisarea descompunerilor numerelor pare mai mici ca un intreg dat
in sume de doua numere prime (Ipoteza lui Goldbach = orice numar par se
poate scrie ca suma a doua numere prime).
2. Functie care primeste doi intregi a si b si determina alti doi
intregi k si c astfel ca a = c * b^k ( b este un divizor posibil al lui a,
k este ordinul de multiplicitate, c este numarul ramas dupa k impartiri
repetate a lui a prin b). Program pentru descompunerea unui numar dat in
factori primi (cu puterile lor) folosind functia. Exemplu:
360 = 2^3 * 3^2 * 5^1
3. Functie care determina pozitia valorii maxime intr-un vector. Program
pentru ordonarea unui vector de numere prin determinarea repetata a valorii
maxime dintr-un vector si schimbarea cu ultimul element din vector.
4. Functie care determina semnul unui numar intreg ("sign") si are
rezultat 0 (valoare zero), -1 (numar negativ) sau +1 (numar pozitiv).
Functie care determina numarul cadranului in care se afla un punct de

coordonate intregi date x,y; rezultatul este 0 daca punctul se afla pe


una din axe sau la intersectia axelor. Indicatie: Se face o selectie
("switch") dupa valoarea 3*sign(x)+sign(y). Program de verificare.

Functii recursive
Un obiect sau un fenomen se defineste in mod recursiv daca in definitia sa exista o
referire la el insusi.
Recursivitatea este folosita cu multa eficienta in matematica. Spre exemplu, definitii
matematice recursive sunt:

Definitia functiei factorial


fact:N->N
fact(n)=1, daca n=0
=n*fact(n-1), daca n>0

Definitia functiei Fibonacci


fib:N->N
fib(n)=1, daca n=0 sau n=1
=fib(n-2)+fib(n-1), daca n>1
Recursivitatea e strins legata de iteratie.Iteratia este executia repetata a unei portiuni de
program, pina la indeplinirea unei conditii (while, do-while , for din C).
Recursivitatea presupune executia repetata a unui modul, insa in cursul executiei lui (si nu la
sfirsit, ca in cazul iteratiei), se verifica o conditie a carei nesatisfacere, implica reluarea executiei
modulului de la inceput, fara ca executia curenta sa se fi terminat. In momentul satisfacerii
conditiei se revine in ordine inversa din lantul de apeluri, reluandu-se si incheindu-se apelurile
suspendate.
Apelul recursiv al unei functii trebuie sa fie conditionat de o decizie care sa impiedice
apelul in cascada ( la infinit ); aceasta ar duce la o eroare de program - depasirea stivei.
Exemplu generic:
void p(
p();
}

){ //functie recursiva
//apel infinit

//apelul trebuie conditionat in una din variantele:


if(cond)p();
while(cond)p();
do p()while(cond);

Exemplificare:
Functia recursiva de calcul a factorialului:

int fact(int n){ //


if(n==1)
return 1;
return n*fact(n-1); //apel recursiv
}
//varianta nerecursiva
int fact(int n){
int i,f;
for(i=f=1;i<=n;i++)
f*=i;
return f;
}
// Observatie: tipul functiei trebuie sa devina long pentru
// n>=8 ( 8!>32767 )

Exercitii recursivitate:
1. Sa se scrie o functie recursiva pentru ridicarea unui numar la o putere intreaga
pe baza relatiei de recurenta x^k = x * x^(k-1) si cu x^0=1
2. Sa se scrie o functie recursiva care calculeaza si returneaza suma cifrelor unui numar
natural primit ca parametru.
3. Sa se scrie o functie recursiva care primeste 3 parametri: n - numar natural, c1,c2 cifre si
returneaza numarul obtinut din n prin inlocuirea tuturor aparitiilor cifrei c1 cu c2.
4. Sa se scrie o functie recursiva care primeste un parametru n numar natural si returneaza
numarul obtinut din n prin eliminarea cifrelor pare.
5. Sa se scrie o functie recursiva care primeste ca parametru litera 'A' si afiseaza in ordine
toate literele mari din alfabet.

6. Se citeste un vector a cu n elemente numere naturale. Sa se calculeze elementul maxim


din vector. Se va folosi o functie recursiva pentru citire si una recursiva pentru
determinarea elementului maxim.