4 - PUNTATORI
versione 13/01/2013
 
ESERCIZIO
 
Costruire un programma che richiede un numero N e genera N valori interi casuali compresi tra 1 e 100. Al termina stampa l'elenco di quelli pari. L'area di memoria deve essere gestita dinamicamente mediante l'uso di puntatori a integer.

 
SOLUZIONE:
OSSERVAZIONI:

void *malloc(size_t size); => Alloca un blocco di size bytes di memoria e ne restituisce l'indirizzo di inizio di tale area. In caso di errore restituisce NULL. size_t corrisponde ad un unsigned int. malloc (deriva da memory allocation) è una funzione delle librerie standard nei linguaggi di programmazione C e C++ per l'allocazione dinamica della memoria. In caso di successo, malloc restituisce un puntatore void (void *) che indica che si tratta di un puntatore ad una regione di dati di tipo sconosciuto. Un cast esplicito è a volte presente ma non è necessario nello standard C. La sua omissione causa tuttavia una incompatibilità con il C++, che invece lo richiede. Richiede <stdlib.h>.

void free ( void * ptr ); => Dealloca il blocco di memoria, puntato dal parametro ptr, precedentemente allocato con i comandi malloc, calloc o realloc. Se ptr non punta ad una zona di memoria allocata dinamicamente il suo comportamento è indefinito. Se ptr è NULL allora free non fa nulla. Si ricordi che free non cambia il valore di ptr che quindi continua a puntare alla stessa zona che però non è più valida. Richiede <stdlib.h>.
Un errore abbastanza frequente (specie se si ha a che fare con vettori di puntatori) è quello di chiamare free più di una volta sullo stesso puntatore; per evitare questo problema una soluzione di ripiego è quella di assegnare sempre a null ogni puntatore liberato con free, dato che, quando il parametro è un puntatore nullo, free non esegue nessuna operazione. Richiede <stdlib.h>.

void exit ( int status ); => Termina il processo correttamente ed esegue le regolari operazioni di chiusura per terminare il programma. Lo stato zero o EXIT_SUCCESS, indica successo mentre lo stato EXIT_FAILURE indica una terminazione non corretta.

/**************************************************************************
 * Nome: lab1-pari.c                                                      *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h>  // richiesta da malloc() e system()
/*
 * Nome: main
 * Scopo: Visualizza i numeri pari contenuti in un vettore allocato dinamicamente
 * Input: --
 * Output: 0 se il programma termina correttamente
 */
int main() 
{
    int n, i, *v;  
    // INPUT - INIZIALIZZAZIONE
    printf("Digita quanti valori, da 1 a 100, vuoi generare: ");
    scanf("%d", &n);
    // Allocazione di memoria dinamica con Casting
    v = (int *)malloc(n * sizeof(int));  
    if (v == NULL) exit(0);
    for (i = 0 ; i < n ; i++) 
        v[i] = rand() % 100 + 1;
    // ALGORITMO + OUTPUT
    printf("\nNumeri generati:\n");
    for (i = 0 ; i < n ; i++) 
       printf("%4d", v[i]);
    printf("\nNumeri pari:\n");
    for (i = 0; i < n; i++) 
        if (v[i] % 2 == 0) 
           printf("%4d", v[i]);
    printf("\n");
    free(v);  /* Liberiamo lo spazio di memoria allocato. */ 
    v = NULL; /* Il puntatore non può essere più usato fino 
                 ad un riassegnamento effettuato con malloc. */


    system("pause");
    return 0;
}

ESERCIZIO
 
Costruire un programma che richiede una sequenza di punti (conclusa con la coppia 0 0) e mostra quelli che appartengono al primo quadrante.

 
SOLUZIONE:
OSSERVAZIONI:

void * realloc ( void * ptr, size_t size ); => La funzione realloc() prevede due argomenti: il primo ptr è un indirizzo di memoria, il secondo size specifica la nuova dimensione del blocco. Il tipo restituito è un tipo puntatore a void al quale viene generalmente applicata un'operazione di casting. Richiede <stdlib.h>.
Viene utilizzata quando si vuol far crescere o ridurre un'area di memoria senza perdere i valori ivi registrati. Realloc() restituisce un puntatore ad una zona di memoria con la dimensione specificata. Tale zona contiene gli stessi dati della vecchia regione indirizzata da ptr (troncata alla fine nel caso la nuova dimensione sia minore di quella precedente). Se realloc non è in grado di ridimensionare utilizzando ancora lo spazio di memoria originale, allocherà una nuova area con le nuove dimensioni, copierà i dati richiesti, e libererà il vecchio puntatore. La funzione realloc() è equivalente alla sequente sequenza:
/**************************************************************************
 * Nome: lab2-punti.c                                                     *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h>  // richiesta da realloc() e system()
/*
 * Nome: main
 * Scopo: Visualizza i punti del piano cartesiano contenuti in un vettore 
 *        allocato dinamicamente e nel primo quadrante del piano cartesiano
 * Input: --
 * Output: 0 se il programma termina correttamente
 */
