Esercitazioni di Fondamenti di Informatica - Lez. 30/10/018 Esercizi sulle funzioni in C I codici e le soluzioni degli esercizi sono nella cartella parte1 1. Scrivere i prototipi delle seguenti funzioni. funzione ipotenusa riceve due argomenti in virgola mobile in doppia precisione e ritorna un risultato in doppia precisione. funzione minoreditre che riceve tre argomenti interi e ritorna il valore del minore. funzione istruzioni che non ha parametri in ingresso e non ha parametri in uscita. funzione convertifloatintero che riceve un argomento float e ritorna in uscita il valore intero piú vicino. Soluzione: 0 double i p o t e n u s a ( double lato1, double l a t o ) 1 int m i n o r e d i t r e ( int a, int b, int c ) ; void i s t r u z i o n i ( void ) ; /* anche void istruzioni () sarebbe valido */ 3 int c o n v e r t i F l o a t I n t e r o ( float Numero Float ) ;. Scrivere una funzione in grado di scambiare il contenuto di due variabili intere passate come parametri Se ho le variabili intere a = 1 e b =, chiamando una funzione scambiainteri(a,b) le variabili avranno valore scambiato a = e b = 1. Soluzione: 1 void s c a m b i a I n t e r i ( int p1, int p ) ; 3 4 int main ( ) { 6 7 int n1, n ; 8 9 /* Inserisco i due valori */ 10 s c a n f ( "%d",&n1 ) ; 11 s c a n f ( "%d",&n ) ; 1 13 /* e li stampo */ 14 p r i n t f ( "n1=%d n=%d\n", n1, n ) ; 1 16 /* chiamo la funzione scambiainteri e scambio i valori 18 N.B. i valori di n1 ed n sono 19 passati per indirizzo 0 */ 1 s c a m b i a I n t e r i (&n1,&n ) ; 3 4 /* stampo di nuovo i contenuti di n1 e n */
6 p r i n t f ( "n1=%d n=%d\n", n1, n ) ; 7 8 } 9 30 31 3 void s c a m b i a I n t e r i ( int p1, int p ){ 33 34 int tmp ; /* variabile temporanea */ 3 36 tmp = p1 ; 37 p1= p ; 38 p=tmp ; 39 } 3. Trova gli errori nel seguente codice per il calcolo del massimo di una sequenza di interi. Soluzione: 1 3 void calcolamassimo ( int numeri [ ], int LUN) ; 4 int main ( ) { 6 7 int LUN = 1 0 ; 8 9 int numeri [ 1 0 ] = {, 3, 4,, 6, 4 1, 3,, 1, 4 } ; 10 int massimo ; 11 1 massimo = calcolamassimo ( numeri,lun) ; 13 p r i n t f ( "massimo -> %d\n", massimo ) ; 14 1 } 16 18 void calcolamassimo ( int numeri [ ], int LUN){ 19 0 int massimo ; 1 int i ; 3 massimo = numeri [ 0 ] ; 4 for ( i =0; i <LUN; i ++){ if ( massimo == numeri [ i ] ) { 6 massimo = numeri [ i ] ; 7 } 8 } 9 } Oltre alla condizione sbagliata per l aggiornamento del valore massimo, la funzione non ritorna il valore massimo ritornato. Per questa secondo errore ci sono due possibili soluzioni: dovendo ritornare un solo valore intero, posso modificare il valore di ritorno da void a int e ritornare il massimo con return(massimo). Il codice risultante sarebbe: 1 3 int calcolamassimo ( int numeri [ ], int LUN) ;
4 int main ( ) { 6 7 int LUN = 1 0 ; 8 9 int numeri [ 1 0 ] = {, 3, 4,, 6, 4 1, 3,, 1, 4 } ; 10 int massimo ; 11 1 massimo = calcolamassimo ( numeri,lun) ; 13 14 p r i n t f ( "massimo -> %d\n", massimo ) ; 1 16 } 18 19 0 int calcolamassimo ( int numeri [ ], int LUN){ 1 int massimo ; 3 int i ; 4 massimo = numeri [ 0 ] ; 6 for ( i =0; i <LUN; i ++){ 7 if ( massimo < numeri [ i ] ) { 8 massimo = numeri [ i ] ; 9 } 30 } 31 return massimo ; 3 } Oppure posso passare una variabile massimo per riferimento e modificarla senza dichiarare una nuova variabile. La soluzione sarebbe: 1 void calcolamassimo ( int numeri [ ], int LUN, int massimo ) ; 3 4 int main ( ) { 6 int LUN = 1 0 ; 7 8 int numeri [ 1 0 ] = {, 3, 4,, 6, 4 1, 3,, 1, 4 } ; 9 int massimo ; 10 11 1 calcolamassimo ( numeri,lun,&massimo ) ; 13 14 p r i n t f ( "massimo -> %d\n", massimo ) ; 1 } 16 18 void calcolamassimo ( int numeri [ ], int LUN, int massimo ){ 19 0 int i ; 1 int temp ; massimo = numeri [ 0 ] ; 3 for ( i =0; i <LUN; i ++){ 4 if ( massimo < numeri [ i ] ) { massimo = numeri [ i ] ;
6 } 7 } 8 9 } 4. Scrivere il codice che, data una sequenza di numeri interi, calcoli la media dei valori attraverso una chiamata di funzione. Soluzione: 1 #d e f i n e MAX 3 float calcolamedia ( int sequenza, int n ) ; 4 6 int main ( ) { 7 8 int a [MAX] ; 9 10 p r i n t f ( "\ ninserisci numeri interi e premi invio: \n" ) ; 11 s c a n f ( "%d %d %d %d %d",&a [ 0 ], & a [ 1 ], & a [ ], & a [ 3 ], & a [ 4 ] ) ; 1 13 float media = calcolamedia ( a,max) ; 14 p r i n t f ( "\nmedia = %f\n", media ) ; 1 16 18 } 19 0 1 float calcolamedia ( int sequenza, int n ){ 3 /* gli array sono sempre copiati per riferimento, 4 devo quindi passare anche il numero di elementi della sequenza */ 6 7 float media = 0 ; 8 for ( int i =0; i <n ; i ++){ 9 media += sequenza [ i ] ; 30 } 31 media = media/n ; 3 return media ; 33 }. Scrivere una funzione che, data una sequenza di numeri interi e un numero intero A, ritorni due elementi: un booleano che indichi se A é presente nella sequenza di numeri e l indice in cui A si trova nella sequenza (o il valore -1 se non é nella sequenza). Soluzione: 0 i nclude <s t d i o. h> 1 #d e f i n e MAXLEN 3 4 /* definiamo il tipo booleano bool */ 6 typedef enum {FALSE=0,TRUE=1} b o o l ; 7
8 /* la funzione cercaintero vuole in input: 9 10 - array di interi in cui cercare 11 - lunghezza dell array di interi 1 -il numero da cercare 13 -la variabile dove salvare l indice 14 */ 1 16 bool c e r c a I n t e r o ( int sequenza, int len, int n, int i n d i c e n ) ; 18 /* scrivo anche una procedura utile per stampare il 19 risultato della funzione cercaintero 0 */ 1 void p r i n t C e r c a I n t e r o ( int sequenza, int len, int n ) ; 3 4 int main ( ) { 6 7 int sequenza [MAXLEN] ={1,,3,4,}; 8 9 int A=; 30 p r i n t C e r c a I n t e r o ( sequenza,maxlen,a) ; 31 A=6; 3 p r i n t C e r c a I n t e r o ( sequenza,maxlen,a) ; 33 34 } 3 36 bool c e r c a I n t e r o ( int sequenza, int len, int n, int i n d i c e n ){ 37 38 bool t r o v a t o = FALSE; 39 i n d i c e n = 1; 40 41 for ( int i =0; i < l e n ; i ++){ 4 if ( sequenza [ i ]==n ){ 43 i n d i c e n = i ; 44 t r o v a t o = TRUE; 4 break ; 46 } 47 } 48 return t r o v a t o ; 49 } 0 1 void p r i n t C e r c a I n t e r o ( int sequenza, int len, int n ){ 3 int i n d i c e ; 4 if ( c e r c a I n t e r o ( sequenza, len, n,& i n d i c e ) ) { p r i n t f ( "Il valore %d si trova nella sequenza 6 in indice %d\n", n, i n d i c e ) ; 7 8 } 9 else{ 60 p r i n t f ( "Il valore %d non si trova nella sequenza \n", n ) ; 61 } 6 } 6. Dato un oggetto di tipo Libreria definito attraverso la seguente struttura dati: 0 typedef struct {
1 char nome [ STRLEN] ; double c o s t o ; 3 int g i a c e n z a ; /* numero di copie presenti */ 4 } Libro ; 6 typedef Libro L i b r e r i a [NUMLIBRO] ; Scrivere una funzione che, dato il nome di un libro: controlla se é nella libreria, controlla se ci sono abbastanza copie e se ci sono ancora copie presenti, vende il libro diminuendo il numero di copie presenti e aggiornando un valore di cassa con il prezzo del libro. Suggerimento: per controllare se il libro é presente in libreria tramite il nome, si devono compare le due stringhe dei nomi: questo é possibile velocemente tramite la funzione strcomp nella libreria <string.h>. 1 #include <s t r i n g. h> 3 #d e f i n e NUMLIBRO 3 4 #d e f i n e STRLEN 30 6 typedef struct { 7 char nome [STRLEN ] ; 8 double c o s t o ; 9 int g i a c e n z a ; 10 } Libro ; 11 1 typedef Libro L i b r e r i a [NUMLIBRO ] ; 13 typedef enum {FALSE=0,TRUE=1} b o o l ; 14 1 L i b r e r i a l i b r e r i a ={ 16 {" Informatica \0", 1 0. 0, 3 }, {" Matematica \0", 0. 0, }, 18 {" Statistica \0",. 0, } 19 } ; 0 1 double c a s s a = 0. 0 ; 3 void librocomprato ( char nome ) ; 4 6 int main ( ) { 7 8 char nome [ STRLEN] = " Informatica \0" ; 9 30 librocomprato (nome ) ; 31 librocomprato (nome ) ; 3 librocomprato (nome ) ; 33 librocomprato (nome ) ; 34 3 p r i n t f ( "In cassa hai %f euro\n", c a s s a ) ; 36 37 } 38 39 40 41 void librocomprato ( char nome){ 4 43 /* variabile che indica se
44 il libro e nella libreria 4 inizializzata a FALSE */ 46 47 bool t r o v a t o = FALSE; 48 49 for ( int i =0; i <NUMLIBRO; i ++){ 0 1 /* compariamo i nomi dei libri */ /* strcmp compara due stringhe 3 se sono uguali ritorna 0 */ 4 if ( strcmp ( l i b r e r i a [ i ]. nome, nome)==0){ 6 t r o v a t o = TRUE; 7 8 /* guardiamo se il libro e disponibile */ 9 if ( l i b r e r i a [ i ]. g i a c e n z a > 0){ 60 p r i n t f ( "Hai venduto %s con prezzo %f\n", 61 nome, l i b r e r i a [ i ]. c o s t o ) ; 6 c a s s a += l i b r e r i a [ i ]. c o s t o ; 63 l i b r e r i a [ i ]. giacenza ; 64 } 6 else{ 66 p r i n t f ( "Libro non in giacenza \n" ) ; 67 } 68 break ; 69 } 70 } 71 if ( t r o v a t o == FALSE){ 7 p r i n t f ( "Libro non trovato.\n" ) ; 73 } 74 7 76 77 } 7. tratto dall ESAME 10/09/01: Scrivere in C una funzione, senza parametri e che non restituisce nulla, che legge una sequenza di numeri terminata dallo 0. La funzione deve considerare solo i valori dei numeri letti che sono multipli di 3, calcolarne la mediana (non la media) e stamparne a video il valore. Si ricorda che la mediana di una sequenza ordinata di numeri interi é il valore centrale, se la sequenza ha cardinalitá dispari, oppure la media tra i due numeri centrali, se la cardinalitá é pari. 1 #d e f i n e DIM 100 3 void ordina ( int a [ ], int d ) ; 4 void stampamediana ( void ) ; 6 int main ( ) { 7 stampamediana ( ) ; 8 9 } 10 11 1 void swap ( int a [ ], int i, int j ){ 13 int temp ; 14 temp = a [ i ] ; 1 a [ i ] = a [ j ] ;
16 a [ j ]=temp ; } 18 19 /* ordina un array dal minore al maggiore */ 0 void ordina ( int a [ ], int d ){ 1 int i, j, t ; 3 4 for ( i =0; i <d ; i ++){ for ( j=i +1; j<d ; j ++){ 6 if ( a [ i ]>a [ j ] ) { 7 swap ( a, i, j ) ; 8 } 9 } 30 } 31 3 } 33 34 void stampamediana ( ) { 3 36 int n=1,d=0; 37 int a [DIM ] ; 38 float t1, t, med ; 39 40 while ( n!=0 && n!=(dim 1)){ 41 p r i n t f ( " Inserisci numero: \n" ) ; 4 s c a n f ( "%d",&n ) ; 43 if ( ( n!=0) && ( n%3 == 0 ) ) { 44 a [ d++] = n ; 4 } 46 } 47 48 /* a questo punto i e uguale alla 49 lunghezza dell array */ 0 1 ordina ( a, d ) ; 3 4 t1 = a [ ( d /) 1]; 6 t = a [ d / ] ; 7 8 9 if ( d% == 0){ 60 med = ( t1+t ) / ; 61 } 6 else{ 63 med = t ; 64 } 6 p r i n t f ( "La mediana e : %.f\n",med ) ; 66 67 } 8. ESAME 8/11/013: Dichiarare in C una struttura per memorizzare la carriera universitaria di uno studente. Ovvero, la struttura deve consentire la memorizzazione del nome e cognome dello studente, la sua matricola, i voti riportati nei 30 esami da sostenere per conseguire la laurea e la media pesata, aggiornata dopo l aggiunta di ogni esame. La media é pesata perche ogni esame puo valere 3,, 8, 10 o 1 crediti e la media deve tenere conto del peso del singolo esame.
Scrivere anche una funzione che prende come parametro la struttura dati relativa ad uno studente, consente l inserimento dei dati relativi ad un esame, aggiorna la media e restituisce la struttura dati aggiornata. Soluzione: 1 #d e f i n e DIM 0 / lunghezza max campi t e s t u a l i / 3 #d e f i n e MATR 6 / lunghezza max m a t r i c o l a / 4 #d e f i n e ESAMI 30 / numero massimo esami / 6 7 typedef char S t r i n g a [DIM ] ; 8 typedef char Matricola [MATR] ; 9 10 /* struct per la definizione di un esame */ 11 typedef struct { 1 int voto ; 13 int c r e d i t i ; 14 }Esame ; 1 16 /* struct per la definizione di uno studente */ 18 typedef struct { 19 0 S t r i n g a nome ; 1 S t r i n g a cognome ; Matricola m a t r i c o l a ; 3 Esame v o t i [ESAMI ] ; 4 int esami ; float media ; 6 } Studente ; 7 8 9 void i n s e r i s c i E s a m e ( Studente s, Esame e ) ; 30 31 int main ( ) { 3 33 Studente studente ={"Mario", "Rossi", "13 ABC" } ; 34 3 Esame esami []= {{,}, 36 {30,10} 37 } ; 38 39 i n s e r i s c i E s a m e (&studente, esami [ 0 ] ) ; 40 i n s e r i s c i E s a m e (&studente, esami [ 1 ] ) ; 41 4 p r i n t f ( "\n Media esami: %f\n", studente. media ) ; 43 44 4 } 46 47 48 void i n s e r i s c i E s a m e ( Studente s, Esame e ){ 49 0 int i, c = 0 ; 1 float v = 0. 0 ; 3 /* aggiornamento nuovo esame */
4 ( s >v o t i [ s >esami ] ). voto = e. voto ; ( s >v o t i [ s >esami ] ). c r e d i t i = e. c r e d i t i ; 6 ( s >esami )++; 7 8 for ( i =0; i <s >esami ; i ++){ 9 v+=((s >v o t i ) [ i ]. voto ( s >v o t i ) [ i ]. c r e d i t i ) ; 60 c+=(s >v o t i ) [ i ]. c r e d i t i ; 61 } 6 s >media = v/ c ; 63 } 9. ESAME 31/08/0: Scrivere in C una funzione ed un programma principale: La funzione prende in ingresso una stringa e restituisce, nel modo che si ritiene piú opportuno, tre valori diversi: la lunghezza della stringa, il numero di vocali contenute e la somma della codifica ASCII dei suoi caratteri. Il programma principale deve chiedere all utente di inserire una stringa, invocare la funzione definita al punto precedente, usando la stringa inserita, e stampare i risultati restituiti in modo appropriato. Soluzione 1: 1 #include <s t r i n g. h> 3 #d e f i n e MAX L 30 / lunghezza massima s t r i n g a / 4 typedef enum {FALSE,TRUE} b o o l ; 6 typedef char S t r i n g a [MAX L ] ; 7 8 typedef struct { 9 int lunghezza ; 10 int numerovocali ; 11 int sommaascii ; 1 } A n a l i s i S t r i n g a ; 13 14 bool c a r a t t e r e V o c a l e ( char a ) ; 1 A n a l i s i S t r i n g a A n a l i z z a S t r i n g a ( S t r i n g a s t r i n g a ) ; 16 18 19 int main ( ) { 0 1 S t r i n g a s t r i n g a ; A n a l i s i S t r i n g a a n a l i s i S t r i n g a ; 3 4 int l e n ; 6 p r i n t f ( " Inserisci una stringa (max %d caratteri ): \n",max L) ; 7 s c a n f ( "%s", s t r i n g a ) ; 8 9 a n a l i s i S t r i n g a = A n a l i z z a S t r i n g a ( s t r i n g a ) ; 30 31 p r i n t f ( " Lunghezza della stringa : %d\ nnumero di vocali: %d\n 3 Somma codifica ASCII: %d\n", a n a l i s i S t r i n g a. lunghezza, 33 a n a l i s i S t r i n g a. numerovocali, a n a l i s i S t r i n g a. sommaascii ) ; 34 3 }
36 37 38 bool c a r a t t e r e V o c a l e ( char a ){ 39 40 if ( a == A a == E a== I a == O a== U 41 a == a a== e a== i a == o a == u ){ 4 return TRUE; 43 } 44 4 else{ 46 return FALSE; 47 } 48 } 49 A n a l i s i S t r i n g a A n a l i z z a S t r i n g a ( S t r i n g a s t r i n g a ){ 0 1 A n a l i s i S t r i n g a a n a l i s i S t r i n g a ; int l e n =0, numerovocali =0,sommaASCII=0; 3 4 /* lunghezza della stringa */ l e n = s t r l e n ( s t r i n g a ) ; 6 /* alternativa per trovare lunghezza stringa 7 while(stringa [len ]!= \0 ){ 8 len ++; 9 } 60 */ 61 6 /* scorriamo tutta la stringa */ 63 for ( int i = 0 ; i <l e n ; i ++){ 64 6 sommaascii+= s t r i n g a [ i ] ; 66 67 /* vediamo se il carattere e una lettera */ 68 if ( ( s t r i n g a [ i ]>= a && s t r i n g a [ i ]<= z ) 69 ( s t r i n g a [ i ]>= A && s t r i n g a [ i ]<= Z ) ) { 70 if ( c a r a t t e r e V o c a l e ( s t r i n g a [ i ] ) ) { 71 numerovocali++; 7 } 73 } 74 7 76 } 77 78 a n a l i s i S t r i n g a. lunghezza=l e n ; 79 a n a l i s i S t r i n g a. numerovocali=numerovocali ; 80 a n a l i s i S t r i n g a. sommaascii = sommaascii ; 81 8 return a n a l i s i S t r i n g a ; 83 84 } In alternativa l esercizio poteva essere svolto anche senza utilizzare una struttura, ma dichiarando nel lunghezza,numerovocali,sommaascii come interi e passandoli per riferimento alla funzione AnalizzaStringa. Soluzione : 1 #include <s t r i n g. h> 3 #d e f i n e MAX L 30 / Lunghezza massima s t r i n g a /
4 typedef enum {FALSE,TRUE} b o o l ; 6 typedef char S t r i n g a [MAX L ] ; 7 8 9 10 void A n a l i z z a S t r i n g a ( S t r i n g a s t r i n g a, int lunghezza, 11 int numerovocali, int sommaascii ) ; 1 13 /* restituisce TRUE se il carattere e una vocale */ 14 bool c a r a t t e r e V o c a l e ( char a ) ; 1 16 int main ( ) { 18 S t r i n g a s t r i n g a ; 19 int lunghezza, numerovocali, sommaascii ; 0 1 p r i n t f ( " Inserisci una stringa (max %d caratteri ):\n",max L) ; s c a n f ( "%s", s t r i n g a ) ; 3 4 A n a l i z z a S t r i n g a ( s t r i n g a,& lunghezza,& numerovocali,&sommaascii ) ; 6 7 p r i n t f ( " Lunghezza della stringa : %d 8 \ nnumero di vocali: %d\ nsomma ASCII %d\n", 9 lunghezza, numerovocali, sommaascii ) ; 30 } 31 3 33 bool c a r a t t e r e V o c a l e ( char a ){ 34 3 if ( a == A a == E a== I a == O a== U 36 a == a a== e a== i a == o a == u ){ 37 38 return TRUE; 39 } 40 41 else{ 4 return FALSE; 43 } 44 } 4 46 47 void A n a l i z z a S t r i n g a ( S t r i n g a s t r i n g a, int lunghezza, 48 int numerovocali, int sommaascii ){ 49 0 1 lunghezza = s t r l e n ( s t r i n g a ) ; 3 /* 4 while(stringa [* lunghezza ]!= \0 ){ * lunghezza ++; 6 } 7 */ 8 9 for ( int i =0; i <( lunghezza ) ; i ++){ 60 61 sommaascii+= s t r i n g a [ i ] ; 6
63 if ( ( s t r i n g a [ i ]>= a && s t r i n g a [ i ]<= z ) 64 ( s t r i n g a [ i ]>= A && s t r i n g a [ i ]<= Z ) ) { 6 66 if ( c a r a t t e r e V o c a l e ( s t r i n g a [ i ] ) ) { 67 ( numerovocali )++; 68 } 69 } 70 } 71 7 }