La prenotazione di posti in aereo con vettore e puntatori

Un esercizio sicuramente impegnativo per gli alunni più giovani ed inesperti che permette però di rinforzare le proprie competenze nell’uso dei vettori e dei tanti odiati puntatori. Vediamo come.

L’idea è che vogliamo un programma che prenoti posti di un aereo, con due categorie di posti a scelta: fumatori e non. I fumatori sono sul fondo dell’aereo, e prenotano il posto da sinistra.
Un puntatore tiene conto del prossimo posto libero per la categoria. Lo stesso per i non  fumatori partono da destra, la punta dell’areo e prenotano verso il fondo a sinistra. Anche qui un puntatore terrà traccia del prossimo posto libero, se disponibile. La struttura dei posti può essere realizzata con un vettore: 0 posto libero, 1 posto occupato. Creare un programma che chieda la preferenza fumatore o meno, occupi il posto libero o segnali l’indisponibilità dello stesso.

Vediamo subito la codifica. Il problema non è complesso ma richiede alcune accortezze tecniche. Innanzi tutto dobbiamo creare il nostre vettore che conterrà i posti. Lo scegliamo di 50, di cui 20 per i fumatori. Usiamo una define per impostare POSTI e FUMATORI quindi. Per semplicità, ci creiamo due funzioni: una che stampa il vettore, anche possibilmente con una grafica comprensibile dei posti ed una inizializza che ci permette di impostare tale vettore con un valore predefinito. Sarà un parametro equivalente a zero per noi ma il codice potremmo riutilizzarlo per altri test, tanto vale renderlo generico.

#define POSTI 50
#define FUMATORI 20

void stampa(int _vettore[])
{
    int i =0;

    for(i=0; i <= POSTI; i++)
    {
        printf("--");
    }
    printf("\n");

    for(i=0; i < POSTI; i++)
    {
        if (i == FUMATORI)
        {
            printf("* "); //separatore fumatori/non fumatori
        }

        printf("%d ", _vettore[i]);
    }

    printf("\n");
    for(i=0; i <= POSTI; i++)
    {
        printf("--");
    }
    printf("\n");
}

void inizializza(int _vettore[], int _occupato)
{
    //inizilizzo il vettore dei posti complessiv
    _occupato = _occupato ? _occupato : 0;
    int i = 0;
    for (i=0; i < POSTI; i++)
    {
        _vettore[i] = _occupato;
    }
}

Veniamo al main, il nostro programma principale. Anche qui come prima cosa ci inizializziamo tutto quello che ci occorre: il vettore dei posti che chiamo aereo. Creiamo i due puntatori, sono semplici puntatori ad intero, lo stesso tipo delle caselle del vettore aereo a cui puntano. Secondo passaggio è farli puntare rispettivamente alla cella zero e ultima del nostro vettore sfruttano la &applicata ad una variabile che ci restituisce il suo indirizzo in memoria. Il secondo puntatore, occhio che deve puntare all’ultima posizione a destra che non coincide con numero posti ma posti -1, iniziando il vettore da zero.

    int *next_fumatore;
    int *next_nonfumatore;

    next_fumatore = &aereo[0];
    next_nonfumatore = &aereo[POSTI - 1];

Quindi la parte più complessa: creiamoci un ciclo che interagisce con l’utente finché non si digita una scelta di uscita. Qui scelgo 1 di inserire un fumatore, 2 inserire un non fumatore, 3 uscire appunto. Inserisco uno switch che mi snellisce il codice ma la struttura è realizzabile anche con if o if/else. Se vogliamo inserire un fumatore dobbiamo fare prima un controllo di integrità: c’è un posto libero? Per tenere traccia mi creo un contatore su misura con la classica i. Lo incremento se c’è posto tra i fumatori e vado quindi a prima usare il puntatore per impostare il posto puntato ad occupato, ovvero 1. Incremento il puntatore o spostare il mio puntatore, sulla falsa riga di quello fatto in fase di inizializzazione degli stessi puntatori, solo che sfrutterò l’indice i per progredire sul puntare la successiva casella. Stampo il vettore per far vedere la situazione aggiornata. Il discorso del contrario è speculare, ma con un contatore j con la dimensione del numero di posti -1 che si decrementa fino a raggiungere l’ultimo posto prima della zona fumatori. Al lettore le considerazioni su questo secondo caso.

                if (i < FUMATORI)
                {
                    *next_fumatore = 1;
                    i++;
                    next_fumatore = &aereo[i];
                    stampa(aereo);
                }
                else
                {
                    printf("Posti fumatori esauriti\n");
                }

 

La codifica completa:

#include <stdio.h>
#include <stdlib.h>

#define POSTI 50
#define FUMATORI 20

void stampa(int _vettore[])
{
    int i =0;

    for(i=0; i <= POSTI; i++)
    {
        printf("--");
    }
    printf("\n");

    for(i=0; i < POSTI; i++)
    {
        if (i == FUMATORI)
        {
            printf("* "); //separatore fumatori/non fumatori
        }

        printf("%d ", _vettore[i]);
    }

    printf("\n");
    for(i=0; i <= POSTI; i++)
    {
        printf("--");
    }
    printf("\n");
}

void inizializza(int _vettore[], int _occupato)
{
    //inizializzo il vettore dei posti complessivi
    _occupato = _occupato ? _occupato : 0;
    int i = 0;
    for (i=0; i < POSTI; i++)
    {
        _vettore[i] = _occupato;
    }
}

int main()
{
    int aereo[POSTI];
    int *next_fumatore;
    int *next_nonfumatore;
    int scelta;

    int j = POSTI -1;
    int i= 0;

    inizializza(aereo,0);

    next_fumatore = &aereo[0];
    next_nonfumatore = &aereo[POSTI - 1];

    while(scelta != 3)
    {
        printf("Scegli 1 per inserire un fumatore \n");
        printf("Scegli 2 per inserire un non fumatore \n");
        printf("Scegli 3 per uscire \n");
        scanf("%d", &scelta);

        switch(scelta)
        {
            case 1:
                if (i < FUMATORI)
                {
                    *next_fumatore = 1;
                    i++;
                    next_fumatore = &aereo[i];
                    stampa(aereo);
                }
                else
                {
                    printf("Posti fumatori esauriti\n");
                }
                break;

            case 2:
                if(j >= FUMATORI)
                {
                    *next_nonfumatore = 1;
                    j--;
                    next_nonfumatore = &aereo[j];
                    stampa(aereo);
                }
                else
                {
                    printf("Posti non fumatori esauriti\n");
                }
                break;

            case 3:
               return 0;
        }

    }

    return 0;
}

Ultima modifica 27 Gennaio 2022

Lascia un commento