matricola, nome, cognome - diegm - Università degli Studi di Udine
Transcript
matricola, nome, cognome - diegm - Università degli Studi di Udine
Università degli Studi di Udine Corsi di laurea in Ing. Gestionale FONDAMENTI DI INFORMATICA (NUOVO ORDINAMENTO) 10 gennaio 2007 - Prova scritta DA RIPORTARE SUL FOGLIO CHE VERRÀ CONSEGNATO: matricola, nome, cognome ISTRUZIONI (da leggere attentamente) 1) Lo studente è tenuto a scrivere, correggere, compilare ed eseguire su computer (a casa o in laboratorio) gli esercizi di programmazione prima della prova orale. Alla prova orale lo studente deve portare un floppy disk contenente i sorgenti dei programmi corretti e le stampe dei relativi file. 2) Non è consentito l’uso di libri, appunti, calcolatrici programmabili, telefoni cellulari. 1. (16 punti) Un dato linguaggio di programmazione assembly prevede l'inserimento di commenti nel codice sorgente mediante la sequenza di caratteri “::” che deve precedere il testo del commento. Il commento termina alla fine della riga. Esempio (per maggior chiarezza, le istruzioni sono scritte in maiuscolo, i commenti in minuscolo): C:\> type esempio.asm ::::::::::::::::::::::::::::::::::: questo e` un commento START: XOR R0 R0 :: questo e` un altro commento MV R1 R2 :: ecc. :: il sorgente puo` contenere righe vuote LOOP: end: LDBR JMPZ INC INC JMP RET R3 R2 end R0 R2 LOOP :: :: :: :: :: copia in R3 l'i-esimo carattere della stringa se vale zero ('\0') la stringa e` finita incrementa il contatore incrementa il puntatore ripete :: (commento) fine del programma Si scriva in linguaggio C il programma uncomment.c che riceve come parametro sulla riga di comando il nome del file sorgente assembly contenente i commenti, che ha estensione .asm, e scrive un file con il medesimo nome ma estensione .as2 contenente soltanto tutte le istruzioni e non i commenti. NOTA: le istruzioni possono contenere il singolo carattere ':' ma non contengono mai la sequenza “::”. Esempio: C:\> uncomment esempio C:\> type esempio.as2 START: XOR MV R0 R0 R1 R2 LOOP: R3 R2 end R0 R2 LOOP end: LDBR JMPZ INC INC JMP RET #include <stdio.h> #include <stdlib.h> #define MAXSTRLEN 64 void uncomment (FILE *fin, FILE *fout); int main (int argc, char *argv[]) { FILE *fin, *fout; char nomefin[MAXSTRLEN], nomefout[MAXSTRLEN]; if (argc != 2) { printf ("numero di parametri errato\n"); exit (EXIT_FAILURE); } strcpy (nomefin, argv[1]); strcat (nomefin, ".asm"); strcpy (nomefout, argv[1]); strcat (nomefout, ".as2"); if ((fin = fopen (nomefin, "r")) == NULL) { printf ("errore di apertura del file di input"); exit (EXIT_FAILURE); } if ((fout = fopen (nomefout, "w")) == NULL) { printf ("errore di apertura del file di output"); exit (EXIT_FAILURE); } uncomment (fin, fout); fclose (fin); fclose (fout); return EXIT_SUCCESS; } void uncomment (FILE *fin, FILE *fout) { int ch, ch_prec; int possibile_commento; possibile_commento = 0; while ((ch = fgetc (fin)) != EOF) { if (ch == ':') { if (possibile_commento) { /* inizio del commento: salta la riga */ while ((ch = fgetc (fin)) != EOF && ch != '\n'); fputc ('\n', fout); possibile_commento = 0; } else { possibile_commento = 1; ch_prec = ch; } } else { if (possibile_commento) { /* falso allarme */ fputc (ch_prec, fout); possibile_commento = 0; } fputc (ch, fout); } } return; } 2. (16 punti) Si scriva in linguaggio C la funzione int num_morse (char s[]) che restituisce il valore del numero intero rappresentato in codice morse nella stringa s. Nella stringa s un carattere ‘-’ indica un punto, una sequenza di tre caratteri ‘-’ indica una linea (cioè “---”), uno spazio separa un simbolo del codice morse (punto o linea) dal successivo, tre spazi separano una cifra dalla successiva. La codifica delle singole cifre in codice morse può essere rappresentata dal seguente vettore di stringhe (‘P’ = punto, ‘L’ = linea): char *nmorse[] = { "LLLLL", "PLLLL","PPLLL","PPPLL","PPPPL", "PPPPP","LPPPP","LLPPP","LLLPP","LLLLP" } (Quindi nmorse[1]è la stringa "PLLLL", nmorse[5]è la stringa "PPPPP", ecc.). Si assuma che la stringa sia corretta. Esempi: s[] = "- - --- --- --- - - --- ---" s[] = "- - - - --- --- --- --- --- ⇒ 23 - --- --- --- ---" ⇒ 501 Suggerimento 1: si scriva una funzione che restituisca il valore della prossima cifra e che, a sua volta, utilizzi una fiunzione che restituisce il valore del prossimo simbolo (punto o linea). Suggerimento 2: si sfrutti il fatto che la stringa contiene solo codici morse di cifre nueriche, composti tutti da cinque simboli. int num_morse (char s[]) { int i, cifra, n; i = 0; n = 0; while ((cifra = prossima_cifra(s, &i)) != -1) { n = n*10 + cifra; } return n; } int prossima_cifra (char s[], int *i) { char *nmorse[] = { "LLLLL", "PLLLL","PPLLL","PPPLL","PPPPL", "PPPPP","LPPPP","LLPPP","LLLPP","LLLLP" } int k; char cifra_morse[6]; if (s[*i] != '\0') { for (k = 0; k < 5; k++) { cifra_morse[k] = prossimo_simbolo (s, i); } cifra_morse[k] = '\0'; k = 0; while (k < 10 && strcmp (cifra_morse, nmorse[k])) k++; if (k == 10) { printf ("errore nella stringa\n"); exit (EXIT_FAILURE); } return k; } else { return -1; } } char prossimo_simbolo (char s[], int *i) { while (s[*i] == ' ') (*i)++; if (s[(*i)+1] == '-') { /* linea */ (*i) += 3; return 'L'; } else { /* punto */ (*i)++; return 'P'; } }