// Dichiaro il tipo predefinito x la struttura e per il suo puntatore.
// Per il puntatore potevo scrivere anche: 
// typedef tPunto *tPuntoPtr;
typedef struct 
{
  int x, y;        
} tPunto, *tPuntoPtr; 
int main() 
{
    int n = 0, i;  
    //tPuntoPtr p = NULL;
    // Oppure
    tPunto *p = NULL;
    // INPUT
    printf("Digita le coordinate separandole con lo spazio (0 0 per finire)\n");
    do 
    {
        // Man mano leggo aggiungo dinamicamente la memoria necessaria
        p = (tPunto *)realloc(p, (n + 1) * sizeof(tPunto));
        // potevo scrivere anche:
        // p = (tPuntoPtr)realloc(p, (n + 1) * sizeof(tPunto));
        if (p == NULL) 
           exit(0);
        printf("%d punto: ",n+1);
        // potevo scrivere anche:
        // scanf("%d %d", &(p+n)->x, &(p+n)->y);
        scanf("%d %d", &p[n].x, &p[n].y);
        n++;  
    }
    while(p[n-1].x != 0 ||  p[n-1].y != 0);
    // ALGORITMO - OUTPUT
    printf("I punti nel 1^ quadrante sono:\n");
    for (i = 0; i < n; i++) 
        if (p[i].x > 0 && p[i].y > 0) 
            printf("(%d,%d)\n", p[i].x, p[i].y);

    system("pause");
    return 0;
}

ESERCIZIO
 
Costruire un programma che legge il nome e tempo di una sequenza di maratoneti e al termine li stampa a video. La sequenza termina quando si digita 0:0:0
 
SOLUZIONE:
OSSERVAZIONI:

1) Per le prove usa il seguente elenco di parole (cut & paste).

1:10:23
Verdi
0:59:2
Gialli
0:59:2
Bianchi
1:1:21
Barbagrossa
1:10:2
Rossi
0:0:0

/**************************************************************************
 * Nome: lab3-maratoneta.c                                                *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h>  // richiesta da realloc() e system()
typedef struct 
{
  int h, m, s;      
} tTempo;

typedef struct 
{
   char nome[20];
   tTempo t;     
} tMaratoneta, *tMaratonetaPtr;

/*
 * Nome: inizializzaMaratoneti
 * Scopo: Inizializza un vettore di maratoneti con dati acquisiti da tastiera
 *        Non ho limite relativamente al numero di atleti da registrare
 * Input: int *n: contiene il nr di atleti letti
 * Output: restituisce il puntatore al vettore di maratoneti 
 *         allocato dinamicamente
 */
tMaratonetaPtr inizializzaMaratoneti(int *n) 
{
    tMaratonetaPtr p = NULL;
    bool bastaAtleti;
    printf("Digita i dati (0:0:0 per terminare):\n");
    printf("--------------------------------------------------\n");
    do 
    {
        p = (tMaratonetaPtr)realloc(p, (*n + 1) * sizeof(tMaratoneta));
        if (p == NULL) exit(0); // L'allocazione è fallita
        printf("Tempo (hh:mm:ss): ");
        scanf("%d:%d:%d", &p[*n].t.h, &p[*n].t.m, &p[*n].t.s);    
        bastaAtleti=( (p[*n].t.h==0) && (p[*n].t.m==0) && (p[*n].t.s==0) );
        if (!bastaAtleti)
        {
            printf("Nome: ");
            scanf("%s", p[*n].nome);
            *n = *n + 1;  
        }
        printf("\n");
    }
    while (!bastaAtleti);
    // while (p[*n-1].t.h != 0 || p[*n-1].t.m != 0 || p[*n-1].t.s != 0);
    printf("--------------------------------------------------\n");
    return p;
}

