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


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

Un valore di tipo Bibita può essere coca, fanta, o birra. Il suo costo è desumibile dalla tabella costante COSTO: per esempio, COSTO[coca] è il costo di una lattina di cocacola, e nel nostro caso è uguale a 1000.

Per ottenere una bibita 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 (coca, fanta e birra, rispettivamente) ci dice quante bottiglie di quella bibita 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, di tipo ListaMonete, servirà a memorizzare le monete inserite prima che la bibita sia fornita all'utente. Se infatti 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_BIBITE 3
const int COSTO[] ={1000, 1000,  1500};
typedef enum Bibita {coca, fanta, birra} Bibita;
typedef enum Moneta {cento, duecento, cinquecento, mille} Moneta;


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


typedef struct Distributore{
	int disponibili[ NUM_BIBITE ];
	int incasso;

	ListaMonete* moneteInserite;
} Distributore;

Esercizio 1: Implementare le seguenti procedure:

Distributore* Crea(int cokes, int fante, int birre);

La funzione Crea crea un nuovo valore di tipo Distributore e ne restituisce l'indirizzo. La funzione ha come parametri il numero di lattine iniziale di coca cola, di fanta e di birra rispettivamente, con i quali inizializzare il campo disponibili: il primo elemento del campo disponibili (relativo alle bottiglie di coca cola) viene inizializzato con il valore passato al parametro cokes, e analogamente viene fatto per le bottiglie di fanta e di birra. Il campo moneteInserite viene inizializzato a NULL, 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 selezionaBibita(Distributore* d, ListaMonete* monete, Bibita bibita);

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 della bibita (consultando l'array costante COSTO) e se la bibita selezionata Ŕ 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 bibite di quel tipo ancora a disposizione in d.

Qualora invece le monete inserite non coprano il costo della bibita, la funzione restituisce 0, e nel campo monete_inserite resterÓ una copia della lista monete (gli altri campi resteranno immutati), in attesa della funzione annulla.

Infine, se le monete inserite superano il costo della bibita ma quest'ultima non risulta disponibile, la funzione restituisce -1, e nel campo monete_inserite resterÓ una copia della lista monete (gli altri campi resteranno immutati), in attesa anche in questo caso della funzione annulla.


Esercizio 3: Implementare la seguente funzione:

ListaMonete* annulla(Distributore* d);

La funzione annulla permette di azzerare l'operazione in corso: le monete vengno restituite in una lista, nello stesso ordine con cui erano state immesse nel distributore d. Alla fine, al campo moneteInserite di d deve essere assegnato il valore NULL.


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

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).