Documente Academic
Documente Profesional
Documente Cultură
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / eslides rev. 2021 108
Particularităţi ale limbajului C
Reamintire:
Similar…
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 108 bis
Declararea variabilelor de tip pointer la funcţie
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 109
Folosirea variabilelor de tip pointer la funcţie
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 109
OBSERVATIE:
DAR…
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 110
Utilitatea variabilelor de tip pointer la funcţie
Exemple:
Functii polimorfice
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 110
Tablouri de pointeri la functii ce permit apelarea indirecta a acestora
#include <stdio.h> Tabl_Point_Fct.c
#include <math.h>
int 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<1.01; x+=0.01)
{ for (i=0; i<nr; i++)
printf(“%lf “, (* tablou[i])(x));
printf(“\n”);
}
return 0;
}
Obs:
tablou[i] este element al tabloului, deci este pointer la functie de tipul specificat;
(*tablou[i]) este chiar functia asociata;
(*tablou[i])(x) are acelasi efect ca apelarea functiei asociate.
De exemplu, (*tablou[0])(x) produce aceeasi valoare ca sin(x)
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 111
Functii polimorfice – exemplul nr. 1
Funcţie de ordonare crescătoare: Funcţie de ordonare descrescătoare:
void ord_cresc (int t[ ], int nr) void ord_descresc (int t[ ], int nr)
{ int i, aux, ordonat=0; { int i, aux, ordonat=0;
while ( ! ordonat ) while ( ! ordonat )
{ ordonat=1; { ordonat=1;
for (i=0; i<nr-1; i++) for (i=0; i<nr-1; i++)
if (t[i] > t[i+1]) if (t[i] < t[i+1])
{aux = t[i]; {aux = t[i];
t[i] = t[i+1]; t[i] = t[i+1];
t[i+1] = aux; t[i+1] = aux;
ordonat=0; ordonat=0;
} }
} }
} }
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 111
/*funcţia de comparare a două valori pentru ordonare crescătoare*/
int comp_cresc (int a, int b)
{ return a>b;
}
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 112
/*funcţia main() cu utilizarea funcţiei de ordonare*/
int main (void)
{ int a[100], n,k;
ordonare(a, n, comp_cresc);
printf(”Valorile ordonate crescător sunt:\n”);
/* ..... instrucţiunile pentru afişarea valorilor a[i], cu i=0, 1, ... nr-1*/
ordonare(a, n, comp_descresc);
printf(”Valorile ordonate descrescător sunt:\n”);
/* ..... instrucţiunile pentru afişarea valorilor a[i], cu i=0, 1, ... n-1*/
}
Fct_Polimorf.c
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 112
Functii polimorfice – exemplul nr. 2
numarul de elemente din tablou
tabloul 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” „2”
pointer la o functie ce are ca
parametri adresele a 2 elemente din tablou („1” si „2”) si trebuie sa returneze un
rezultat de tip int cu valoarea:
<0 dacă „1 < 2”
0 dacă „1==2”
>0 dacă „1 > 2”
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 113
De exemplu…
numarul de elemente din tablou
tabloul 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” „2”
pointer la o functie ce are ca
parametri adresele a 2 elemente din tablou („1” si „2”) si trebuie sa returneze un rezultat
de tip int cu valoarea:
<0 dacă „1 < 2”
0 dacă „1==2”
>0 dacă „1 > 2”
… 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);
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 113
Funcţii cu rezultat de tip pointer
NU scrieţi astfel de funcţii:
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 114
Alocarea dinamică a memoriei
Variabile statice
– alocare la momentul compilării (tip asociat)
– compilatorul calculează şi alocă spaţiul de memorie necesar
Variabile dinamice
– alocare în timpul execuţiei programului (alocare dinamică)
– zona de memorie: memorie heap
– programatorul specifică numărul de octeţi şi cere explicit
programului să îi aloce
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 114
Operatorul sizeof( ) - Reamintire
float x; ???
sizeof (x)
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 115
Funcţii de bibliotecă destinate alocării 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 = numărul de octeţi alocaţi unul după altul
(continuu) în memorie
rezultatul este un pointer către începutul zonei alocate sau NULL în caz de eşec
(alocarea nu s-a putut face corect; de exemplu, nu există suficient spaţiu liber)
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 115
void * realloc (void * bloc, size_t dim);
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 116
RECOMANDARE: este bine să se testeze valoarea pointerului returnat (aflăm dacă
alocarea s-a făcut corect). Altfel, pot apărea erori de execuţie a căror cauză este greu
de depistat!
#include<stdio.h>
#include<stdlib.h> /* pentru funcţiile de alocare dinamică */
………
int * p;
p = (int*) calloc (1000, sizeof(int));
if( p == NULL)
{ printf(“alocare eşuată!”);
exit(1);
}
………
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 116
Problema rezolvata
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 117
#include <stdio.h>
#include <stdlib.h>
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);
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 117
void Testare(int * p)
{ if (p==NULL)
{printf("Alocare dinamica de memorie esuata\n");
exit(1);
}
}
*c++=*a++ + *b++;
}
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 118
OBSERVATIE FOARTE UTILA
Alocarea spatiului in heap face posibila folosirea valorilor
depuse in zona de catre orice functie a programului.
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 118
#include <stdio.h>
#include <stdlib.h>
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<sfarsit)
scanf("%d", a++);
}
void ModificaMatrice(int * a, int n)
{ int* sfarsit=a+n;
while (a<sfarsit)
{ * a = 55;
a += 2;
}
}
void AfiseazaMatrice(int * a, int m, int n)
{ int * inceput=a, *sfarsit=a+m*n; heap.c
while (a<sfarsit)
{printf(((a-inceput)%n==n-1) ? "%6d\n" : "%6d", *a);
a++;
}
}
Daniela Saru - "Programarea calculatoarelor. Note de curs” – Ed. Printech, 2011 / slides rev. 2021 119