Fondamenti Informatica B Soluzioni seconda prova intermedia del 30 gennaio 2006 temi 1 e 2 Esercizio 1 tema 1 Siano date le seguenti definizioni di costanti e tipi in linguaggio C: #define MAX_LENGTH 40 #define MAX_PRENOTAZIONI_UTENTE 10 typedef char Stringa[MAX_LENGTH]; typedef struct { Stringa cognome; Stringa nome; int numpersone; Stringa giornoarrivo; /*nel formato ggmmaaaa */ int giornipermanenza; Prenotazione; /* una variabile di questo tipo contiene la singola prenotazione richiesta da un utente */ typedef struct { Prenotazione vettprenotazioni[max_prenotazioni_utente]; int numprenotazioni; ElencoPrenotazioni;
typedef struct el { Prenotazione info; struct el *next; ElemLista; typedef ElemLista *Lista; Si sviluppi il sottoprogramma void inserisciprenotazionidioggi(elencoprenotazioni prenotazioni, Stringa datacorrente, Lista *l); che inserisce nella lista puntata da l tutte le prenotazioni contenute in prenotazioni che hanno come giorno di arrivo la data corrente. In altre parole, tutte le prenotazioni il cui campo giornoarrivo sia uguale al parametro datacorrente. È possibile utilizzare le funzioni di libreria per la manipolazione delle stringhe (ad esempio, per valutare se due stringhe sono uguali). SOLUZIONE void inserisciprenotazionidioggi(elencoprenotazioni prenotazioni, Stringa datacorrente, Lista *l) { int i; Prenotazione p; for (i=0; i < prenotazioni.numprenotazioni; i++) { p = prenotazioni.vettprenotazioni[i]; if (strcmp(p.giornoarrivo, datacorrente) == 0) inserisciintesta(l, p);
tema 2 Siano date le seguenti definizioni di costanti e tipi in linguaggio C: #define MAX_LENGTH 40 #define MAX_PRENOTAZIONI_UTENTE 10 typedef char Stringa[MAX_LENGTH]; typedef struct { Stringa cognome; Stringa nome; int numpersone; Stringa giornoarrivo; /*nel formato ggmmaaaa */ int giornipermanenza; Prenotazione; /* una variabile di questo tipo contiene la singola prenotazione richiesta da un utente */ typedef struct { Prenotazione vettprenotazioni[max_prenotazioni_utente]; int numprenotazioni; ElencoPrenotazioni; typedef struct el { Prenotazione info; struct el *next; ElemLista;
typedef ElemLista *Lista; Si sviluppi il sottoprogramma void inserisciprenotazionidioggi(elencoprenotazioni prenotazioni, int numerog, Lista *l); che inserisce nella lista puntata da l tutte le prenotazioni contenute in prenotazioni in cui i giorni di permanenza siano in numero inferiore al valore del parametro numerog ed il numero di persone indicato nella prenotazione sia superiore a 5. SOLUZIONE void inserisciprenotazionidioggi(elencoprenotazioni prenotazioni, int numerog, Lista *l) { int i; Prenotazione p; for (i=0; i < prenotazioni.numprenotazioni; i++) { p = prenotazioni.vettprenotazioni[i]; if (p.giornipermanenza < numerog && p.numpersone > 5) inserisciintesta(l, p); Esercizio 2 tema1 Si consideri la seguente funzione ricorsiva: int fric(int a) { if (a < 2) return 0;
else if ((a % 2) == 0) return a + fric(a-2); else return fric(a-1); Si consideri, inoltre, la chiamata di fric all interno del seguente main: void main() { int valore = 5; int risultato; risultato = fric(valore); printf( Risultato della chiamata ricorsiva: %d, risultato); 1. Quale valore viene stampato dal main? Si mostri lo stato della memoria nel momento in cui l ultimo record di attivazione associato a fric è ancora attivo. 2. Qual è in generale il valore calcolato dalla funzione fric? SOLUZIONE 1)
main valore = 5 risultato = fric(valore) risultato = 0 + 2 + 4 = 6 6 fric(5) 1 rec. att. a = 5 return = fric(4) 6 fric(4) 2 rec. att. a = 4 return = 4 + fric(2) 2 fric(2) 3 rec. att. a = 2 return = 2 + fric(0) fric(0) 4 rec. att. a = 0 return = 0 0 2) La funzione calcola la somma dei numeri pari compresi fra il valore passato come parametro e 2. tema 2 Si consideri la seguente funzione ricorsiva: int fric(int a) { if (a < 3) return 0; else if ((a % 3) == 0) return a + fric(a-3); else return fric(a-(a%3));
Si consideri, inoltre, la chiamata di fric all interno del seguente main: void main() { int valore = 10; int risultato; risultato = fric(valore); printf( Risultato della chiamata ricorsiva: %d, risultato); 1. Quale valore viene stampato dal main? Si mostri lo stato della memoria nel momento in cui l ultimo record di attivazione associato a fric è ancora attivo. 2. Qual è in generale il valore calcolato dalla funzione fric? SOLUZIONE 1)
2) La funzione calcola la somma dei multipli di 3 compresi fra il valore passato come parametro e 3.
Esercizio 3 tema 1 I dati relativi ai risultati del campionato di hockey su ghiaccio per l anno 2005 vengono salvati all interno del file di testo risultati2005.txt. Tali dati vengono memorizzati per righe, secondo il seguente formato: Milano Asiago 10 3 Cortina Bolzano 2 3 Ogni riga del file memorizza le informazioni relative a una partita giocata nel 2005. Per ogni partita, le informazioni memorizzate sono (nell ordine in cui appaiono in ogni riga): il nome della squadra di casa; il nome della squadra ospite; il punteggio della squadra di casa; il punteggio della squadra ospite. 1. Si definisca il tipo di dato Partita. Una variabile di questo tipo deve permettere di memorizzare tutti i dati relativi ad una partita. 2. Data la seguente definizione del tipo Stringa: #define MAX_LENGTH 50 typedef char Stringa[MAX_LENGTH]; Si scriva il codice del sottoprogramma int vittorietrasferta(stringa nomefile), che legge dal file risultati2005.txt i dati relativi alle partite e visualizza sullo schermo i dettagli di tutte quelle dove la squadra ospite ha battuto la squadra di casa. Il sottoprogramma restituisce il numero complessivo delle partite in cui la squadra ospite ha battuto la squadra di casa. 3. Dato il seguente main, si scriva la corretta chiamata alla funzione vittorietrasferta....
void main() { Stringa nomefileris = risultati2005.txt ; int vittorie; /* chiamata funzione vittorietrasferta(...) */... SOLUZIONE 1) typedef struct { Stringa nomesquadracasa; Stringa nomesquadraospite; int punteggiocasa; int punteggioospite; Partita; 2) int vittorietrasferta(stringa nomefile) { int contvittorietrasferta = 0; int valorilettidafile; Partita p; FILE *pf= fopen(nomefile, "r"); if (pf == NULL) printf("impossibile aprire il file %s", nomefile);
else { valorilettidafile = fscanf(pf, "%s %s %d %d", p.nomesquadracasa, p.nomesquadraospite, &p.punteggiocasa, &p.punteggioospite); while (valorilettidafile > 0) { if (p.punteggioospite > p.punteggiocasa) { contvittorietrasferta++; printf("dettagli partita: ospite %s batte casa %s %d a %d", p.nomesquadraospite, p.nomesquadracasa, p.punteggioospite, p.punteggiocasa); valorilettidafile = fscanf(pf, "%s %s %d %d", p.nomesquadracasa, p.nomesquadraospite, &p.punteggiocasa, &p.punteggioospite);
if (fclose(pf)!= 0) printf("errore nella chiusura del file"); return contvittorietrasferta; 3) void main() { Stringa nomefileris = "risultati2005.txt"; int vittorie; /* chiamata funzione vittorietrasferta(...) */ vittorie = vittorietrasferta(nomefileris); tema 2 I dati relativi ai risultati del campionato di hockey su ghiaccio per l anno 2005 vengono salvati all interno del file di testo risultati2005.txt. Tali dati vengono memorizzati per righe, secondo il seguente formato: Milano Asiago 10 3 Cortina Bolzano 2 3 Ogni riga del file memorizza le informazioni relative a una partita giocata nel 2005. Per ogni partita, le informazioni memorizzate sono (nell ordine in cui appaiono in ogni riga): il nome della squadra di casa; il nome della squadra ospite;
il punteggio della squadra di casa; il punteggio della squadra ospite. 1. Si definisca il tipo di dato Partita. Una variabile di questo tipo deve permettere di memorizzare tutti i dati relativi ad una partita. 2. Data la seguente definizione del tipo Stringa: #define MAX_LENGTH 50 typedef char Stringa[MAX_LENGTH]; Si scriva il codice del sottoprogramma int memorizzavittorie(stringa nomefile), che acquisisce da tastiera i dati relativi alle partite e salva sul file risultati2005.txt quelli relativi alle partite dove la squadra ospite ha battuto la squadra di casa. Il sottoprogramma restituisce il numero complessivo delle partite in cui la squadra ospite ha battuto la squadra di casa. 3. Dato il seguente main, si scriva la corretta chiamata alla funzione memorizzavittorie.... void main() { Stringa nomefileris = risultati2005.txt ; int vittorie; /* chiamata funzione memorizzavittorie(...) */... SOLUZIONE 1) typedef struct { Stringa nomesquadracasa;
Stringa nomesquadraospite; int punteggiocasa; int punteggioospite; Partita; 2) int memorizzavittorie(stringa nomefile) { int contvittorietrasferta = 0; int valoriscrittisufile; boolean terminalettura; Partita p; FILE *pf= fopen(nomefile, "w"); if (pf == NULL) printf("impossibile aprire il file %s", nomefile); else { do { printf("\ninserisci dati di una partita\n"); printf("nome squadra di casa:"); scanf("%s", p.nomesquadracasa); printf("\nnome squadra ospite:"); scanf("%s", p.nomesquadraospite); printf("\npunteggio squadra di casa:"); scanf("%d", &p.punteggiocasa); printf("\npunteggio squadra ospite:"); scanf("%d", &p.punteggioospite);
if (p.punteggioospite > p.punteggiocasa) { contvittorietrasferta++; valoriscrittisufile = fprintf(pf, "%s %s %d %d", p.nomesquadracasa, p.nomesquadraospite, p.punteggiocasa, p.punteggioospite); printf("terminare lettura (sì = 1)?"); scanf("%d", &terminalettura); while (terminalettura == falso && valoriscrittisufile > 0); if (terminalettura == falso) printf("errore scrittura su file"); if (fclose(pf)!= 0) printf("errore nella chiusura del file"); return contvittorietrasferta; 3) void main() {
Stringa nomefileris = "risultati2005.txt"; int vittorie; /* chiamata funzione memorizzavittorie(...) */ vittorie = memorizzavittorie(nomefileris); Esercizio 4 tema 1 Si indichi quale delle seguenti affermazioni è vera motivando brevemente la risposta (è possibile che una, nessuna o più affermazioni siano vere contemporaneamente): 1. Un indirizzo di rete può essere assegnato contemporaneamente a più calcolatori. 2. Un processo è definito come la coppia (programma eseguibile, stato di esecuzione). 3. La memoria virtuale ci consente di aumentare la capacità di memorizzazione di una memoria di massa. SOLUZIONE 1. falso, 2. vero, 3. falso (aumenta la capacità della memoria centrale!) tema 2 Si indichi quale delle seguenti affermazioni è vera motivando brevemente la risposta (è possibile che una, nessuna o più affermazioni siano vere contemporaneamente): 1. Un processo è un programma eseguibile. 2. Un indirizzo di rete non può mai essere assegnato contemporaneamente a più calcolatori.
3. Un processo può passare dallo stato di attesa allo stato di esecuzione appena il dato che stava aspettando si rende disponibile. SOLUZIONE 1. falso (è necessario anche lo stato di esecuzione), 2. vero, 3. falso (il processo passa sempre prima dallo stato di pronto).