Laborator 12: Recursivitate, Pointeri la funcții. Funcţii cu număr variabil de parametri

Obiectivele laboratorului

Teorie:

Exerciții:

  1. Analizați împreună cu asistentul exemplul funcției listf din secțiunea de teorie de pe ocw.

    a. Rulați programul dat în exemplu.

    b. Modificați programul anterior a.i. să apelați funcția listf pentru a afișa valorile corespunzătoare pentru următoarele funcții matematice:

      i. sin

      ii. cos

      iii. exp

      iv. log10

      v. sqrt

      vi. fabs

ATENȚIE! Se dorește implementarea unei soluții modularizate, de aceea obligatoriu se va defini un vector de pointeri la funcții. Orice altă soluție nu se va puncta.

  1. Realizați implementarea funcției cu număr variabil de parametri numită gcd, care să permită aflarea celui mai mare divizor comun (gcd) al parametrilor dați (cel puțin două elemente care sunt numere naturale). Puteți presupune că lista se termină cu un număr negativ.

Hint: Exemplu 8 din teoria indicată de pe ocw.

Exemplu:

printf("%d\n", gcd(5, 10, -1));
// va printa 5 pentru ca gcd(5, 10) = 5

printf("%d\n", gcd(5, 10, 2, 100, -1));
// va printa 1 pentru ca gcd(5, 10, 2, 100) = 1

printf("%d\n", gcd(500, 10, 25, 75, -1));
// va printa 5 pentru ca gcd(500, 10, 25, 75) = 5

printf("%d\n", gcd(1024, 48, 64, 256, 2048, -1));
// va printa 16 pentru ca gcd(1024, 48, 64, 256, 2048) = 16
  1. Se dorește implementarea unei funcții polimorfice (generice) de sortare (o funcție care va putea sorta crescător un vector de caractere / întregi / șiruri de caractere / structuri etc). Semnătura funcției este:
// definim tipul de pointer la funcție care va compara 2 elemente (tip necunoscut) si va returna
// un număr care indică relația dintre cele 2 elemente
// ex. să presupunem că cei 2 parametri se numesc first și second
// funcția va returna
// -x, dacă first  < second ("first - second  < 0")
//  0, dacă first == second ("first - second == 0")
// +x, dacă first  > second ("first - second  > 0")
// (unde -x/+x semnifică un număr strict negativ/pozitiv)
typedef int (*cmp_t)(const void*, const void*);

// funcția sortează vectorul v descris astfel:
// - nu se cunoaște exact tipul unui element (void *)
// - are num elemente
// - fiecare element are size byte
// - pentru compararea a 2 elemente, se da o funcție cmp de comparare
void sort(void* v, size_t num, size_t size, cmp_t cmp);

Pentru validarea soluției, se va demonstra că funcția sortează corect un vector de caractere (char), un vector de numere reale (double) și un vector de șiruri de caractere (char *).

Exemplu de utilizare pentru un vector cu elemente de tip int:

int cmp_int(const void* first, const void* second) {
    int f = *(int *) first;
    int s = *(int *) first;

    if (f < s) {
        return -1; // f < s
    }
    if (f > s) {
        return +1; // f > s
    }
    return 0;       // f == s
}
// succesiunea de if-uri se putea înlocui cu "return f - s;"

int num_v, *v; // presupunem existența unui vector v cu n elemente întregi
sort(v, n, sizeof(int), cmp_int);

// printează v pentru verificare

[BONUS] 4. Realizați o pereche de funcții cu număr variabil de parametri, numită bprintf() / bscanf() care să permită scrierea / citirea cu format a unui număr de variabile dintr-un fișier binar.

Semnăturile funcțiilor sunt:

int bprintf(FILE*, char *format, ...);
int bscanf(FILE*, char *format, ...);

Funcțiile vor folosi în implementare fwrite() / fread().

Pentru simplitate presupunem că există doar următorii specificatori:

Pentru simplitate se va considera că după caracterul '%' urmează mereu unul din cei 3 specificatori (c/d/s).

Funcționare:

Mod de implementare:

[BONUS] 5. Se cere implementarea unei funcții polimorfice de căutare binară. Aceasta va urma modelul funcției de sortare de la exercițiul 3.

Pentru o aprofundare mai bună a conceptelor prezentate în laborator, vă recomandăm să parcurgeți materialele din arhiva demo_func_ptr.zip de pe Moodle.