/*
 * Nome: visualizzaMaratoneti
 * Scopo: Visualizza un vettore di n maratoneti 
 * Input: Maratoneta v[]: un riferimento al vettore da visualizzare
 *        int n: la lunghezza del vettore
 * Output: -
 */
void visualizzaMaratoneti(tMaratoneta v[], int n) 
{
    int i;
    printf("Elenco atleti:\n");
    for (i = 0; i < n; i++) 
        printf("%-20s %02d:%02d:%02d\n", v[i].nome, v[i].t.h, v[i].t.m, v[i].t.s);
    printf("\n");
}

/*
 * Nome: main
 * Scopo: Inizializza e visualizza i dati contenuti in un vettore di maratoneti
 *        allocato dinamicamnte
 * Input: --
 * Output: 0 se il programma termina correttamente
 */
int main() 
{
    tMaratoneta *v = NULL;
    int n = 0;
    //INPUT
    v = inizializzaMaratoneti(&n);
    //OUTPUT
    visualizzaMaratoneti(v, n);
    
    system("pause");
    return 0;  
}

ESERCIZIO
 
Costruire un programma che legge il nome e tempo di una sequenza di maratoneti e al termine mostra quello che ha il tempo migliore. La sequenza termina quando si digita 0:0:0

 
SOLUZIONE:
OSSERVAZIONI:

1) Per le prove usa il seguente elenco di parole (cut & paste).

1:10:23
Verdi
0:59:1
Gialli
0:59:2
Bianchi
1:1:21
Barbagrossa
1:10:2
Rossi
0:0:0

2) Le strutture possono essere inizializzate in questo modo

tMaratoneta best = {"", {100, 60, 60}};  // singolo elemento
tMaratoneta v[]={
                   {"Verdi",       {1,10,23} },
                   {"Gialli",      {0,59,1}  },
                   {"Bianchi",     {0,59,2}  },
                   {"Barbagrossa", {1,1,21}  },
                   {"Rossi",       {1,10,2}  }
                }; // Array di strutture
oppure
tMaratoneta v[]={
                   "Verdi",       {1,10,23},
                   "Gialli",      {0,59,1},
                   "Bianchi",     {0,59,2},
                   "Barbagrossa", {1,1,21},
                   "Rossi",       {1,10,2}
                };
/**************************************************************************
 * Nome: lab4-maratonetaMigliore.c                                        *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h>  // richiesta da realloc() e system()
typedef struct 
{
  int h, m, s;      
} tTempo;

typedef struct 
{
   char nome[20];
   tTempo t;     
} tMaratoneta, *tMaratonetaPtr;

/*
 * Nome: inizializzaMaratoneti
 * Scopo: Inizializza un vettore di maratoneti con dati acquisiti da tastiera
 *        Non ho limite relativamente al numero di atleti da registrare
 * Input: int *n: contiene il nr di atleti letti
 * Output: restituisce il puntatore al vettore di maratoneti 
 *         allocato dinamicamente
 */
tMaratonetaPtr inizializzaMaratoneti(int *n) 
{
    tMaratonetaPtr p = NULL;
    bool bastaAtleti;
    printf("Digita i dati (0:0:0 per terminare):\n");
    printf("--------------------------------------------------\n");
    do 
    {
        p = (tMaratonetaPtr)realloc(p, (*n + 1) * sizeof(tMaratoneta));
        if (p == NULL) exit(0); // L'allocazione è fallita
        printf("Tempo (hh:mm:ss): ");
        scanf("%d:%d:%d", &p[*n].t.h, &p[*n].t.m, &p[*n].t.s);    
        bastaAtleti=( (p[*n].t.h==0) && (p[*n].t.m==0) && (p[*n].t.s==0) );
        if (!bastaAtleti)
        {
            printf("Nome: ");
            scanf("%s", p[*n].nome);
            *n = *n + 1;  
        }
        printf("\n");
    }
    while (!bastaAtleti);
    printf("--------------------------------------------------\n");
    return p;
}

/*
 * Nome: visualizzaMaratoneti
 * Scopo: Visualizza un vettore di n maratoneti 
 * Input: Maratoneta v[]: un riferimento al vettore da visualizzare
 *        int n: la lunghezza del vettore
 * Output: -
 */
void visualizzaMaratoneti(tMaratoneta v[], int n) 
{
    int i;
    printf("Elenco atleti:\n");
    for (i = 0; i < n; i++) 
        printf("%-20s %02d:%02d:%02d\n", v[i].nome, v[i].t.h, v[i].t.m, v[i].t.s);
    printf("\n");
}

