M_Cap7_3
-
Upload
victor-mihai -
Category
Documents
-
view
222 -
download
0
Transcript of M_Cap7_3
-
7/25/2019 M_Cap7_3
1/23
Pointeri la funcii
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
2/23
Particulariti ale limbajului C
Reamintire:
numele unui tablou pointer constant - indic adresa de nceput a tabloului(adresa primului element)
int a [4];
este pointer de tip int *
Similar
numele unei funcii pointer constant - indic adresa de nceput a funciei
int functie ( float x);
este pointer de tip adres a unei funcii cu:- rezultat de tip int- un singur parametru de tip float
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
3/23
int f(float); /* prototipul funciei f, cu rezultat de tip int i un singurparametru de tip float */
int (*adr_f) (float); /* declararea variabilei adr_fca pointer de tip adres a uneifuncii cu rezultat de tip int i un singur parametru de tip float */
float x;..
adr_f = f; /*corect, feste o valoare pointer constant (nume de funcie)*/
adr_f = f(x); /*greit, rezultatul funciei este o valoare de tip int */
adr_f = &f(x); /*gresit, &f(x) este adresa rezultatului funciei (adresa unui int)*/
Declararea variabilelor de tip pointer la funcie
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
4/23
Folosirea variabilelor de tip pointer la funcie
long factorial (int k); /*prototipul funciei factorial*/
long (*adr_f) (int); /*pointer la funcie*/
long fact;
intn=3;
adr_f= factorial; /*atribuire de valoare variabilei pointer la funcie*/
............
fact = (*adr_f) (n); /*Apelarea funciei factorial cu ajutorul pointerului la
funcie;Are efect similar cu: fact = factorial(n);
*/
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
5/23
OBSERVATIE:
Trebuie avuta in vedere concordana dintre tipul funciei i tipulvariabilei pointer la funcie
La compilare - concordana se refer doar la tipul rezultatului
funciei
DAR
n faza de execuie - dac numrul i tipul parametrilor precizaipentru funcie i pentru variabila pointer nu sunt identice, vor fisemnalate erori
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
6/23
Utilitatea variabilelor de tip pointer la funcie
Variabilele de tip pointer la funcie permit scrierea de funcii
i programe cu grad mare de generalitate.
Exemple:
Tablouri de pointeri la functii ce permit apelareaindirecta a acestora
Functii polimorfice
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
7/23
Tablouri de pointeri la functii ce permit apelarea indirecta a acestora
#include #include
void main (void){ int i, nr;
double x;double (* tablou [6] ) (double)= {sin, cos, tan, exp, log, log10};nr = sizeof(tablou)/sizeof(tablou[0]);for (x=0.01; x
-
7/25/2019 M_Cap7_3
8/23
Functii polimorfice exemplul nr. 1
void ord_cresc (int t[ ], int nr)
{ int i, aux, ordonat=0;while ( ! ordonat )
{ ordonat=1;for (i=0; i t[i+1]){aux = t[i];
t[i] = t[i+1];t[i+1] = aux;
ordonat=0;}
}}
Funcie de ordonare cresctoare: Funcie de ordonare descresctoare:
void ord_descresc (int t[ ], int nr)
{ int i, aux, ordonat=0;while ( ! ordonat )
{ ordonat=1;
for (i=0; i
-
7/25/2019 M_Cap7_3
9/23
/*funcia de comparare a dou valori pentru ordonare cresctoare*/int comp_cresc (int a, int b)
{ return a>b;}
/*funcia de comparare a dou valori pentru ordonare descresctoare*/
int comp_descresc (int a, int b){ return a
-
7/25/2019 M_Cap7_3
10/23
/*funcia main() cu utilizarea funciei de ordonare*/void main(void){ int a[100], n,k;
/* ..... instruciunile pentru citirea de la tastatur a valorilor:- n numrul de elemente din tabloul a;- a[i], cu i=0, 1, ... n-1 */
printf(Valorile iniiale sunt:\n);/* ..... instruciunile pentru afiarea valorilor a[i], cu i=0, 1, ... n-1*/
ordonare(a, n, comp_cresc);printf(Valorile ordonate cresctor sunt:\n);/* ..... instruciunile pentru afiarea valorilor a[i], cu i=0, 1, ... nr-1*/
ordonare(a, n, comp_descresc);printf(Valorile ordonate descresctor sunt:\n);/* ..... instruciunile pentru afiarea valorilor a[i], cu i=0, 1, ... n-1*/}
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
11/23
Functii polimorfice exemplul nr. 2
numarul de elemente din tabloutabloul ce trebuie sortat dimensiunea in numar de octeti a unui element
void qsort (void* tab, size_t n, size_t dim, int (*compar)(const void*, const void*));
1 2pointer la o functie ce are ca
parametri adresele a 2 elemente din tablou (1 si 2) si trebuie sa returneze unrezultat de tip intcu valoarea:
2
Functie din biblioteca descrisa de stdlib.h
Implementeaza metoda QUICKSORT pentru sortarea (ordonarea) crescatoare a valorilor
unui tablouPoate fi utilizata indiferent de tipul elementelor tabloului si de semnificatia notiunii derelatie de ordine careia i se supun
Programatorul trebuie sa expliciteze intr-o functie scrisa de el insusi relatia de ordinedorita, respectand restrictiile impuse de prototipul functiei
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
12/23
numarul de elemente din tabloutabloul ce trebuie sortat dimensiunea in numar de octeti a unui element
void qsort(void* tab, size_t n, size_t dim, int(*compar)(const void*, const void*));
1 2pointer la o functie ce are ca
parametri adreselea 2 elemente din tablou (1si 2) si trebuie sa returneze un rezultatde tip intcu valoarea:
2
De exemplu
pentru sortarea crescatoare a unui tablou de valori intregi pozitive, functia de compa-rare a valorilor ar putea fi scrisa astfel:
int compar_numere (const void* a, const void* b)
{ return *((int*)a) - *((int*)b);
}
Sortarea unui tablou int t[100] cu nr elemente poate fi apoi realizata astfel:
qsort(t, nr, sizeof(int), compar_numere);
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
13/23
Funcii cu rezultat de tip pointer
NUscriei astfel de funcii:
int * exemplu1 (void) int * exemplu2 (int k){ int b; /* variabil local */ { .......
........ return &k; /* k este parametru !!! */return &b;
} }
Principala utilitate a funciilor ce dau rezultat de tippointer este alocarea de spaiu n memorie pentru aa-
numitele variabile dinamice ale programelor scrise nlimbaj C
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
14/23
Alocarea dinamic a memoriei
Variabile statice
alocare la momentul compilrii (tip asociat) compilatorul calculeaz i aloc spaiul de memorie necesar
Variabile dinamice
alocare n timpul execuiei programului (alocare dinamic) zona de memorie: memorieheap programatorul specific numrul de octei i cere explicit
programului si aloce
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
15/23
Operatorul sizeof( ) - Reamintire
sizeof(float) inseamna 4 (octei), adic nr. de octei necesari pt.reprezentarea intern a tipuluifloat
float x; ???
sizeof (x)
float a[10]; ???sizeof(a)
sizeof (a[5]+7) ???
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
16/23
Funcii de bibliotec destinate alocrii dinamice de
memorie, descrise n stdlib.h
tip predefinit, similar int, descris n stddef.h, stdlib.h, alloc.h,mem.h, stdio.h, string.h
void * malloc (size_t dim);dim= numrul de octei alocaiunul dup altul
(continuu) n memorierezultatul este un pointer ctre nceputul zonei alocatesau NULLn caz de eec
(alocarea nu s-a putut face corect; de exemplu, nu exist suficient spaiu liber)
void * calloc (size_t n, size_t dim);dim= numrul de octei ai fiecrui element
n=numrul de elemente
ce vor fi memorate unul dup altul
idem malloc()
Obs.: in plus fata de malloc(), iniializeazcu valoarea 0octeii alocai
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
17/23
void * realloc (void * bloc, size_t dim);
bloc= adresa blocului de memoriealocat anterior printr-un apel malloc(),
calloc()sau realloc()
Redimensioneazblocul de memorie alocat anterior (n plus sau minus), ladimoctei (dimva fi noua dimensiune a zonei de memorie alocate n urmaapelului funciei)
Rezultatul = adresa de nceput a zonei de memorie alocate alocate (care nucoincide neaprat cu cea veche) sau NULL, dac alocarea nu a putut fi fcut
void free (void * bloc);
Elibereaz zona de memorieindicat de pointerul bloc.
Se aplic numai pentru zone de memorie ce au fost alocate prin folosireafunciilor malloc(), calloc()sau realloc()
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
18/23
RECOMANDARE: este bine s se testeze valoarea pointerului returnat (aflm dacalocarea s-a fcut corect). Altfel, pot aprea erori de execuie a cror cauz este greude depistat!
#include#include /* pentru funciile de alocare dinamic */int * p;p = (int*) calloc (1000, sizeof(int));if( p == NULL){ printf(alocare euat!);
exit(1);}
int * q; /* variabil ajuttoare */..........for (q=p; q < p+1000; q++)
*q = 1;
..........
??? Rolul variabilei ajuttoare ???
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
19/23
Problema rezolvata
Scriei un program n care:
- s citii de la tastatur dimensiunile l (numr de linii) i c (numr decoloane) pentru 2 matrice;
- s alocai dinamic spaiu de memorie pentru elementele celor 2 matrice
- s citii de la tastatur valorile matricelor
- s memorai valorile citite n spaiul alocat anterior- s calculai i s afiai pe ecran valorile matricei sum a celor 2 matrice
void Testare(int * p);void CitesteMatrice(int * a, int n);
void AfiseazaMatrice(int * a, int m, int n);void SumaMatrice(int * a, int * b, int * c, int n);
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
20/23
#include #include void Testare(int * p);
void CitesteMatrice(int * a, int n);void AfiseazaMatrice(int * a, int m, int n);
void SumaMatrice(int * a, int * b, int * c, int n);
void main (void){ int l, c, *pa, *pb, *pc, dim;printf("Cate linii? ");scanf("%d", &l);printf("Cate coloane? ");scanf("%d", &c);
dim=l*c*sizeof(int);pa=(int*)malloc(dim);
Testare(pa);pb=(int*)malloc(dim);Testare(pb);pc=(int*)malloc(dim);Testare(pc);printf("Tastati valorile primei matrice:");CitesteMatrice(pa,l*c);printf("Tastati valorile celei de-a doua matrice:");
CitesteMatrice(pb,l*c);SumaMatrice(pa,pb,pc,l*c);
AfiseazaMatrice(pc,l,c);free(pa);free(pb);free(pc);
}
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
21/23
void Testare(int * p){ if (p==NULL)
{printf("Alocare dinamica de memorie esuata\n");exit(1);}
}
void CitesteMatrice(int * a, int n){ int* sfarsit=a+n;
while (a
-
7/25/2019 M_Cap7_3
22/23
OBSERVATIE FOARTE UTILA
Alocarea spatiului in heap face posibila folosirea valorilor
depuse in zona de catre orice functie a programului.
La limita, zona poate fi alocata de o functie, folosita de
alta si eliberata de alta.
Important este ca functiile respective sa cunoasca adresa
zonei din heap cu care se lucreaza.
ATENTIE !!! Pot sa apara erori greu de depistat in cazulfolosirii necorespunzatoare a acestei zone, la fel ca si in
cazul variabilelor globale
Prof. dr. ing. Daniela Saru Curs - Programarea Calculatoarelor Anul I A Facultatea Automatica si Calculatoare - UPB
-
7/25/2019 M_Cap7_3
23/23
#include
#include void Testare(int * p);void CitesteMatrice(int * a, int n);
void AfiseazaMatrice(int * a, int m, int n);void ModificaMatrice(int * a, int n);
void main (void)
{ int l, c, *pa, dim;printf("Cate linii? "); scanf("%d", &l);
printf("Cate coloane? "); scanf("%d", &c);dim=l*c*sizeof(int);pa=(int*)malloc(dim);
Testare(pa);printf("Tastati valorile matricei:");
CitesteMatrice(pa,l*c);ModificaMatrice(pa,l*c);printf("Valorile matricei modificate:\n");
AfiseazaMatrice(pa,l,c);free(pa);
}
void Testare(int * p)
{ if (p==NULL){printf("Alocare din. de memorie esuata\n");exit(1);}
}
void CitesteMatrice(int * a, int n){ int* sfarsit=a+n;
while (a