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';
}
}