/*
 * Nome: Minore
 * Scopo: Individuare se un tempo cronometrato e' inferiore ad un altro
 * Input: Tempo t1: primo tempo cronometrato
 *        Tempo t2: secondo tempo cronometrato
 * Output: 1 se il primo tempo e' inferiore al secondo e 0 altrimenti
 */
bool Minore(tTempo t1, tTempo t2) 
{
    if (t1.h < t2.h) 
        return true;
    else if (t1.h == t2.h) 
    {
        if (t1.m < t2.m) 
            return true;
        else if(t1.m == t2.m && t1.s < t2.s) 
            return true;     
    }
    // Se arrivo qui t1 non è minore di t2 
    return false;
}

/*
 * Nome: main
 * Scopo: Inizializza e visualizza i dati contenuti in un vettore di maratoneti
 *        allocato dinamicamnte ed infine visualizza il maratoneta con il tempo 
 *        inferiore
 * Input: --
 * Output: 0 se il programma termina correttamente
 */
int main() 
{
    int n = 0, i;
    // Inizializzo la variabile best
    tMaratoneta best = {"", {100, 60, 60}};
    //INPUT
    tMaratoneta *v = inizializzaMaratoneti(&n);
    /* Potevo inizializzare l'array in questo modo:
    tMaratoneta v[]={
                    {"Verdi",       {1,10,23} },    
                    {"Gialli",      {0,59,1}  },    
                    {"Bianchi",     {0,59,2}  },    
                    {"Barbagrossa", {1,1,21}  },    
                    {"Rossi",       {1,10,2}  }   
                  };
    */
    // ALGORITMO
    for (i = 0; i < n ; i++) 
        if (Minore(v[i].t, best.t)) 
            best = v[i];
    //OUTPUT
    visualizzaMaratoneti(v, n);
    printf("Miglior maratoneta:\n%-20s %02d:%02d:%02d\n", best.nome, best.t.h, best.t.m, best.t.s);
  
    system("pause");
    return 0;  
}

ESERCIZIO
 
Costruire un programma che legge il nome e il tempo realizzato da ogni atleta di una sequenza di maratoneti. Al termine mostra la classifica di arrivo partendo dall'atleta migliore. La sequenza termina quando si digita 0:0:0

 
SOLUZIONE:
OSSERVAZIONI:

1) In C++ (come in C) esistono i puntatori a funzione! Questi servono quando il programma deve scegliere quale funzione chiamare fra diverse possibili, e la scelta non é definita a priori ma dipende dai dati del programma stesso. Per approfondimenti clicca qui.

2) L'algoritmo di ordinamento utilizzato è l'Insertion Sort 3) Per le prove usa il seguente elenco di parole (cut & paste).

1:10:23
Verdi
0:59:1
Gialli
0:59:2
Bianchi
1:1:21
Barbagrossa
1:10:2
Rossi
0:0:0

/**************************************************************************
 * Nome: casa1-maratonetiOrdinati.c                                       *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // richiesto da system()
typedef struct 
{
  int h, m, s;      
} tTempo;
typedef struct 
{
   char nome[20];
   tTempo t;     
} tMaratoneta, *tMaratonetaPtr;
/*
 * Nome: inizializzaMaratoneti
 * Scopo: Inizializza un vettore di maratoneti con dati acquisiti da tastiera
 *        Non ho limite relativamente al numero di atleti da registrare
 * Input: int *n: contiene il nr di atleti letti
 * Output: restituisce il puntatore al vettore di maratoneti 
 *         allocato dinamicamente
 */
tMaratonetaPtr inizializzaMaratoneti(int *n) 
{
    tMaratonetaPtr p = NULL;
    bool bastaAtleti;
    printf("Digita i dati (0:0:0 per terminare):\n");
    printf("--------------------------------------------------\n");
    do 
    {
        p = (tMaratonetaPtr)realloc(p, (*n + 1) * sizeof(tMaratoneta));
        if (p == NULL) exit(0); // L'allocazione è fallita
        printf("Tempo (hh:mm:ss): ");
        scanf("%d:%d:%d", &p[*n].t.h, &p[*n].t.m, &p[*n].t.s);    
        bastaAtleti=( (p[*n].t.h==0) && (p[*n].t.m==0) && (p[*n].t.s==0) );
        if (!bastaAtleti)
        {
            printf("Nome: ");
            scanf("%s", p[*n].nome);
            *n = *n + 1;  
        }
        printf("\n");
    }
    while (!bastaAtleti);
    printf("--------------------------------------------------\n");
    return p;
}
/*
 * Nome: visualizzaMaratoneti
 * Scopo: Visualizza un vettore di n maratoneti 
 * Input: Maratoneta v[]: un riferimento al vettore da visualizzare
 *        int n: la lunghezza del vettore
 * Output: -
 */
