Elementi di informatica e Programmazione Corsi di Laurea di Ing. Informatica, Ing. Elettronica e delle Telecomunicazioni, Ing. dell'automazione Industriale Alessandro Saetti Marco Sechi e Alessandro Bugatti (email: alessandro.saetti,marco.sechi,alessandro.bugatti@unibs.it) Università degli Studi di Brescia Elementi di informatica e programmazione Università di Brescia 1
FAC SIMILE ESAME 2
PARTE I FAC SIMILE ESAME 3
DOMANDE RISPOSTE CHIUSE 4
DOMANDE RISPOSTE CHIUSE X 55 5
DOMANDE RISPOSTE CHIUSE X 1 bit 0, 1 2 bit 0, 1, 2, 3 (00, 01, 10, 11) 3 bit 0, 1, 2, 23-1 (000, 001, 010, 011, 100, 101, 110, 111) K bit 0 2 k -1 2 6 6 2 4 8 16 32 64 55 6
DOMANDE RISPOSTE CHIUSE X Struttura semplificata di una unità centrale di elaborazione e dei suoi collegamenti con le altre unità funzionali 7
DOMANDE RISPOSTE CHIUSE X La cache è costituita da SRAM (acronimo di Static Random Access Memory). E' un tipo di RAM volatile che non necessita di refresh. La necessità di usare molti componenti per cella le rende però più costose delle DRAM (usate per la ram). Le celle di una SRAM sono costituite sostanzialmente da un particolare circuito 8
DOMANDE RISPOSTE CHIUSE X X I= X= V[] V[i]= 9
DOMANDE RISPOSTE CHIUSE X F() I Copio il valore I= I= 10
DOMANDE RISPOSTE CHIUSE X P[1].x= P[1].x= F() P[1].x= P[1].x= 11
DOMANDE RISPOSTE CHIUSE X 12
DOMANDE RISPOSTE CHIUSE X 13
DOMANDE RISPOSTE APERTE Quesito 1: Visualizzare i divisori di un intero acquisito da tastiera. Quesito 2: Visualizzare i primi 1000 numeri con le cifre invertite. 14
DOMANDE RISPOSTE APERTE Quesito 1 Visualizzare i divisori di un intero acquisito da tastiera. 15
DOMANDE RISPOSTE APERTE Quesito 2: Visualizzare i primi 1000 numeri con le cifre invertite. Per stampare le cifre in modo rovesciato posso seguire questa procedura 1234 10 4 1234 10 123 10 4 3 123 10 12 10 4 3 2 12 10 1 10 4 3 2 1 1 10 0 FINE 16
DOMANDE RISPOSTE APERTE 17
DOMANDE RISPOSTE APERTE Quesito 3: Indicare i bit di segno, mantissa ed esponente della codifica del numero 12.683 in notazione scientifica normalizzata a base 2, definita utilizzando 8 bit per la mantissa, 4 bit per l esponente e codificando l esponente in complemento a 2. Positivo segno 0 12. 683 Codifica di 12 1100 (4 bit) La mantissa è di 8 per cui arrivo alla quarta cifra 1100. 1010 Mantissa 0.11001010 x 2 4 Esponente 0100 18
DOMANDE RISPOSTE APERTE Quesito 4: Si supponga che la memoria centrale del calcolatore contenga 3 processi P1, P2 e P3; - I tre processi siano inizialmente in stato pronto e siano ordinati nel seguente modo nella coda: P1, P2, P3 ; - Il quanto di tempo della CPU sia di 10 msec; - Il processo P1 esegua una operazione di output che dura 7 msec dopo essere stato in esecuzione per 1msec; - P2 esegua un operazione di input che dura 20msec dopo 5 msec di esecuzione; - P3 non esegua operazioni di I/O; - il tempo di esecuzione complessivo richiesto da ogni processo sia di 10 msec. Utilizzando un Gantt Chart si indichi per ogni processo quando e quali stati assume prima di terminare. 19
Quesito 5 DOMANDE RISPOSTE APERTE Quesito 5 Si consideri un calcolatore con un banco di 16 registri ad uso generico, parole di memoria di 16 bit ed istruzioni del linguaggio macchina con 4 bit di codice operativo. Scrivere il programma Assembly che incrementa di 1 unità i 30 numeri naturali presenti in un area contigua della memoria centrale, supponendo che ciascun naturale sia codificato con 2 byte e che il primo byte dell area di memoria abbia indirizzo uguale a 200. È consentito l uso delle seguenti istruzioni Assembly. Possibili formati di codifica delle nostre istruzioni assembler sono: LOADiL RX, VAL LOADiH RY, VAL ADD RX, RY, RZ LOAD RX, RY STORE RX, RY B LABEL END 20
Quesito 5 DOMANDE RISPOSTE APERTE 1 LOAD 21 STORE R3 3 Incremento R3 2 21 22 22 R1 A 200 202 2122 4 260 B R2 21
Quesito 5 DOMANDE PROGRAMMAZIONE La sequenza dei passaggi che il nostro programma deve svolgere è la seguente: A B Imposto come posizione di partenza 200 (in R1) Imposto come posizione di arrivo 260 (in R2) Leggo il contenuto indicato in R1 e lo sistemo nel registro R3 Incremento il contenuto di R3 Riscrivo il nuovo contenuto di R3 nella cella di memoria indicata da R1 Mi sposto al numero successivo incrementando R1 di 2 1 2 3 4 LOADiL R1 11001000 LOADiH R1 00000000 LOADiL R2 00000100 LOADiH R2 00000001 SI Non sono giunto in fondo (R1<R2) NO FINE 22
Quesito 5 DOMANDE RISPOSTE APERTE La memoria centrale non è altro che un insieme di celle accessibili mediante un indirizzo: OPERAZIONE DI LETTURA IN MEMORIA Leggo il contenuto indicato in R1 e lo sistemo nel registro R3 13 Per caricare nel registro R3 il contenuto della cella indicata nel registro R1 (inizialmente contenente l indirizzo 200) devo eseguire l istruzione LOAD sotto indicata: LOAD R3 R1 13 23
Quesito 5 DOMANDE RISPOSTE APERTE Incremento il contenuto di R3 Per incrementare il contenuto di un registro (nel nostro caso R3) possiamo usare la costante 0001 ADD R3 R3 0001 1 14 Incremento 13+ Si poteva anche inizializzare un registro non ancora usato (esempio R4) con il valore 1 LOADiL R4 00000001 LOADiH R4 00000000 e poi utilizzare l istruzione ADD a fianco ADD R3 R3 R4 24
Quesito 5 DOMANDE RISPOSTE APERTE OPERAZIONE DI SCRITTURA IN MEMORIA: Riscrivo il nuovo contenuto di R3 nella cella di memoria indicata da R1 14 Per scrivere il contenuto del registro R3 nella cella indicata nel registro R1 mi basta eseguire la seguente STORE STORE R1, R3 14 25
Quesito 5 DOMANDE RISPOSTE APERTE Mi sposto al numero successivo incrementando R1 di 2 14 Per spostarsi alla cifra successiva occorre spostarsi di 2 byte (il numero naturale è codificato con 2 byte) ADD R1, R1, 0010 202 200 26
Quesito 5 DOMANDE RISPOSTE APERTE Abbiamo tutto quello che ci serve per implementare la soluzione Imposto come posizione di partenza 200 (in R1) Imposto come posizione di arrivo 260 (in R2) Leggo il contenuto indicato in R1 e lo sistemo nel registro R3 Incremento il contenuto di R3 Riscrivo il nuovo contenuto di R3 nella cella di memoria indicata da R1 Mi sposto al numero successivo incrementando R1 di 2 LOADiL R1 11001000 LOADiH R1 00000000 LOADiL R2 00000100 LOADiH R2 00000001 CICLO: LOAD R3 R1 ADD R3 R3 0001 STORE R1 R3 ADD R1 R1 0010 BLT R1 R2 CICLO FINE: END R1=200 R2=260 SI Non sono giunto in fondo (R1<R2) NO FINE R3= 27
Quesito 5 DOMANDE RISPOSTE APERTE Seguendo un procedimento leggermente diverso avremo avuto invece la seguente codifica Imposto come posizione di partenza 200 (in R1) Imposto come posizione di arrivo 260 (in R2) Se non sono giunto in fondo (R1<R2) SI Leggo il contenuto indicato in R1 e lo sistemo nel registro R3 Incremento il contenuto di R3 Riscrivo il nuovo contenuto di R3 nella cella di memoria indicata da R1 Mi sposto al numero successivo incrementando R1 di 2 FINE NO LOADiL R1 11001000 LOADiH R1 00000000 LOADiL R2 00000100 LOADiH R2 00000001 INIZIO: BLT R1 R2 CICLO B FINE CICLO: LOAD R3 R1 ADD R3 R3 0001 STORE R1 R3 ADD R1 R1 0010 B INIZIO FINE: END R1= R2= R3= 28
PARTE II - PROGRAMMAZIONE FACSIMILE ESERCITAZIONE 29
INTESTAZIONE DELLA FUNZIONE TipoRestituito NomeFunzione(parametri) Predisporre opportunamente le sezioni della funzione in modo adatto alla scrittura su carta SEZIONE DICHIARAZIONE VARIABILI/ INIZIALIZZAZIONE/INPUT SEZIONE DICHIARAZIONE VARIABILI Inserire nella parte più in alto dello spazio a disposizione, man mano che servono, le variabili necessarie al corpo della funzione SEZIONE DICHIARAZIONE VARIABILI Inseriamo qui le valorizzazioni iniziali che consentono all algoritmo implementato nella funzione di operare correttamente SEZIONE CORPO FUNZIONE E' la sezione più corposa predisporre uno spazio sufficientemente ampio SEZIONE OUTPUT / PRESENTAZIONE RISULTATI Inserire nella parte più in basso dello spazio a disposizione le eventuali istruzioni di output return(valore Restituito); VALORI DI RITORNO 30
#include <stdio.h> #include <stdlib.h> Come nei flow chart occorre cercare una predisposizione spaziale adatta alla presentazione della soluzione su carta. int main() SEZIONE DICHIARAZIONE VARIABILI/ INIZIALIZZAZIONE/INPUT SEZIONE DICHIARAZIONE VARIABILI Inserire nella parte più in alto dello spazio a disposizione, man mano che servono, le variabili necessarie alla sezione algoritmo SEZIONE INIZIALIZZAZIONE / INPUT Inseriamo qui le valorizzazioni iniziali che consentono all algoritmo applicato di funzionare E' la sezione più corposa predisporre uno spazio sufficientemente ampio SEZIONE ALGORITMO SEZIONE OUTPUT / PRESENTAZIONE RISULTATI Inserire nella parte più in basso dello spazio a disposizione le istruzioni di output system("pause"); return(0); 31
DOMANDE PROGRAMMAZIONE Quesito 1: Visualizzare la quantità di divisori di 10 numeri naturali acquisiti da tastiera. Per svolgere questo compito si definisca ed utilizzi una funzione che produca la quantità di divisori di un dato intero. 32
Quesito 1 DOMANDE DI PROGRAMMAZIONE #include <stdio.h> int divisori(int num) int i, div = 0; for (i = 1; i <= num; i++) if (num % i == 0) div = div + 1; return div; int main(void) int i, x; for (i = 0; i <= 10; i++) scanf("%d", &x); printf("%d\n", divisori(x)); return 0; 33
DOMANDE PROGRAMMAZIONE Quesito 2: Acquisire 5 numeri naturali e successivamente per ciascuno di questi numeri visualizzare la x-esima potenza di 2. Per svolgere questo compito si definisca ed utilizzi una funzione che per ciascun intero x in un dato vettore di n variabili intere visualizzi la x- esima potenza di 2. È vietato l utilizzo delle funzionalità disponibili tramite la libreria math.h. 34
Quesito 2 Pot=1 2 0 Pot=Pot*2 2 1 DOMANDE DI PROGRAMMAZIONE Pot 1 Pot 2 1 Calcolo della potenza n esima di 2 mediante iterazione 1 Pot 2 1 i Pot=Pot*2 2 2 4 2 Pot Pot 2 2 i Pot=Pot*2 2 n 2 n 2 n-1 Pot Pot 2 n i 35
Quesito 2 DOMANDE DI PROGRAMMAZIONE #include <stdio.h> void potenza(int v[], int n) int i, j, pot; for (i = 0; i < n; i++) pot = 1; for (j = 1; j <= v[i]; j++) pot = pot * 2; printf("%d\n", pot); int main(void) int vett[5], i; for (i = 0; i < 5; i++) scanf("%d", &vett[i]); potenza(vett,5); return 0; 36
DOMANDE PROGRAMMAZIONE Quesito 3: Acquisire da tastiera 10 date del calendario e successivamente visualizzare il numero di date acquisite che precedono l ultima data acquisita. Per svolgere questo compito si dichiari una nuova tipologia di dati adatta ai fini dell esercizio e si definisca ed utilizzi due funzioni C con le seguenti finalità: Produrre 1 se una data del calendario precede una seconda data del calendario. Produrre la quantità di date del calendario in un data sequenza di n date del calendario che precedono una data del calendario. 37
Quesito 3 Iniziamo ad analizzare la prima funzione richiesta. Dovrà avere uno schema di questo tipo ACQUISIRE LA DATA 1 E LA DATA 2 CORPO DELLA FUNZIONE DOMANDE DI PROGRAMMAZIONE D1 Partendo da questo schema possiamo individuare i parametri essenziali per la nostra funzione... D2... e definire la struttura dati necessaria typedef struct int g, m, a; Data; 1 se la Data1 è precedente alla Data2 altrimenti 0 RESTITUIRE 1 SE DATA1<DATA2 ALTRIMENTI 0 int primadi(data d1, Data d2) // dichiarazione variabili,inizializzazione // CORPO FUNZIONE... Return (0 oppure 1); 38
Quesito 3 DOMANDE DI PROGRAMMAZIONE Analizziamo ora il corpo della funzione PrimaDi() CORPO DELLA FUNZIONE Se l anno della 1^ data è minore dell anno della 2^ data allora la 1^ data è sicuramente precedente altrimenti se gli anni delle due date coincidono if (d1.a < d2.a) return 1 else if (d1.a == d2.a) valuto il mese e se quello della 1^ data è inferiore a quello della 2^ data allora la 1^data è sicuramente precedente altrimenti se i mesi nelle due date coincidono valuto i giorni e se quelli della 1^ data sono inferiori a quelli della 2^ data allora la 1^ data è sicuramente precedente Ho considerato tutte le casistiche possibili per cui la 1^ data non è precedente alla 2^ data if (d1.m < d2.m) return 1; else if (d1.m == d2.m) return 0; if (d1.g < d2.g) return 1; 39
Quesito 3 DOMANDE DI PROGRAMMAZIONE Iniziamo ora ad analizzare la seconda funzione richiesta. ACQUISIRE LA DATA DI RIFERIMENTO, L ELENCO DELLE DATE E LA SUA NUMEROSITA Partendo da questo schema possiamo individuare i parametri essenziali per la nostra funzione... N CORPO DELLA FUNZIONE RESTITUIRE IL NUMERO DI DATE PRECEDENTI ALLA DATADI RIFERIMENTO Numero di date[] precedenti a una data di riferimento (quindi un int) int numprecedenze(data v[], int n, Data ref) // DICHIARAZIONE VARIABILI // CORPO DELLA FUNZIONE return prec; 40
Esercizio 6 Scrivere la dichiarazione C di un nuovo tipo di struttura dati che aggrega tre variabili intere che rappresentano rispettivamente l'ora, i minuti e i secondi di un determinato orario. Scrivere una funzione C che dati due orari produce 1 se il primo orario è inferiore al secondo, 0 altrimenti. Scrivere una seconda funzione C che, sfruttando la precedente funzione, restituisca il numero di orari di un dato vettore di n variabili di tipo orario che precedono un orario acquisito da tastiera. Analizziamo ora il corpo della funzione NumPrecedenze() Lo scorrimento degli elementi di un elenco richiede l uso di una variabile contatore int i; int numprecedenze(data v[], int n, Data ref) Inserisco le variabili e poi eventualmente le inizializzo int i; int prec=0; CORPO DELLA FUNZIONE Scorro l array v[] dal primo all ultimo elemento for (i=0 ; i < n ; i++) Se la data i esima v[i] è precedente alla data di riferimento incremento la variabile che conteggia il numero di date precedenti if (primadi(v[i], ref) == 1) prec = prec + 1 return prec; int prec; 41
Quesito 2 DOMANDE DI PROGRAMMAZIONE #include <stdio.h> typedef struct int g, m, a; Data; int primadi(data d1, Data d2) if (d1.a < d2.a) return 1; else if (d1.a == d2.a) if (d1.m < d2.m) return 1; else if (d1.m == d2.m) if (d1.g < d2.g) return 1; return 0; 42
Quesito 2 DOMANDE DI PROGRAMMAZIONE int numprecedenze(data v[], int n, Data ref) int i, prec = 0; for (i = 0; i < n; i++) if (primadi(v[i], ref) == 1) prec = prec + 1; return prec; int main(void) Data vett[10]; int i; for (i = 0; i < 10; i++) scanf("%d/%d/%d", &vett[i].g, &vett[i].m, &vett[i].a); printf("%d\n", numprecedenze(vett, 9, vett[9])); return 0; 43
DOMANDE RISPOSTE APERTE ULTERIORI ESEMPI FLOW CHART Quesito 1: Visualizzare in una sequenza di 10 orari quello più vicino a mezzogiorno. L orario è costituito dalla coppia hh.mm Quesito 2: Indicare se una matrice NxN di numeri è simmetrica (ovvero se è uguale alla sua trasposta). (2 cicli annidati). Si supponga che l esecutore sia in grado di interpretare le operazioni riguardanti l acquisizione di una intera matrice NxN (usare un blocco sottoprogramma). 44
DOMANDE RISPOSTE APERTE Quesito 1: Visualizzare in una sequenza di 10 orari quello più vicino a mezzogiorno. L orario è costituito dalla coppia hh.mm Inizialmente la parte di inizializzazione sembra superflua. Scrivendo la soluzione su carta conviene comunque lasciare dello spazio per questa sezione Leggo per 10 volte degli orari nella forma hh:mm Lasciamo, visto che si scrive su carta, uno spazio sufficiente a contenere la parte iterata, Parte iterata Alcuni passaggi possono essere «formalizzati» immediatamente nel simbolismo visto per i flow chart. Altri invece necessitano di un ulteriore approfondimento che andremo via via ad analizzare 45
Quesito 1 DOMANDE RISPOSTE APERTE Visualizzare in una sequenza di 10 orari quello più vicino a mezzogiorno. L orario è costituito dalla coppia hh.mm (1 singolo ciclo) HH N MM N Valuto se è il più vicino alle 12:00 fino a quel momento NO HH N >=12 SI differenza=(12 HH N )*60 MM N differenza=(hh N 12)*60+MM N NO differenza<diff_minima SI diff_minima=differenza HH min =HH N MM min =MM N Per valutare l orario più vicino alle 12.00 devo sapere quale è la differenza minima (diff_minima) riscontrata nei precedenti orari HH min MM min 46
Quesito 1 DOMANDE RISPOSTE APERTE Visualizzare in una sequenza di 10 orari quello più vicino a mezzogiorno. L orario è costituito dalla coppia hh.mm (1 singolo ciclo) Parte iterata ma il primo orario letto con quale diff_minima deve essere messo a confronto? All inizio devo impostare la variabile diff_minima con la massima differenza possibile ovvero 12*60+1. Questo assegnamento va posto nel blocco relativo all inizializzazione dell algoritmo. diff_minima=12*60+1 47
Per ottimizzare la disposizione dei blocchi su un foglio di carta è consigliabile disporre gli elementi del flow chart seguendo una disposizione spaziale che dia ampio spazio alla «parte iterata» che solitamente risulta essere quella più articolata. 48
DOMANDE RISPOSTE APERTE Quesito 1 Seguendo la disposizione spaziale consigliata otteniamo la soluzione finale Visualizzare in una sequenza di 10 orari quello più vicino a mezzogiorno. L orario è costituito dalla coppia hh.mm (1 singolo ciclo) 49
DOMANDE RISPOSTE APERTE Quesito 2: Indicare se una matrice NxN di numeri è simmetrica (ovvero se è uguale alla sua trasposta). (2 cicli annidati). Si supponga che l esecutore sia in grado di interpretare le operazioni riguardanti l acquisizione di una intera matrice NxN (usare un blocco sottoprogramma). Inizialmente la parte di inizializzazione sembra superflua. Scrivendo la soluzione su carta conviene comunque lasciare dello spazio per questa sezione Loop interno Loop esterno Scorro per N volte le righe della matrice Alcuni passaggi possono essere «formalizzati» immediatamente nel simbolismo visto per i flow chart. Altri invece necessitano di un ulteriore approfondimento che andremo via via ad analizzare Lascio in sospeso l output del nostro algoritmo Per ogni r-esima riga scorro per N volte le colonne della matrice 50
DOMANDE RISPOSTE APERTE Quesito 2 Sostituiamo i blocchetti contenenti la «descrizione informale» Ipotizzo inizialmente che la Simmetrica=1 mia matrice sia simmetrica 3 Indicare se una matrice NxN di numeri è simmetrica ovvero è uguale alla sua trasposta. (2 cicli annidati) appena un elemento della matrice risulta diverso dal suo corrispondente trasposto la matrice non sarà più simmetrica! Valuto se l elemento M[R,C]!=M[C,R] e se si allora la matrice M non è simmetrica 12 M R,C!= M R,C NO SI Simmetrica=0 Enuncio se la matrice è simmetrica oppure no NO Simmetrica==1 SI 1 «Non è simmetrica» «E simmetrica» 51
Quesito 2 DOMANDE RISPOSTE APERTE Indicare se una matrice NxN di numeri è simmetrica ovvero è uguale alla sua trasposta. (2 cicli annidati) Effettuando le opportune sostituzioni otteniamo la seguente soluzione 52
Per ottimizzare la disposizione dei blocchi su un foglio di carta è consigliabile disporre gli elementi del flow chart seguendo una disposizione spaziale che dia ampio spazio alla «parte iterata» che solitamente risulta essere quella più articolata. Parte iterata esterna 53
Quesito 2 Seguendo la disposizione spaziale consigliata otteniamo la soluzione finale DOMANDE RISPOSTE APERTE Indicare se una matrice NxN di numeri è simmetrica ovvero è uguale alla sua trasposta. (2 cicli annidati) 54
DOMANDE RISPOSTE APERTE Quesito 3: Indicare i bit di segno, mantissa ed esponente della codifica del numero -0.3203125 in notazione scientifica normalizzata a base 2, definita utilizzando 8 bit per la mantissa, 4 bit per l esponente e codificando l esponente in complemento a 2. Negativo segno 1-0. 3203125 La mantissa è di 8 per cui arrivo alla settima cifra Codifica di 0 0 (1 bit) Normalizzo la rappresentazione 0. 0101001 0001 Mantissa 0.10100100 x 2-1 Complemento i singoli bit Aggiungo 1 1110 Esponente 1111 55
DOMANDE RISPOSTE APERTE Quesito 4: Si supponga che la memoria centrale del calcolatore contenga 3 processi P1, P2 e P3; -I 3 processi siano inizialmente in stato pronto e siano ordinati nel seguente modo nella coda: P1, P2, P3 ; -Il quanto di tempo della CPU sia di 10 msec; -Il processo P1 esegua una operazione di output che dura 7 msec dopo essere stato in esecuzione per 1msec e questo per 2 volte; -P2 esegua un operazione di input che dura 17msec dopo 5 msec di esecuzione; -P3 non esegua operazioni di I/O; -il tempo di esecuzione complessivo richiesto da ogni processo è rispettivamente: 4 msec. P1-10 msec. P2 e 20 msec. P3 Utilizzando un Gantt Chart si indichi per ogni processo quando e quali stati assume prima di terminare. 56
DOMANDE RISPOSTE APERTE Quesito 5 Si consideri un calcolatore con un banco di 16 registri ad uso generico, parole di memoria di 16 bit ed istruzioni del linguaggio macchina con 4 bit di codice operativo. Scrivere il programma Assembly che moltiplica due numeri naturali positivi presenti in un area contigua della memoria centrale a partire dall indirizzo 200. Supponiamo che ciascun naturale sia codificato con 2 byte e che il risultato venga scritto nell area di memoria con indirizzo uguale a 300. È consentito l uso delle seguenti istruzioni Assembly. 57
Quesito 5 DOMANDE RISPOSTE APERTE LOAD R2 LOAD R3 Moltiplico R2 * R3 STORE R4 58
Quesito 5 DOMANDE RISPOSTE APERTE La sequenza dei passaggi che il nostro programma deve svolgere è la seguente: Imposto la posizione del primo fattore (200 in R1) Leggo il contenuto indicato in R1 e lo sistemo nel registro R2 Imposto la posizione del secondo fattore (202 in R1) Leggo il contenuto indicato in R1 e lo sistemo nel registro R3 Calcolo il prodotto tra R3 e R2 e lo riverso in R4 LOADiL R1 11001000 LOADiH R1 00000000 LOAD R2 R1 ; R2 M[R1] LOADiL R1 11001010 LOADiH R1 00000000 LOAD R3 R1 ; R3 M[R1] Imposto la posizione in ram del risultato (300 in R1) Scrivo il nuovo contenuto di R4 nella cella di memoria indicata da R1 FINE END LOADiL R1 00101100 LOADiH R1 00000001 STORE R1 R4 ; M[R1] R4 59
Quesito 5 DOMANDE RISPOSTE APERTE Non avendo a disposizione l istruzione relativa al prodotto posso sostituirla con una somma multipla. In altre parole per implementare il prodotto M x N Rappresenta il prodotto P Rappresenta M Rappresenta N R4 R2 R3 sommo M volte il valore N Rappresenta M R2 R4 R3 R5 1 Rappresenta N 60
Quesito 5 DOMANDE RISPOSTE APERTE Quindi per implementare il prodotto MxN (R2xR3) posso inizializzare un registro (esempio R4) con il valore 0 e successivamente, per M (R2) volte, aggiungere a R4 il valore N (R3). Per conteggiare il numero di somme multiple effettuate avrò bisogno di un ulteriore registro (R5). Sommo ripetutamente a 3 R4 il contenuto di R3 (N) 0 R2 1 2 M-1 0 5 R4 R3 3 Primo fattore M Secondo fattore N Rappresenta il risultato 0 1 Ad ogni somma incremento R5 R5 e solo quando diventa uguale a M 1 (R2) smetto Rappresenta il contatore 4 61
Quesito 5 DOMANDE RISPOSTE APERTE Calcolo il prodotto tra R3 e R2 e lo riverso in R4 Parto da 0 poiché l istruzione di salto è basata sull operatore di confronto «minore» 1 Imposto a 0 il registro contatore R5 LOADiL R5 00000000 LOADiH R5 00000000 Azzero il registro (R4) che conterrà il risultato LOADiL R4 00000000 2 LOADiH R4 00000000 Sommo il contenuto del registro R3 al contenuto 3 CICLO: del registro risultato R4 ADD R4 R4 R3 4 Incremento il contatore R5 di 1 (R1) ADD R5 R5 0001 SI Non ho finito? (R5<R2) NO BLT R5 R2 CICLO ;(4) 62
Quesito 5 DOMANDE RISPOSTE APERTE LOADiL R1 11001000 ; indirizzo 1^ fattore M LOADiH R1 00000000 LOAD R2 R1 ; R2 M[R1] LOADiL R1 11001010 ; indirizzo 2^ fattore N LOADiH R1 00000000 LOAD R3 R1 ; R3 M[R1] LOADiL R4 00000000 ; azzero il risultato LOADiH R4 00000000 LOADiL R5 00000000 ; contatore LOADiH R5 00000000 CICLO: ADD R4 R4 R3 ADD R5 R5 0001 ; incremento contatore BLT R5 R2 CICLO LOADiL R1 00101100 LOADiH R1 00000001 STORE R1 R4 ; M[R1] R4 END Indirizzo 1^ fattore 2^ fattore risultato contatore R1= R2=3 R3=5 R4= R5= 63
Quesito 5 Calcolo il prodotto tra R3 e R2 e lo riverso in R4 DOMANDE RISPOSTE APERTE Se N o M possono essere nulli il programma deve essere modificato in questo modo 1 2 Imposto a 0 il registro contatore R5 Azzero il registro (R4) che conterrà il risultato Non ho finito? (R5<R2) SI Sommo il contenuto del registro R3 al contenuto del registro risultato R4 NO LOADiL R5 00000000 LOADiH R5 00000000 LOADiL R4 00000000 LOADiH R4 00000000 INIZIO: BLT R5 R2 CICLO B FINE 3 CICLO: ADD R4 R4 R3 Incremento il contatore R5 di 1 (R1) 4 ADD R5 R5 0001 B INIZIO FINE FINE: END 64
DOMANDE PROGRAMMAZIONE Quesito 1: Visualizzare il numero di una sequenza di 10 numeri naturali che risulti più vicino alla loro media. Per svolgere questo compito si definisca ed utilizzi una funzione che dato un elenco di valori restituisca tale valore. 65
Quesito 1 Il funzione C che dovremo implementare sarà caratterizzata da una struttura di questo tipo: DOMANDE DI PROGRAMMAZIONE Partendo da questo schema possiamo individuare i parametri essenziali per la nostra funzione ACQUISIRE L ELENCO DI VALORI IN UN VETTORE X[] E LA SUA DIMENSIONE N N CORPO DELLA FUNZIONE RESTITUIRE IL VALORE PIU VICINO ALLA MEDIA Numero di X[i] più vicino alla media (quindi un double) double NrPiuVicinoAllaMedia(double X[], int n) // dichiarazione variabili,inizializzazione // CORPO FUNZIONE... return piuvicino; 66
Quesito 1 DOMANDE DI PROGRAMMAZIONE Continuiamo ad analizzare il corpo della nostra funzione CALCOLO LA MEDIA SCORRO L ELENCO DEI VALORI, CALCOLO LA DIFFERENZA E LOCALIZZO L ELEMENTO PIU VICINO NrPiuVicinoAllaMedia(double X[], int n) // dichiarazione variabili,inizializzazione double media, piuvicino, distanzaminima; int i; // CORPO FUNZIONE... // A) Calcolo la media media=0; for (i=0; i<n ; i++) media=media+x[i]; media=media/n; // B) Calcolo il valore + vicino piuvicino=x[0]; distanzaminima=fabs(x[0]-media); for (i=1 ; i<n ; i++) if (fabs(x[i]-media)<distanzaminima) piuvicino=x[i]; distanzaminima=fabs(x[i]-media); // Restituzione risultati return piuvicino; 67
Quesito 1 DOMANDE DI PROGRAMMAZIONE Scriviamo quindi il corpo della nostra funzione. double NrPiuVicinoAllaMedia(double X[], int n) // Dichiarazione delle variabili /inizializzazione double media =0, piuvicino=x[0], distanzaminima; int i; // Corpo della funzione // A) Calcolo la media for (i=0; i<n ; i++) media=media+x[i]; media=media/n; printf("la media e': %.2f",media); // B) Calcolo il valore + vicino distanzaminima=fabs(x[0]-media); for (i=1 ; i<n ; i++) if (fabs(x[i]-media)<distanzaminima) piuvicino=x[i]; distanzaminima=fabs(x[i]-media); // Restituzione risultato return piuvicino; 68
Quesito 1 DOMANDE DI PROGRAMMAZIONE Se si volesse poi testare la funzione appena prodotta possiamo inserirla all interno del seguente programma C. #include <stdio.h> #include <math.h> #define N 5 double NrPiuVicinoAllaMedia(double X[], int n) // Dichiarazione delle variabili /inizializzazione double media =0, piuvicino=x[0], distanzaminima; int i; // Corpo della funzione // A) Calcolo la media for (i=0; i<n ; i++) media=media+x[i]; media=media/n; printf("la media e': %.2f",media); // B) Calcolo il valore + vicino distanzaminima=fabs(x[0]-media); for (i=1 ; i<n ; i++) if (fabs(x[i]-media)<distanzaminima) piuvicino=x[i]; distanzaminima=fabs(x[i]-media); // Restituzione risultato return piuvicino; int main() double X[N]=3, 7.3, 8.23, 3, 23.1; double risultato=nrpiuvicinoallamedia(x,n); printf("il valore + vicino alla media e': %.2f",risultato); 69
DOMANDE PROGRAMMAZIONE Quesito 2: Acquisire un elenco di 10 numeri naturali e successivamente restituirne la «moda» (il valore più frequente). Per svolgere questo compito si definisca ed utilizzi una funzione che dato vettore di n variabili intere visualizzi l elemento più frequente 70
Quesito 2 La funzione C che dovremo implementare sarà caratterizzata da una struttura di questo tipo: DOMANDE DI PROGRAMMAZIONE Partendo da questo schema possiamo individuare i parametri essenziali per la nostra funzione ACQUISIRE IL VETTORE X[] E LA SUA DIMENSIONE N N CORPO DELLA FUNZIONE (DOPPIO CICLO) Numero di X[i] più frequente (quindi un int) MOSTRO IL VALORE PIU FREQUENTE (MODA) int EstraiLaModa(int X[], int n) // dichiarazione variabili,inizializzazione // CORPO FUNZIONE... Return moda; 71
Quesito 2 DOMANDE DI PROGRAMMAZIONE Il corpo della nostra funzione potrebbe implementare il seguente algoritmo: Lo scorrimento degli elementi di un elenco richiede l uso di una variabile contatore Scorro l array originale X[] e ricopio i valori, eliminando i duplicati, nell array Distinto[] Mi serve una variabile per il conteggio dei numeri distinti Se X[i] è la prima occorrenza in Distinti[j] VERO 1 Contemporaneamente per ogni valore distinto Distinti[j] conteggio il numero di occorrenze in Conta[j] FALSO Se è una successiva occorrenza del numero incremento di 1 il conteggio 72
Quesito 2 Scriviamo il corpo della nostra funzione DOMANDE DI PROGRAMMAZIONE Man mano servono dichiaro le singole variabili bool ENuovo; int i, j; int Conta[N]=0, maxconta; int Distinti[N]=0; int ndistinti=0; // A - Conteggio la frequenza di ogni numero for (i=0 ; i<n ; i++) ENuovo=true; // ipotizzo che sia un nuovo valore for (j=0 ; j<ndistinti ; j++) if (X[i]==Distinti[j]) Conta[j]++; ENuovo=false; break; if (ENuovo==true) Distinti[nDistinti]=X[i]; Conta[nDistinti]++; ndistinti++; SCORRO L ELENCO DAL PRIMO ALL ULTIMO ELEMENTO X i DEL VETTORE X[] ED ESTRAGGO LE SINGOLE OCCORRENZE E CONTEMPORANEAME NE CONTEGGIO LE ISTANZE.. 73
Quesito 2 DOMANDE DI PROGRAMMAZIONE Scriviamo il corpo della nostra funzione Man mano servono aggiungo ulteriori variabili int Moda; int maxconta; // B - Determinazione del nr + frequente maxconta=conta[0]; Moda=Distinti[0]; for (j=1; j<ndistinti ; j++) if (maxconta < Conta[j]) maxconta=conta[j]; Moda=Distinti[j]; POI SCORRO L ARRAY DEI CONTEGGI CONTA[] ALLA RICERCA DEL VALORE IN DISTINTI[] PIU FREQUENTE 74
Quesito 2 DOMANDE DI PROGRAMMAZIONE Scriviamo quindi il corpo della nostra funzione. int EstraiLaModa(int X[], int n) // Dichiarazione variabili/inizializzazione bool ENuovo; int Moda,i, j; int Conta[N]=0, maxconta; int Distinti[N]=0; int ndistinti=0; // Corpo funzione // A - Conteggio la frequenza di ogni numero for (i=0 ; i<n ; i++) ENuovo=true; // ipotizzo che sia un nuovo valore for (j=0 ; j<ndistinti ; j++) if (X[i]==Distinti[j]) Conta[j]++; ENuovo=false; break; if (ENuovo==true) Distinti[nDistinti]=X[i]; Conta[nDistinti]++; ndistinti++; // Determinazione del nr + frequente maxconta=conta[0]; Moda=Distinti[0]; for (j=1; j<ndistinti ; j++) if (maxconta < Conta[j]) maxconta=conta[j]; Moda=Distinti[j]; // Restituzione del valore return Moda; 75
DOMANDE PROGRAMMAZIONE Quesito 3: Acquisire da tastiera 10 orari e successivamente visualizzare il numero di secondi trascorsi tra l orario minore e quello maggiore. Per svolgere questo compito si dichiari una nuova tipologia di dati adatta ai fini dell esercizio e si definisca ed utilizzi due funzioni C con le seguenti finalità: Produrre il numero di secondi trascorsi dall inizio della giornata dell orario passato come argomento. Produrre la durata della fascia temporale in secondi occupata dall elenco di orari registrati in un determinato vettore di n variabili di tipo orario 76
Quesito 3 DOMANDE DI PROGRAMMAZIONE #include <stdio.h> #define N 5 typedef struct int ora; int minuti; int secondi; torario; void StampaOrario(tOrario O) printf("%2d:%2d:%2d",o.ora,o.minuti,o.secondi); // ------------------------------------------------------------ int SecondiTrascorsi(tOrario A) int tseca; tseca=a.ora*60*60+a.minuti*60+a.secondi; return tseca; 77
Quesito 3 DOMANDE DI PROGRAMMAZIONE int DurataFasciaOrariaOccupata(tOrario Orari[], int n) // Devo determinare il minimo e il massimo orario torario vmin,vmax; int tsecmax, tsecmin, tsec, i; // Inizializzazione tsecmin=seconditrascorsi(orari[0]); tsecmax=seconditrascorsi(orari[0]); vmin=orari[0]; vmax=orari[0]; for (i=1 ; i < n ; i++) tsec=seconditrascorsi(orari[i]); if (tsec < tsecmin) tsecmin=tsec; vmin=orari[i]; if (tsec > tsecmax) tsecmax=tsec; vmax=orari[i]; printf("fascia considerata: "); StampaOrario(vMin); printf(" - "); StampaOrario(vMax); printf("\n"); // Calcolo la differenza in secondi tra l'orario minimo // e quello massimo tsec=seconditrascorsi(vmax)-seconditrascorsi(vmin); return tsec; 78
Quesito 3 DOMANDE DI PROGRAMMAZIONE int main() torario Orario; torario Orari[N] = 21, 56, 18, 14, 2, 13, 14, 2, 58, 21, 46, 58, 9, 14, 59 ; printf("la fascia oraria occupata dagli orari dura %d secondi",duratafasciaorariaoccupata(orari,n)); return(0); 79
Docente: A. Elementi di Informatica e Programmazione 80
R5 D1 81
82