Esercizi Programmazione I Novembre 06 Esercizio Valutazione espressioni con puntatori Valutare e definire il tipo delle seguenti espressioni. Inserire le parentesi per sotolineare l ordine della valutazione in base alla priorità degli operatori. i n t i =, j = 5, p = &i, q = &j, r ; double x ; p == & i ; 5 & p ; 6 r = &x ; 7 7 p / q + 7 ; 8 ( r = & j ) = p ; 9 Le espressioni sono tutte di tipo intero: Soluzione dell esercizio p == (&i), valore ( (&p)), valore r = (&x), il compilatore restituisce un warning, conversione implicita da double a int (((7 ( p)))/( q) + 7, valore ( (r = (&j))) = ( p), valore 5 Ricordarsi r è un lvalue dato che è equivalente alla variabile a cui punta, cioè j. Esercizio Assegnamenti legali e illegali con i puntatori Valutare quali dei seguenti assegnamenti sono legali (nessun errore/warning) e quali sono illegali. i n t p ; f l o a t q ; void v ; 5 p = 0 ; 6 p = ; 7 p = ( i n t ) ; 8 p = v = q ; 9 v = ; 0 p = q ; p = ( i n t ) p ; Soluzione dell esercizio (a differenza dell esempio sotto, 0 è un intero che può essere assegnato ad un puntatore, per esempio, anche NULL è definito come 0 in stdlib.h). Illegale (da int a int)
Illegale (da int a void) Illegale (da float a int) Esercizio Chiamata per riferimento Scrivere una funzione swap che scambia i valori di due variabili di tipo int. Testare la funzione chiamandola da main(), su due variabili int i = e int j = 5. Stampare infine le due variabili i e j per controllare che il loro valore sia scambiato. Scrivere le due funzioni nell0 stesso file mainfile.c. Come ulteriore esercizio, spostare la definizione della funzione swap in un altro file myswaplib.c. Includere la dichiarazione della funzione nel file myswaplib.h, ed importarlo #include myswaplib.h. Fare riferimenti all esercizio del 8 Ottobre. Compilare separatamente i due file: gcc -c myswaplib.c e gcc -c mainfile.c. Infine linkare i due file gcc -o mainfile mainfile.o myswaplib.o per ottenere un solo eseguibile. #i n c l u d e <s t d i o. h> void swap ( i n t p, i n t q ) { 5 i n t tmp ; 6 tmp = p ; 7 p = q ; 8 q = tmp ; 9 } 0 i n t main ( void ) { i n t i =, j =5; 5 swap(& i, &j ) ; 6 p r i n t f ( %d %d\n, i, j ) ; 7 r e t u r n 0 ; 8 } 9 Soluzione dell esercizio Esercizio Scrivere cosa stampa il seguente programma. #i n c l u d e <s t d i o. h> i n t main ( ) { double a []= {.,. 7 }, p= NULL, q= NULL; 5 i n t r= NULL; 6 i n t r e s= 0 ; 7 8 p= a ; 9 q = p + ; 0 p r i n t f ( %l d \n, q p ) ; p r i n t f ( %d\n, ( i n t ) q ( i n t ) p ) ; p r i n t f ( %d\n, q == &a [ ] ) ; // A cosa punta q q u i n d i? Chiamata per riferimento r= ( i n t ) a + ; // Se non s i sa cosa stampa i n questo caso d i r e dove punta r 5 p r i n t f ( %d\n, r ) ; 6 p r i n t f ( %d\n, ( i n t ) r ( i n t ) a ) ; 7 p r i n t f ( %f \n, p ) ; 8 9 r e t u r n 0 ; 0 } Ecco cosa stampa: Soluzione dell esercizio
8 078990.00000 Il valore di q p è il numero di elementi di distanza nell array tra l elemento puntato da p e quello puntato da q. (int)q (int)p è invece la distanza in byte tra di essi: in questo caso, essendo un array di double la distanza è 8 byte, visto che ogni elemento double dell array occupa 8 byte. Nel quarto caso non è facile dire cosa stampa. Con quell operazione vengono letti i secondi byte del secondo elemento dell array (un tipo double in C occupa 8 byte), e si stampano come se fossero un valore di tipo int, come mostra il quinto valore stampato. Esercizio 5 Matrici Data una matrice int a[][5] e due cicli for indicizzati da i (righe) e j (colonne), dire quali delle seguenti espressioni è corretta per recuperare l elemento a[i][j] (cioè, dire quali di queste espressionisono equivalenti ad essa): *(a[i] + j) (*(a + i))[j] *((*(a + i)) + j) *(&a[0][0] + 5*i + j) Sono tutte e quivalenti a a[i][j]. Soluzione dell esercizio 5 Esercizio 6 Matrici Dichiarare una matrice di int di dimensione e inizializzarla con i valori da a 6. Utilizzare due cicli for per stampare tutta la matrice, stampando tutti gli elementi di una riga separati da uno spazio e poi andando a capo per ogni nuova riga: Riga Riga 5 6 7 8 Riga 9 0 Riga 5 6 #i n c l u d e <s t d i o. h> i n t main ( ) { c o n s t i n t rows=, c o l s= ; 5 Soluzione dell esercizio 6 6 i n t matrix [ rows ] [ c o l s ] = { {,,, }, { 5, 6, 7, 8 }, { 9, 0,, }, {,, 5, 6 } } ; 7 8 f o r ( i n t i= 0 ; i < rows ; i ++) { 9 p r i n t f ( Riga %d\n, i +) ; 0 f o r ( i n t j= 0 ; j < c o l s ; j++) p r i n t f ( %d, matrix [ i ] [ j ] ) ; puts ( ) ; } 5 r e t u r n 0 ; 6 } 7
Esercizio 7 Matrici Nella funzione main() prendere da tastiera (scanf()) il numero di righe e colonne di una matrice. Sempre dentro main() chiamare una funzione int mallocmatrix(int, int) che crea alloca con malloc() una matrice con un numero di righe e colonne passato per parametro (ritorna il puntatore alla matrice). Chiamare poi una funzione void inputmatrix(int, int, int), passando il puntatore alla matrice ed il numero di righe e colonne; tale funzione legge da tastiera (scanf()) tutti i valori della matrice (utilizzare due cicli for). Infine chiamare una funzione void printmatrix(int, int, int), che stampa tutti i valori della matrice. Un esempio dell output e dell input è dato qui sotto. Scrivere tutto il codice in un solo file (le definizioni di tutte e tre le funzioni e la funzione main()). Infine, come nell esercizio, spostare le definizioni delle tre funzioni mallocmatrix(), inputmatrix() e printmatrix() in un file mylib.c separato, e importare le dichiarazioni delle tre funzioni utilizzando mylib.h. Dammi il numero di righe della matrice: Dammi il numero di colonne della matrice: Dammi elemento [],[]: Dammi elemento [],[]: Dammi elemento [],[]: Dammi elemento [],[]: Dammi elemento [],[]: 5 Dammi elemento [],[]: 6 Riga Riga 5 6 #i n c l u d e <s t d i o. h> #i n c l u d e <s t d l i b. h> 5 i n t mallocmatrix ( i n t rows, i n t c o l s ) { 6 7 i n t mat = ( i n t ) malloc ( rows s i z e o f ( i n t ) ) ; 8 9 f o r ( i n t i = 0 ; i < rows ; i ++) 0 mat [ i ] = ( i n t ) malloc ( c o l s s i z e o f ( i n t ) ) ; r e t u r n mat ; } 5 6 Soluzione dell esercizio 7 7 void inputmatrix ( i n t matrix, i n t rows, i n t c o l s ) { 8 9 f o r ( i n t i= 0 ; i < rows ; i ++) 0 f o r ( i n t j= 0 ; j < c o l s ; j++) { p r i n t f ( Dammi elemento [%d ], [ % d ] :, i +, j +) ; s c a n f ( %d, &matrix [ i ] [ j ] ) ; } 5 r e t u r n ; 6 } 7 8 void p r i n t M a t r i x ( i n t matrix, i n t rows, i n t c o l s ) { 9 0 f o r ( i n t i= 0 ; i < rows ; i ++) { p r i n t f ( Riga %d\n, i +) ; f o r ( i n t j= 0 ; j < c o l s ; j++) p r i n t f ( %d, matrix [ i ] [ j ] ) ; puts ( ) ; 5 } 6 7 r e t u r n ; 8 } 9
0 i n t main ( ) { i n t rows= 0 ; i n t c o l s = 0 ; p r i n t f ( Dammi i l numero d i r i g h e d e l l a matrice : ) ; 5 s c a n f ( %d, &rows ) ; 6 p r i n t f ( Dammi i l numero d i colonne d e l l a matrice : ) ; 7 s c a n f ( %d, &c o l s ) ; 8 9 i n t matrix= mallocmatrix ( rows, c o l s ) ; 50 inputmatrix ( matrix, rows, c o l s ) ; 5 p r i n t M a t r i x ( matrix, rows, c o l s ) ; 5 5 f r e e ( matrix ) ; 5 55 r e t u r n 0 ; 56 } 57 5