void visualizzaMaratoneti(tMaratoneta v[], int n) 
{
    int i;
    printf("Elenco atleti:\n");
    for (i = 0; i < n; i++) 
        printf("%-20s %02d:%02d:%02d\n", v[i].nome, v[i].t.h, v[i].t.m, v[i].t.s);
    printf("\n");
}
/*
 * Nome: Minore
 * Scopo: Individuare se un tempo cronometrato e' inferiore ad un altro
 * Input: Tempo t1: primo tempo cronometrato
 *        Tempo t2: secondo tempo cronometrato
 * Output: 1 se il primo tempo e' inferiore al secondo e 0 altrimenti
 */
bool Minore(tTempo t1, tTempo t2) 
{
    if (t1.h < t2.h) 
        return true;
    else if (t1.h == t2.h) 
    {
        if (t1.m < t2.m) 
            return true;
        else if(t1.m == t2.m && t1.s < t2.s) 
            return true;     
    }
    // Se arrivo qui t1 non è minore di t2 
    return false;
}

/*
 * Nome: ordina
 * Scopo: Ordina i maratoneti in un database
 * Input: Maratoneta v[]: il database di maratoneti
 *        int n: il numero di maratoneti contenuti nel database v
 * Output: -
 */
void ordina(tMaratoneta v[], int n, bool (*confronta)(tTempo, tTempo)) 
{
int i, j;
tMaratoneta x;

    for (i = 1; i < n; i++) 
    {
        x = v[i];
        for (j = i - 1; j >= 0 && (*confronta)(x.t, v[j].t) > 0; j--)
            v[j+1] = v[j];
        v[j+1] = x;
    }
}

/*
 * Nome: main
 * Scopo: Inizializza e visualizza i dati contenuti in un vettore di maratoneti
 *        allocato dinamicamnte ed infine ordina la sequenza di maratoneti
 * Input: --
 * Output: 0 se il programma termina correttamente
 */
int main() 
{
    tMaratoneta *v = NULL;
    int n = 0;
    //INPUT
    v = inizializzaMaratoneti(&n);
    // ALGORITMO
    ordina(v, n, Minore);
    //OUTPUT
    visualizzaMaratoneti(v, n);
  
    system("pause");
    return 0;  
}

ESERCIZIO
 
Costruire un programma che legge il nome e il tempo realizzato da ogni atleta di una sequenza di maratoneti. Al termine mostra la classifica di arrivo in ordine crescente o decrescente a seconda della scelta dell'utente. La sequenza termina quando si digita 0:0:0

 
SOLUZIONE:
OSSERVAZIONI:

1) Per approfondimenti relativamente agli array di puntatori a funzione clicca qui.

2) Per approfondimenti relativamente al passaggio di puntatori a funzioni come argomenti di una funzione clicca qui.

3) L'algoritmo di ordinamento utilizzato è l'Insertion Sort

4) Per le prove usa il seguente elenco di parole (cut & paste).

1:10:23
Verdi
0:59:1
Gialli
0:59:2
Bianchi
1:1:21
Barbagrossa
1:10:2
Rossi
0:0:0

/**************************************************************************
 * Nome: casa2-maratonetiOrdinati.c                                       *
 * Autore: Alessandro Saetti                                              *
 * Data: 6/4/10                                                           *
 **************************************************************************/
#include <stdio.h>
#include <stdlib.h> // richiesto da system() e realloc()
typedef struct 
{
  int h, m, s;      
} tTempo;
typedef struct 
{
   char nome[20];
   tTempo t;     
} tMaratoneta, *tMaratonetaPtr;
/*
 * Nome: inizializzaMaratoneti
 * Scopo: Inizializza un vettore di maratoneti con dati acquisiti da tastiera
 *        Non ho limite relativamente al numero di atleti da registrare
 * Input: int *n: contiene il nr di atleti letti
 * Output: restituisce il puntatore al vettore di maratoneti 
 *         allocato dinamicamente
 */
