Documente Academic
Documente Profesional
Documente Cultură
Functii
n general, un program este alcatuit dintr-un ansamblu de module, fiecare
modul corespunznd unei subprobleme a problemei date. La rndul lor, aceste subprobl
eme pot fi descompuse n alte subprobleme, acest proces de descompunere progresiva
putnd continua pna se obtin probleme simple, alcatuite doar din cteva instructiuni
. Identificarea acestor subprobleme, care vor fi mai simplu de tratat, presupune
determinarea unor prelucrari similare efectuate asupra unor informatii diferite
, sau mpartirea problemei n subprobleme, mai simple, dar avnd semnificatii clare. D
escrierea n limbajul C a unei astfel de subprobleme constituie o functie. Deci o
functie este o unitate de sine statatoare de cod (instructiuni) proiectata pentr
u a realiza (rezolva) o anumita problema (task). O functie C joaca acelasi rol p
e care l au functiile, subrutinele si procedurile n alte limbaje de programare, de
si detaliile pot fi diferite.
Aceste functii sunt organizate, din punct de vedere functional (al apelu
rilor), ntr-o structura ierarhica; n vrful acestei ierarhii se afla functia princip
ala (main), sau modulul principal, care apeleaza modulele de la nivelurile infer
ioare. O functie poate fi apelata nu numai de catre functia (modulul) principal,
dar si de alte functii.
Folosirea functiilor presupune existenta unor mecanisme de definire si a
pelare a acestora. Pentru identificarea unei functii, acesteia i se asociaza un
nume, distinct de numele altor functii. Pentru a specifica informatiile pe care
functia le schimba cu o alta functie, sau modulul principal, de care va fi apela
ta, functiei i se asociaza o lista de parametri. n cadrul definirii unor functii,
acesti parametri sunt denumiti parametri formali (ntruct au rol descriptiv; descr
iu operatiile efectuate de functie). n cadrul apelului unei functii, parametrii s
e numesc actuali sau efectivi, si acestia i vor nlocui pe cei formali, n momentul a
pelului.
Si n exemplele utilizate anterior s-au folosit functii, de exemplu pentru
citirea, respectiv scrierea datelor s-au utilizat functiile: scanf() si printf
().
Pe lnga aceste functii de biblioteca, un program C poate contine o singur
a functie, main(), ca n exemplele prezentate pna acum.
Spre deosebire de Pascal, o functie C nu poate contine alte functii. Functiile d
antet, care v
efinite de utilizator pot fi incluse ntr-unul sau mai multe fisiere
or fi compilate separat.
n general, o functie poate realiza att actiuni ct si furniza rezultate.
6.1. Definirea functiei si transferul parametrilor
Formatul general pentru definirea unei functii este:
tip_returnat nume_functie (tip1 param1, tip2 param2, )
{
declaratii_variabile_locale
/* corpul functiei:
prelucrarile efectuate de aceasta */
. . . . . . . . . . .
return (expresie);
}
Se defineste functia nume_functie , care returneaza o valoare de un anumit
tip
tip_returnat (tipul expresiei)
si are parametrii formali param1, param2,
, dec
larati de tipurile: tip1, tip2,
.
Daca functia nu returneaza o valoare, tip_returnat nu este specificat sau
este void (adica nimic). Daca functia returneaza o valoare de tip int, tip_return
at poate fi omis, desi specificarea tipului int, ca valoare returnata, este o mai
buna practica de programare (si se recomanda, pentru a pune n evidenta valoarea
returnata). Daca ntre paranteze se specifica numai void, functia nu are argumente
.
Daca se utilizeaza puncte ( ) ca ultimul (sau singurul) parametru n lista d
e parametri, functia va lua un numar variabil de argumente, ca n declaratia:
int printf (char*format, )
{
. . . .
}
Declaratiile pentru argumente de tip tablou cu o singura dimensiune nu t
rebuie sa specifice numarul de elemente din tablou. Pentru tablouri multidimensi
onale, marimea fiecarei dimensiuni, mai putin prima, trebuie specificata.
Daca functia returneaza o singura valoare, tipul acesteia precede numele
functiei, iar valoarea returnata este cea indicata de declaratia return (expres
ie);. Parantezele ce includ expresia sunt optionale, dar ele sunt folosite de mu
lti programatori.
Spre deosebire de Pascal sau Fortran n care sunt diferite proceduri (subr
utine) ce returneaza oricte valori, inclusiv nici una, si functii care returneaza
o singura valoare, limbajul C nu face deosebire ntre acestea. n C sunt doar funct
ii, care pot, optional, returna o singura valoare, n modul descris anterior.
O functie care returneaza o valoare poate fi utilizata n expresii, n timp
ce o functie de tip void nu are o valoare si nu poate fi utilizata ntr-o expresie
.
Formatul general al apelului unei functii este:
nume_functie (arg1, arg2, );
Valorile arg1, arg2, sunt transmise ca argumente efective pentru functie
. Daca functia nu are argumente, sunt specificate, obligatoriu, cele doua parant
eze ( ).
Daca se apeleaza o functie care este descrisa (definita), dupa apelul sa
u, sau definita n alt fisier trebuie inclusa o declaratie a prototipului functiei
, ce are formatul general:
tip_returnat nume_functie (tip1 param1, tip2 param2,
);
Aceasta declaratie precizeaza compilatorului tipul valorii returnate de
functie, numarul de argumente pe care le ia si tipul fiecarui argument. De exem
plu:
long double power (double x, int n);
Numele argumentelor dintre paranteze pot fi omise, ntruct important este t
ipul argumentelor si nu numele lor:
long double power (double, int);
deoarece numele sunt nesemnificative n acest moment.
Daca compilatorul a ntlnit anterior definitia functiei sau o declaratie de
prototip pentru functie, fiecare argument va fi automat convertit pentru a se p
otrivi cu tipul asteptat de functie, cnd aceasta este apelata.
Daca nu a fost ntlnita nici definitia functiei, nici o declaratie de proto
tip, compilatorul va presupune ca functia returneaza o valoare de tip int, si va
converti automat toate argumentele de tip float la tipul double, iar cele de ti
p char sau short int la tipul int, nainte de a le transmite functiei. Celelalte t
ipuri de argumente ale functiei vor fi transmise fara conversie.
Toate argumentele pentru o functie pot fi transmise prin valoare; adica
valorile transmise, prin variabile sau expresii, sunt utilizate pentru a initial
iza argumentele formale ale functiei, si deci valorile argumentelor efective nu
pot fi modificate de functie. Functia nu are acces niciodata la argumentele actu
ale (efective) ale apelului, daca sunt transmise prin valoare. Valorile pe care
le manipuleaza functia sunt propriile sale copii, locale, care sunt memorate n st
iva. Odata ce functia se termina stiva este descarcata, deci aceste valori local
e se pierd. Din acest motiv argumentele actuale nu sunt modificate, ceea ce nseam
na ca programatorul nu trebuie sa salveze si sa refaca valorile argumentelor, la
apelul unei functii.
Transferul parametrilor prin valoare nu este potrivit n situatiile:
cnd se transfera un obiect mare: necesita timp si spatiu pentru a aloca s
i copia obiectul n stiva, care poate fi prea mare pentru aplicatii n timp real;
cnd valorile argumentelor trebuie sa fie modificate.
Daca un pointer (referinta) este transmis unei functii, functia poate mo
difica valorile referite de pointer, dar nu poate modifica valoarea acestui poin
ter.
Utilizarea referintei (pointerului) unui argument pentru transmiterea ac
estuia se impune cnd functia trebuie sa returneze rezultate. De asemenea poate fi
st redeclarate.
Variabilele definite n cadrul unei functii sunt denumite si variabile loc
ale automatice, deoarece ele sunt automat create la apelul functiei si valorile lo
r sunt locale functiei.
Variabilele locale, declarate ntr-o functie (bloc) exista numai pe durata
executiei acelei functii (bloc), fiind create la intrarea n functie, prin alocar
e de memorie, si distruse la iesirea din functie, prin eliberarea memoriei ocupa
te.
Variabilele declarate n exteriorul unui bloc pot fi referite din cadrul b
locului; pentru acest bloc, variabilele acestea sunt nelocale (sau globale).
ntr-un bloc (al unei functii) sunt accesibili toti identificatorii defini
ti n acel bloc, precum si cei din blocurile n care acesta este inclus. Pentru oric
are din acesti identificatori, definitia valabila n blocul considerat este cea af
lata n blocul cel mai apropiat.
Parametrii formali declarati n prototipul functiei pot fi folositi pentru
a referi argumentele functiei oriunde n cadrul corpului functiei.
Exemplu de utilizare a variabilelor globale: programul converteste un numar ntreg
ntr-o alta baza.
/*
*/
#include <stdio.h>
int numar_convertit[16];
int numar, baza;
void main(void)
{
void citeste_numar_baza(void);
void conversie (void);
citeste_numar_baza();
if (baza < 2 || baza > 16)
{
printf ("Baza eronata ! Implicit baza = 10 \n");
baza = 10;
}
conversie();
}
void citeste_numar_baza(void)
{
printf ("Numar de convertit:");
scanf ("%d", &numar);
printf ("In baza:");
scanf ("%d", &baza);
}
void conversie (void)
{
char cifra_baza[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','
F'};
int index=0;
if (numar < 0)
{
printf("-");
numar = -numar;
}
do
{
numar_convertit[index] = numar % baza;
numar /= baza;
index ++;
} while (numar != 0);
for ( --index ; index >= 0 ; --index )
printf ("%c", cifra_baza[numar_convertit[index]]);
printf ("\n");
}
n acest exemplu, functiile definite nu au argumente, motiv pentru care la declara
rea functiilor s-a utilizat tipul void pentru argumente; de asemenea functiile n
u returneaza nici o valoare. Prelucrarile efectuate de aceste functii se fac, de
fapt, asupra variabilelor globale, definite n afara functiilor.
Efecte laterale
Orice functie, fie ca nu este de tip void si calculeaza o valoare pe car
e o ntoarce ca rezultat al apelului sau, fie ca este de tip void, poate modifica
si variabilele globale (sau nelocale) ale programului, pe lnga valorile transmise
ca parametrii, prin referinta (pointeri).
Acestea constituie efecte laterale ale functiei si, de obicei, fac nteleg
erea programelor mai dificila. Din acest motiv se evita modificarea variabilelor
globale n cadrul functiilor.
De asemenea, daca dorim ca functia sa nu modifice valorile parametrilor,
chiar daca sunt transmisi prin referinta, parametrii respectivi trebuie declara
ti de tip const n antetul functiei. n acest fel se evita unele erori de programare
, dar si prelucrarile realizate de functie devin mai clare.