You are on page 1of 20

West University of Timisoara

Faculty of Mathematics and Informatics Programming I

Limbajul de programare C

08.04.21 Lucian Cucu - The C Programming Language 1


West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Structura programelor: functii

program C = set de definitii de functii


+ declaratii de functii si variabile globale
+ directive de preprocesare
De ce?
Programele reale sunt foarte mari si complexe!
Dezvoltarea lor ca o singura unitate functionala este
- nepractica
- greu de intretinut/modificat
- imposibil de reutilizat
De aceea, programele sunt descompuse in unitati functionale (deseori, sute sau
mii!), de obicei grupate in conformitate cu rolul lor in economia functionala a
programului in unitati de translatare separate (fisiere sursa).

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

Structura programelor: descompunere functionala


#include <stdlib.h> #include <stdlib.h>
#define N 1000
#define N 1000
enum boolean { FALSE, TRUE};
enum boolean { FALSE, TRUE};
int main()
{ int a[N], b[2*N];
int a[N], b[2*N], i, sorted=FALSE; int main()
for(i=0;i<N; i++) /* init a */ {
a[i]=rand();
for(i=0;i<2*N; i++)
b[i]=rand();
/* init b */ init_a();
while(!sorted) /*sort a */
{ init_b();
sorted=TRUE;
for(i=0; i<N-1;i++)
if(a[i]>a[i+1])
sort_a();
{
int aux;
aux=a[i]; }
sort_b();
a[i]=a[i+1];
a[i+1]=aux;
sorted=FALSE;
} void init_a()
} {
while(!sorted) /*sort b */ ...
{ }
sorted=TRUE; void init_b()
for(i=0; i<N-1;i++) {
if(b[i]>b[i+1]) ...
{ }
int aux;
void sort_a()
aux=b[i];
b[i]=b[i+1]; {
b[i+1]=aux; ...
sorted=FALSE; }
} void sort_b()
} {
... ...
} }
08.04.21 Lucian Cucu - The C Programming Language 3
West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Structura programelor: parametrizarea functiilor


Program.c Main.c
#include <stdlib.h>
#include <stdlib.h> #define N 1000
#define N 1000 enum boolean { FALSE, TRUE};
enum boolean { FALSE, TRUE};
int main() void init(int [], int);
{ void sort(int [], int);
int a[N], b[2*N], i, sorted=FALSE;
for(i=0;i<N; i++) /* init a */ int main()
a[i]=rand(); {
for(i=0;i<2*N; i++) /* init b */ int a[N], b[2*N];
b[i]=rand(); init(a, N);
while(!sorted) /*sort a */ init(b, 2*N);
{ sort(a,N);
sorted=TRUE; sort(b, 2*N);
for(i=0; i<N-1;i++) }
if(a[i]>a[i+1]) Array_f.c
{ void init(int t[], int n)
int aux; {
aux=a[i]; int i;
a[i]=a[i+1]; for(i=0;i<n; i++)
a[i+1]=aux; t[i]=rand();
sorted=FALSE; }
}
} void sort(int t[], int n)
while(!sorted) /*sort b */ {
{ int i, sorted=FALSE;
sorted=TRUE; while(!sorted) /*sort a */
for(i=0; i<N-1;i++) {
if(b[i]>b[i+1]) sorted=TRUE;
{ for(i=0; i<n-1;i++)
int aux; if(t[i]>t[i+1])
aux=b[i]; {
b[i]=b[i+1]; int aux;
b[i+1]=aux; aux=t[i];
sorted=FALSE; t[i]=t[i+1];
} t[i+1]=aux;
} sorted=FALSE;
} }
}
}

08.04.21 Lucian Cucu - The C Programming Language 4


West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Structura programelor: unitati de translatare (fisiere sursa)


File_1.c File_2.c File_n.c

int main()
{
...

}

Definitii de functii

08.04.21 Lucian Cucu - The C Programming Language 5


West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Structura programelor: detalii


file.c
Legenda:
# include <header.h> # directiva de preprocesare
int count;
declaratie de variabila globala
int f();
declaratie de functie (prototip)
int main()
{# declaratie de variabila locala
int val;
definitie de functie
val=f(); /* call of f() */

} 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

Structura programelor: functii

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() */
}
{

}

08.04.21 Lucian Cucu - The C Programming Language 7


West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Structura programelor: functii

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 > );

08.04.21 Lucian Cucu - The C Programming Language 8


West University of Timisoara
Faculty of Mathematics and Informatics Programming I

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();
}

08.04.21 Lucian Cucu - The C Programming Language 9


West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Structura programelor: modalitati de comunicare intre functii