tMaratonetaPtr inizializzaMaratoneti(int *n) 
{
    tMaratonetaPtr p = NULL;
    bool bastaAtleti;
    printf("Digita i dati (0:0:0 per terminare):\n");
    printf("--------------------------------------------------\n");
    do 
    {
        p = (tMaratonetaPtr)realloc(p, (*n + 1) * sizeof(tMaratoneta));
        if (p == NULL) exit(0); // L'allocazione è fallita
        printf("Tempo (hh:mm:ss): ");
        scanf("%d:%d:%d", &p[*n].t.h, &p[*n].t.m, &p[*n].t.s);    
        bastaAtleti=( (p[*n].t.h==0) && (p[*n].t.m==0) && (p[*n].t.s==0) );
        if (!bastaAtleti)
        {
            printf("Nome: ");
            scanf("%s", p[*n].nome);
            *n = *n + 1;  
        }
        printf("\n");
    }
    while (!bastaAtleti);
    printf("--------------------------------------------------\n");
    return p;
}
/*
 * Nome: visualizzaMaratoneti
 * Scopo: Visualizza un vettore di n maratoneti 
 * Input: Maratoneta v[]: un riferimento al vettore da visualizzare
 *        int n: la lunghezza del vettore
 * Output: -
 */
void visualizzaMaratoneti(tMaratoneta v[], int n) 
{
    int i;
    printf("Elenco atleti:\n");
    for (i = 0; i < n; i++) 
        printf("%-20s %02d:%02d:%02d\n", v[i].nome, v[i].t.h, v[i].t.m, v[i].t.s);
    printf("\n");
}
/*
 * Nome: Minore
 * Scopo: Individuare se un tempo cronometrato e' inferiore ad un altro
 * Input: Tempo t1: primo tempo cronometrato
 *        Tempo t2: secondo tempo cronometrato
 * Output: 1 se il primo tempo e' inferiore al secondo e 0 altrimenti
 */
bool Minore(tTempo t1, tTempo t2) 
{
    if (t1.h < t2.h) 
        return true;
    else if (t1.h == t2.h) 
    {
        if (t1.m < t2.m) 
            return true;
        else if(t1.m == t2.m && t1.s < t2.s) 
            return true;     
    }
    // Se arrivo qui t1 non è minore di t2 
    return false;
}

/*
 * Nome: maggiore
 * Scopo: Individuare se un tempo cronometrato e' superiore ad un altro
 * Input: Tempo t1: primo tempo cronometrato
 *        Tempo t2: secondo tempo cronometrato
 * Output: 1 se il primo tempo e' superiore al secondo e 0 altrimenti
 */
bool Maggiore(tTempo t1, tTempo t2) 
{
    if (t1.h==t2.h && t1.h==t2.h && t1.h==t2.h) return false;
    return !(Minore(t1,t2));
}
/*
 * Nome: ordina
 * Scopo: Ordina i maratoneti in un database
 * Input: Maratoneta v[]: il database di maratoneti
 *        int n: il numero di maratoneti contenuti nel database v
 * Output: -
 */
void ordina(tMaratoneta v[], int n, bool (*confronta)(tTempo, tTempo)) 
{
int i, j;
tMaratoneta x;

    for (i = 1; i < n; i++) 
    {
        x = v[i];
        for (j = i - 1; j >= 0 && (*confronta)(x.t, v[j].t) > 0; j--)
            v[j+1] = v[j];
        v[j+1] = x;
    }
}

/*
 * Nome: main
 * Scopo: Inizializza e visualizza i dati contenuti in un vettore di maratoneti
 *        allocato dinamicamnte ed infine ordina la sequenza di maratoneti
 * Input: --
 * Output: 0 se il programma termina correttamente
 */
int main() 
{
    tMaratoneta *v = NULL;
    int n = 0, TipoOrdinamento;
    bool (*cmp[2])(tTempo, tTempo) = { Minore, Maggiore };

    //INPUT
    v = inizializzaMaratoneti(&n);
    printf("Stampa in ordine crescente (0) o decrescente (1) -> ");
    scanf("%d", &TipoOrdinamento);
    // ALGORITMO
    ordina(v, n , cmp[TipoOrdinamento]);
    // Potevo anche usare l'operatore di dereferenziazione 
    //ordina(v, n , *cmp[TipoOrdinamento]);
    //OUTPUT
    visualizzaMaratoneti(v, n);
  
    system("pause");
    return 0;  
}

ESERCIZIO
 
Testo esercizio
 
SOLUZIONE:
Soluzione C++
Soluzione JavaScript
Soluzione VBA
Soluzione ASP
Soluzione PHP