Corso di Programmazione - Prova Pratica - Terzo Appello - 7 febbraio 2001 - prova 302


L'esame di oggi ha a che fare con un distributore automatico di merendine.

Un valore di tipo Snack può essere Mars, Pandorino, o Milka. Il suo costo è desumibile dalla tabella costante COSTO: per esempio, COSTO[Milka] è il costo di una barretta di cioccolato Milka, e nel nostro caso è uguale a 2000.

Per ottenere una merendina dal distributore, uno deve inserire delle monete (da 100, 200, 500 o 1000 lire). Queste sono rappresentate da valori del tipo enumerazione Moneta. Di monete, per avere una bibita, in genere non ne basta una, ed a questo serve il tipo ListaMonete, i cui valori sono liste semplici di elementi di tipo Moneta.

Un distributore di bibite, di tipo Distributore, lo possiamo pensare come un record di tre campi: il campo disponibili è una tabella di interi che, avendo come indice una bibita (Mars, Pandorino, o Milka, rispettivamente) ci dice quanti esemplari di quella merendina sono disponibili nel distributore stesso; il campo incasso ci dice la somma totale del denaro immesso nel distributore (che verrà incrementato ad ogni erogazione di servizio). Infine, il campo moneteInserite, servirà a memorizzare le monete inserite prima che la merendina sia fornita all'utente; si tratta di una tabella che, in corrispndenza di ogni moneta dice quante monete di quel taglio sono state inserite. Quando la lista delle monete inserite non copre il costo della bibita selezionata, o se la bibita selezionata non è più disponibile, sarà possibile all'utente annullare l'operazione ed avere indietro le monete inserite.

#define NUM_SNACKS 3
#define NUM_COINS  4


typedef enum Snack {Mars, Pandorino, Milka} Snack;
const int COSTO[] ={1500, 1000,  2000};

typedef enum Moneta {cento, duecento, cinquecento, mille} Moneta;


typedef struct ListaMonete{
	Moneta coin;
	struct ListaMonete* prossima;
} ListaMonete;


typedef struct Distributore{
	int moneteInserite[NUM_COINS];
	int disponibili[NUM_SNACKS];
	int incasso;
} Distributore;

Esercizio 1: Implementare le seguenti procedure:

Distributore* Crea(int mars, int pandorini, int cioccolate);

La funzione Crea crea un nuovo valore di tipo Distributore e ne restituisce l'indirizzo. La funzione ha come parametri il numero iniziale di merendine Mars, di pandorini, di barrette di cioccolata rispettivamente, con i quali inizializzare il campo disponibili: il primo elemento del campo disponibili (relativo ai Mars) deve essere inizializzato con il valore passato al parametro mars, e la stessa cosa deve essere fatta per i pandorini e le barrette di cioccolato. Tutti gli elementi della tabella moneteInserite vengono inizializzati a 0. Il campo incasso viene inizializzato a 0.

 

void stampa(Distributore d);

La procedura stampa deve fornire a video una rappresentazione dello stato dei campi del distributore d passato come parametro attuale.


Esercizio 2: Implementare la seguente funzione:

int selezionaSnack(Distributore* d, ListaMonete* monete, Snack snack);

Questa funzione restituisce 1 se le monete della lista monete (la lista delle monete inserite, passata come parametro attuale) hanno raggiunto o superato il costo dello snack (consultando l'array costante COSTO) e se lo snack selezionato Ŕ ancora disponibile. In tal caso, il distributore non restituisce il resto: l'incasso del distributore d viene incrementato dell'importo inserito, e viene decrementato il numero di snack di quel tipo ancora a disposizione in d.

Qualora invece le monete inserite non coprano il costo dello snack, la funzione restituisce 0, e negli elementi della tabella moneteInserite resterÓ traccia di quante monete da 100, 200, 500 e 1000 sono state inserite (gli altri campi resteranno immutati), in attesa di una chiamata della funzione annulla.

Infine, se le monete inserite superano il costo dello snack ma quest'ultimo non risulta disponibile, la funzione restituisce -1, e negli elementi della tabella moneteIinserite resterÓ traccia di quante monete da 100, 200, 500 e 1000 sono state inserite (gli altri campi resteranno immutati), in attesa di una chiamata della funzione annulla.


Esercizio 3: Implementare la seguente funzione:

int annulla(Distributore* d);

La funzione annulla permette di azzerare l'operazione in corso: la funzione restituisce il valore complessivo delle monete inserite. Alla fine, a tutti gli elementi della tabella moneteInserite di d deve essere assegnato il valore 0.


IMPORTANTE:
La modalità di consegna dell'esame
è analoga a quella delle esercitazioni durante il corso: è sufficiente inviarlo come esercitazione numero 302.

Bisogna inserire esclusivamente la definizione delle funzioni richieste ed eventuali procedure o funzioni ausiliarie, per consentirne la correzione automatica.

Per superare la prova è necessario che almeno uno dei tre esercizi sia corretto (ovvero che la compilazione abbia successo e che l'esecuzione soddisfi la specifica data).