Comunicare: partajare de date #include <stdlib.h>
- prin argumentele actuale, #define N 1000
- prin valoarea returnata enum boolean { FALSE, TRUE};

- prin variabile globale void init(int [], int);


void sort(int [], int);

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 init(int t[], int n)


{
int i;
for(i=0;i<2*n; i++)
t[i]=rand();
}

void init(int t[], int n) void sort(int t[], int n)


{
{ int i, sorted=FALSE;
while(!sorted) /*sort a */
int i; {
sorted=TRUE;
for(i=0;i<n; i++) for(i=0; i<n-1;i++)
if(t[i]>t[i+1])
t[i]=rand(); {
int aux;
} aux=t[i];
t[i]=t[i+1];
t[i+1]=aux;
sorted=FALSE;
Lucian Cucu - The C Programming Language }
08.04.21
} 10
West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Structura programelor: modalitati de comunicare intre functii

Comunicare: partajare de date file.c

- prin variabile globale int count;

void f1(void);

Date Statice int main()


{
count: 1
0
3
2 count++;
f1();
s }
c
o void f2(void)
p {
e count++;

of }

c
o
u void f2(void);
Stiva n void f1(void)
SP: t
(date automatice) {
count++;
f2();
}

08.04.21 Lucian Cucu - The C Programming Language 11


West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Structura programelor: modalitati de comunicare intre functii

Comunicare: partajare de date


- prin valoarea returnata
#include <stdio.h>
int getint();
Date Statice
int main() {
int nr;
nr = getint();
}

int getint()
{
int x;
scanf(“%d”, &x);
return x;
}
SP:
Stiva
x: 1234
nr: 1234

08.04.21 Lucian Cucu - The C Programming Language 12


West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Functii: context de apel

Contextul de apel al unei functii este o zona de memorie de pe stiva pe care:


- se copiaza valoarea argumentelor actuale (in ordine inversa!)
- se salveaza adresa de revenire
- se creaza variabilele locale automatice ale functiei apelate

variabile locale automatice

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

Functii: conventia de apel C

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

Functii: mecanismul de returnare a valorii functiei

Mecanismul de returnare a valorii functiei este implementat ca un protocol


bazat pe tip,
respectat de compilator la compilarea:
- instructiunii return expresie cat si a
- instructiunii care preia valoarea de retur in functia apelanta.

Functia apelanta Functia apelata

... type f()


result=f(); {
... ...
Zona (partajata) de memorie
(tip)ex return expression;
presie }
x pr e sie
(tip)e

08.04.21 Lucian Cucu - The C Programming Language 15


West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Mecanismul de returnare a valorii functiei : un posibil protocol

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.

Return type Public (shared) storage area


char low byte of register R0
short R0
int (2 bytes) R0
long R0, R1
float R0, R1
double R0, R1, R2, R3
long double R0, R1, R2, R3, R4

08.04.21 Lucian Cucu - The C Programming Language 16


West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Functii: functii recursive

Functie recursiva : o functie care se autoapeleaza.

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!

08.04.21 Lucian Cucu - The C Programming Language 17


West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Functii recursive : example


#include <stdio.h>
/* printd: print n in decimal */
void printd(int n)
{
if (n < 0)
{
putchar('-');
n = -n;
}
if (n / 10)
printd(n / 10);

/* if FALSE -> stop recursive calls! and print out a digit */


putchar(n % 10 + '0');
}

/* 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);
}

08.04.21 Lucian Cucu - The C Programming Language 18


West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Functii: apeluri recursive


...
result=factorial(4);
4
...

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

08.04.21 Lucian Cucu - The C Programming Language 19


West University of Timisoara
Faculty of Mathematics and Informatics Programming I

Functii recursive : posibile probleme

Daca
- apelul recursiv nu este oprit niciodata (pentru ca lipseste/nu este corecta conditia de oprire!)
sau
- apelul recursiv se repeta de multe ori

Spatiul disponibil pe stiva poate fi epuizat!


In asemenea cazuri
- daca compilarea s-a facut cu optiunea "check stack overflow"
atunci programul se termina cu mesajul de eroare: "Stack overflow!"
- daca compilarea nu s-a facut cu optiunea "check stack overflow“
atunci rezultatul este imprevizibil!!!

Atunci, daca recursivitatea este mai putin eficienta si potential periculoasa,


de ce se recurge la recursivitate??
Pentru ca:
- este mai simplu de implementat
- anumite tipuri de functii recursive pot fi transformate automat in varianta lor
iterativa care este mai eficienta
!
08.04.21 Lucian Cucu - The C Programming Language 20

You might also like