Professional Documents
Culture Documents
Limbajul de programare C
Unitati functionale :
- functii (in programele C : functii care returneaza o valoare)
- proceduri (in programele C : functii declarate de tip void )
08.04.21 Lucian Cucu - The C Programming Language 2
West University of Timisoara
Faculty of Mathematics and Informatics Programming I
int main()
{
...
…
}
Definitii de functii
} domeniu de identificator
#
int f()
{
O functie este executata
return expr; doar in urma apelarii!
}
08.04.21 Lucian Cucu - The C Programming Language 6
West University of Timisoara
Faculty of Mathematics and Informatics Programming I
Function:
- declaratie (prototip) – in orice unitate de translatare (fisier sursa) in care e apelata
- apeluri – mai multe, chiar in aceeasi unitate de translatare
- definitie – unica in toate unitatile de translatare ale unei aplicatii
Type f(); /*prototype */ /* no calls to f()! */
int main()
{...
f(); /*call of f() */
...
f(); /*call of f() */
} Type f(); /*prototype */
Type f2()
/*definition of function f */ {...
Type f() f(); /*call of f() */
}
{
…
}
Declaratie de functie :
Tip nume_functie (<lista_decalaratii_de_tip> );
Definitie de functie :
Tip nume_functie (<lista_decalaratii_parametri> )
{
/*declaratii de variabile locale si de functii*/
/* instructiuni*/
…
return expresie; /* expresia trebuie sa fie de tipul Tip */
}
Apel de functie:
nume_functie (<lista_argumente_actuale> );
var = nume_functie (< lista_argumente_actuale > );
Functii: taxonomie
#include <stdlib.h>
#define N 1000
void init(int [], int);
declaratie (prototip) de functie
void sort(int [], int);
functie apelanta
int main()
{
int a[N], b[2*N]; apel de functie
...
init(b, 2*N); argumente actuale
...
}
argumente formale (parametri)
void init(int t[], int n)
{
int i; definitie functie apelata
for(i=0;i<n; i++)
t[i]=rand();
}
int main()
{
int a[N], b[2*N];
init(a, N);
t a n N init(b, 2*N);
sort(a,N);
sort(b, 2*N);
t b n 2*N
}
void f1(void);
c
o
u void f2(void);
Stiva n void f1(void)
SP: t
(date automatice) {
count++;
f2();
}
int getint()
{
int x;
scanf(“%d”, &x);
return x;
}
SP:
Stiva
x: 1234
nr: 1234
adresa de revenire
Context de apel
argumente actuale
contextul de apel al
functiei apelante
08.04.21 Lucian Cucu - The C Programming Language 13
West University of Timisoara
Faculty of Mathematics and Informatics Programming I
Conventia de apel C :
Argumentele se transmit (de catre functia apelanta) catre functia apelata
- prin valoare
- in ordine inversa
...
a N);
init(a, N
SP:
...
In timpul
apelului
void init(int t[], int n) i:
{ return
int i; address context de apel
for(i=0;i<n; i++) t: a
t[i]=rand(); n: N
} anterior /ulterior apelului
Contextul de apel
al apelantului
08.04.21 Lucian Cucu - The C Programming Language 14
West University of Timisoara
Faculty of Mathematics and Informatics Programming I
Valoarea de return :
- se plaseaza intr-un registru (sau mai multi registri) de catre functia apelata
- este “preluata” de catre functia apelanta din acelasi registru (registri)
Exceptie:
daca valoarea de return este o structura, adresa unei zone de memorie unde se
copiaza valoarea structurii este transmisa in registru catre functia apelanta.
Argumente pro:
"recursive code is more compact, and often much easier to write and understand
than the non-recursive equivalent. Recursion is especially convenient for
recursively defined data structures like trees." (K&R, 4.10)
Argumente contra:
recursive functions need more storage area and take more time to execute
than the non-recursive equivalent, because of the additional overhead
incurred by the repeated function calls.
Atentie:
orice functie recursiva trebuie sa testeze o conditie de oprire a
apelului recursiv pentru a preveni apelarea la nesfarsit!
/* compute factorial of n */
unsigned long factorial(unsigned int n)
{
if(n<=1) /* if FALSE stop recursive calls*/
return 1; /* and return to previous call */
else
return n*factorial(n-1);
}
return addr
n:
1
/* compute factorial of n */ return addr
unsigned long factorial(unsigned int n
n=3)
n=4
n=1
n=2 n: 2
{
if(n<=1) return addr
n:
3
return 1
1; return addr
n: 4
else result:
6
2 24
24
n-1
return n* factorial(n-1)
factorial(n-1);
} n-1
n-1
Daca
- apelul recursiv nu este oprit niciodata (pentru ca lipseste/nu este corecta conditia de oprire!)
sau
- apelul recursiv se repeta de multe ori