M_Cap7_3

download M_Cap7_3

of 23

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