Informatica 1 Prova di recupero 15 Febbraio 2005 Si risolvano i seguenti esercizi. Ai fini della determinazione del voto finale il loro punteggio andrà sommato al punteggio del laboratorio. Il tempo complessivo a disposizione è di 3 ore. Esercizio 1 (2 punti) Si rappresentino in complemento a due i numeri 45 e 64, usando parole di 16 bit. Quindi si esegua la differenza, in binario, 45 64 e si riconverta il risultato in formato decimale. Esercizio 2 (4 punti) Si considerino le seguenti dichiarazioni nel linguaggio C typedef struct { float PrimoCampo; char SecondoCampo; int TerzoCampo; struttura; struttura x, r; int z; float w; Scrivere una sequenza di istruzioni nel linguaggio di von Neumann che sia equivalente alle seguenti istruzioni C: x = r; z = r.terzocampo; r.primocampo = w; Si possono fare le seguenti assunzioni: 1. Una variabile di tipo float occupa due celle di memoria, mentre variabili di tipo int e char ne occupano una. Le celle della macchina di von Neumann corrispondenti alle variabili C suddette sono, rispettivamente: x: Un numero adeguato di celle a partire dalla cella 101 r: Un numero adeguato di celle a partire dalla cella 111 z: Un numero adeguato di celle a partire dalla cella 121 w: Un numero adeguato di celle a partire dalla cella 131 I campi delle variabili di tipo struttura sono memorizzati in celle consecutive. 2. Le istruzioni del linguaggio di von Neumann utilizzabili sono le seguenti LOAD xxx STORE xxx ADD xxx
SUB xxx BR zzz (Salta all istruzione numero zzz) BEQ zzz (Salta all istruzione numero zzz se il contenuto dell accumulatore è 0) BG zzz (Salta all istruzione numero zzz se il contenuto dell accumulatore è > 0) BGE zzz (Salta all istruzione numero zzz se il contenuto dell accumulatore è >= 0) BLE zzz (Salta all istruzione numero zzz se il contenuto dell accumulatore è <= 0) L aggiunta del simbolo = subito dopo il codice operativo di un istruzione indica la modalità di indirizzamento immediata. L aggiunta del simbolo @ subito dopo il codice operativo di un istruzione indica la modalità di indirizzamento indiretta. 3. Le istruzioni del linguaggio di von Neumann che realizzano il codice C suddetto siano numerate a partire dal numero k Esercizio 3 (20 punti) Parte a. (3 punti) Definire dei tipi di dato per contenere informazioni relative a patenti e multe. Una patente è definita da un numero identificativo, dal nome del proprietario, dal suo codice fiscale, da una data di rilascio e una di scadenza, e da un numero di punti ancora disponibili sulla patente. Una multa è definita da un numero identificativo, dal numero identificativo della patente cui viene addebitata, dalla data in cui è stata emessa, dall'ammontare della multa (in euro), dal numero di punti da togliere alla patente a causa della multa. Parte b. (9 punti nella versione semplificata; 12 nella versione completa) Codificare un sottoprogramma che prende in ingresso i descrittori fpat e fmul di 2 file (entrambi supposti aperti sia in lettura che in scrittura), uno contenente una serie di patenti, ed uno contenente una serie di multe, e ritorna il descrittore di un nuovo file. Il sottoprogramma deve realizzare quanto segue: per ogni multa presente nel file fmul, il sottoprogramma modifica i dati della patente corrispondente nel file fpat, togliendo i punti indicati nella multa. Se una patente, dopo avere sottratto i punti di una multa, ha un residuo di punti minore o uguale a zero, il sottoprogramma scrive in un terzo file (il cui descrittore verrà ritornato alla fine) la posizione nel file fpat della suddetta patente. Si assuma che nel file fpat le patenti siano elencate in ordine di data di scadenza, mentre nel file fmul le multe siano ordinate secondo l identificatore della patente a cui si riferiscono. Si supponga pure che tutte le multe del file fmul si riferiscano a patenti effettivamente esistenti nel file fpat. Versione semplificata Si assuma che per ogni patente nel file fmul si trovi al massimo una multa. Parte c. (7 punti) Codificare un sottoprogramma che prende in ingresso il nome di un file contenente patenti, e restituisce una lista contenente le patenti con meno di 10 punti residui, ordinate in ordine crescente di punti residui (cioè mettendo prima quelle con meno punti residui).
Soluzioni Esercizio 1 45: 0000000000101101 64: 0000000001000000-64: 1111111111000000 45-64: 0000000000101101 + 1111111111000000 = 1111111111101101 Che è il complemento di 10011, cioè -19, come dovrebbe essere. Esercizio 2 /* x = r, con x che parte dalla cella 101 ed occupa 4 celle, mentre r parte dalla cella 111 */ LOAD 111 STORE 101 LOAD 112 STORE 102 LOAD 113 STORE 103 LOAD 114 STORE 104 /* z = r.terzocamp, con il terzo campo di r che corrisponde alla cella 114 */ LOAD 114 STORE 121 /* r.primocampo = w, con il primo campo di r che è lungo 2 celle */ LOAD 131 STORE 111 LOAD 132 STORE 112
Esercizio 3 Parte a. typedef struct { unsigned long id; char nome[80]; char CF[16]; TipoData rilascio; TipoData scadenza; int punti; TipoPatente; /* dove TipoData è stata più volte dichiarata a lezione e esercitazione. */ typedef struct { unsigned long id; unsigned long id_pat; TipoData emessa; float somma; int punti; TipoMulta; Parte b. Versione completa. FILE *aggiornapatenti(file *fpat, FILE *fmul){ TipoMulta m_cor, m_prec; unsigned long id_pat; int totpunti; long pos_pat; bool next_pat; /* bool è definito come al solito */ FILE *fsottozero = fopen("invalide.txt", "wb"); rewind(fmul); while(!feof(fmul)){ next_pat = false; totpunti = 0; do { fread(&m_cor, sizeof(tipomulta), 1, fmul); if(totpunti == 0){
/* è la prima multa che leggo relativa alla prossima patente */ totpunti = m_cor.punti; m_prec = m_cor; else if (m_cor.id_pat == m_prec.id_pat){ /* la multa appena letta si riferisce alla stessa patente della multa precedente, * mi, limito a sommare i punti da togliere */ totpunti += m_cor.punti; else { /* devo passare alla prossima multa; come prima cosa, ritorno sulla multa precedente */ fseek(fmul, -(sizeof(tipomulta)), SEEK_CUR); m_cor = m_prec; next_pat = true; while(!feof(fmul) && next_pat == false); /* Vado a cercare la patente da modificare nel file di patenti, quindi faccio i cambiamenti * necessari; */ rewind(fpat); do { fread(&p, sizeof(tipopatente), 1, fpat); while(p.id!= m_cor.id_pat); fseek(fpat, -(sizeof(tipopatente)), SEEK_CUR); p.punti -= totpunti; pos_pat = ftell(fpat); fwrite(&p, sizeof(tipopatente), 1, fpat); /* se la patente ha un numero di punti <= 0, la segnalo nel file apposito; if (p.punti <= 0){ fwrite(&pos_pat, sizeof(long), 1, fsottozero); /* fine del while esterno */ return fsottozero;
Versione semplificata. FILE *aggiornapatenti(file *fpat, FILE *fmul){ TipoMulta m_cor, m_prec; unsigned long id_pat; int totpunti; long pos_pat; bool next_pat; /* bool è definito come al solito */ FILE *fsottozero = fopen("invalide.txt", "wb"); rewind(fmul); while(fread(&m_cor, sizeof(tipomulta), 1, fmul) == 1){ /* Vado a cercare la patente da modificare nel file di patenti, quindi faccio i cambiamenti * necessari; */ rewind(fpat); do { fread(&p, sizeof(tipopatente), 1, fpat); while(p.id!= m_cor.id_pat); fseek(fpat, -(sizeof(tipopatente)), SEEK_CUR); p.punti -= m_cor.punti; pos_pat = ftell(fpat); fwrite(&p, sizeof(tipopatente), 1, fpat); /* se la patente ha un numero di punti <= 0, la segnalo nel file apposito; if (p.punti <= 0){ fwrite(&pos_pat, sizeof(long), 1, fsottozero); /* fine del while esterno */ return fsottozero;
Parte c. typedef struct EL { TipoPatente info; struct EL *next; ElListaPatenti; typedef TipoElPatente *ListaPatenti; ListaPatenti menodi10(char *nome_file){ FILE *f = fopen(nome_file, "rb"); ListaPatenti res = NULL; TipoPatente p; while(fread(&p, sizeof(tipopatente), 1, f) == 1){ if (p.punti < 10) inser_per_punti(&res, p); return res; /* adattata dalla funzione vista ad esercitazione */ bool inser_per_punti(listapatenti *l, TipoPatente p) { ElListaPatenti *pt_new_el; if (*arch == NULL) { pt_new_el = malloc(sizeof(ellistapatenti)); pt_new_el->info = p; pt_new_el->next = NULL; *l = pt_new_el; return true; if((*l)->info.punti > p.punti) { pt_new_el = malloc(sizeof(ellistapatenti)); pt_new_el->info = p; pt_new_el->next = *l; *l = pt_new_el; return true; else { return inser_per_punti(&((*l)->next), p);