24 aprile 2002 Avvisi: Risultati 1 o Esonero: (entro) lunedi 27 disponibili nella pag. WEB, ma anche esposti nella bacheca fuori dal corridoio 2 o dente, piano terra. Speciale 1 o Esonero : soluzioni, commenti, correzioni compiti prossima lezione (giovedì 2 maggio). Progetti: gia disponibili nella pag. WEB. Esercizio 6.19 Qualche minuto di laboratorio Scrivere un programma C che simuli il lancio di due dadi. Il programma dovra utilizzare rand per lanciare il primo dado e poi invocarla nuovamente per lanciare il secondo dado: poi calcolera la somma dei due valori. (Nota: tale somma puo variare tra 2 e 12). Tale programma dovra lanciare i due dadi 36.000 volte e poi dovra visualizzare i seguenti risultati: Un vettore di frequenze F per i risultati di ogni lancio cioe tale che F(i) rappresenta quante volte la somma dei due dadi e stata uguale ad i con i=2,3, 12. Una matrice D 6x6 tale che D(i,j) rappresenta quante volte si e ottenuto i col primo dado e j con il secondo dado con i,j=1,2,,6. Vediamo le soluzioni proposte da voi 1
Chiamata di funzioni per riferimento Chiamata per riferimento usando puntatori come argomenti Si passa l indirizzo di un argomento usando l operatore & Consentono di cambiare il valore nella locazione di memoria Gli array non si possono passare con & perche il nome dell array e gia un puntatore operatore* Usato come alias per una variabile all interno di una funzione void double(int *number) {*number = 2 * (*number);} *number si usa come alias per la variabile passata 1. /* Elevare al cubo mediante una chiamata per valore */ 2. #include <stdio.h> 3. int cubebyvalue(int); 4. main() 5. { 6. int number = 5; 7. printf("the original value of number is %d\n", number); 8. number = cubebyvalue(number); 9. printf("the new value of number is %d\n", number); 10. return 0; 11. } 12. int cubebyvalue(int n) 13. { 14. return n * n * n; /* eleva al cubo */ 15. } The original value of number is 5 The new value of number is 125 Output 2
1 /* Fig. 7.7: fig07_07.c 2 Elevare al cubo mediante chiamata per riferimento 3 mediante puntatori */ 4 5 #include <stdio.h> 6 7 void cubebyreference( int * ); Notare che viene dato 8 l indirizzo di number 9 int main() infatti cubebyreference 10{ aspetta un puntatore 11 int number = 5; (indirizzo di una variabile). 12 13 printf( "The original value of number is %d", number 14 cubebyreference( ); &number ); 15 printf( "\nthe new value of number is %d\n", number 16 ); 17 return 0; 18} 19 20void cubebyreference( int *nptr ) 21{ 22 *nptr = *nptr * *nptr * *nptr; 23} All interno dicubebyreference, si usa *nptr (*nptr e number). The original value of number is 5 The new value of number is 125 Output Usare il qualificatore Const con i puntatori Qualificatore const una variabile non puo essere cambiata Utile avere const se la funzione non deve cambiare una variabile Tentativi di cambiare un const produce errore in compilazione Puntatori const puntano alla stessa locazione di memoria Devono essere inizializzati quando sono dichiarati int *const myptr = &x; Tipo int *const puntatore costante a unint const int *myptr = &x; Puntatori regolari a const int const int *const Ptr = &x; const puntatore a const int x puo essere cambiato, ma non*ptr 3
1. /* Fig7_10 Converting lowercase letters to uppercase letters */ 2. /* using a non-constant pointer to non-constant data */ 3. #include <stdio.h> 4. void converttouppercase(char *); 5. main() 6. { 7. char string[] = "characters"; 8. printf("the string before conversion is: %s\n", string); 9. converttouppercase(string); 10. printf("the string after conversion is: %s\n", string); 11. return 0; 12. } 13. void converttouppercase(char *s) 14. { 15. while (*s!= '\0') { 16. if (*s >= 'a' && *s <= 'z') 17. *s -= 32; /* convert to ASCII uppercase letter */ 18. ++s; /* increment s to point to the next character */ 19. } 20. } The string before conversion is: characters The string after conversion is: CHARACTERS Output 4
1. /* Fig7_11 Printing a string one character at a time using */ 2. /* a non-constant pointer to constant data */ 3. #include <stdio.h> 4. void printcharacters(const char *); 5. main() 6. { 7. char string[] = "print characters of a string"; 8. printf("the string is:\n"); 9. printcharacters(string); 10. putchar('\n'); 11. return 0; 12. } 13. void printcharacters(const char *s) 14. { 15. for ( ; *s!= '\0'; s++) /* no initialization */ 16. putchar(*s); 17. } The string is: print characters of a string Output 1. /* Fig7_12.c Attempting to modify data through a */ 2. /* non-constant pointer to constant data */ 3. #include <stdio.h> 4. void f(const int *); 5. main() 6. { 7. int y; 8. f(&y); /* f attempts illegal modification */ 9. return 0; 10. } 11. void f(const int *x) 12. { 13. *x = 100; /* cannot modify a const object */ 14. } 13 Warning: assignment of read-only location Dev-C++ 13 ERROR: Cannot modify a const object Borland 5
1. /* Fig. 7.13 Attempting to modify a constant pointer to */ 2. /* non-constant data */ 3. #include <stdio.h> 4. main() 5. { 6. int x, y; 7. int * const ptr = &x; 8. ptr = &y; /* attempt to modify a const pointer*/ 9. return 0; 10. } 10 Warning: assignment to read-only variable ptr Dev-C++ 10 ERROR: Cannot modify a const object Borland 1 /* Fig. 7.14: fig07_14.c 2 Attempting to modify a constant pointer to 3 constant data */ 4 5 #include <stdio.h> 6 7 int main() 8 { 9 int x=5, y; 10 11 const int * const ptr = &x; 12 13 14 15 *ptr = 7; 16 ptr = &y; 17 18 return 0; 19 } FIG07_13.c: Error E2024 FIG07_13.c 15: Cannot modify a const object in function main 16: Cannot modify a const object in function main *** 2 errors in Compile *** 6
Bubble Sort usando chiamata per riferimento Implementare bubblesort usando puntatori Scambia due elementi La funzione swap deve ricevere un indirizzo (usando &) degli elementi dell array Gli elementi dell array hanno una chiamata-pervalore per default Usando puntatori e l operatore *, la funzione swap puo scambiare elementi dell array 1 /* Fig. 7.15: fig07_15.c 2 This program puts values into an array, sorts the values into 3 ascending order, and prints the resulting array. */ 4 #include <stdio.h> 5 #define SIZE 10 6 void bubblesort( int *, const int ); 7 8 int main() 9 { 11 int a[ SIZE ] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 }; 12 int i; 13 14 printf( "Data items in original order\n" ); 15 16 for ( i = 0; i < SIZE; i++ ) 17 printf( "%4d", a[ i ] ); 18 19 bubblesort( a, SIZE ); /* ordina l array */ 20 printf( "\ndata items in ascending order\n" ); 21 22 for ( i = 0; i < SIZE; i++ ) 23 printf( "%4d", a[ i ] ); 24 25 printf( "\n" ); 27 return 0; 28 } Bubblesort prende l indirizzo dell array. Il nome di un array e un puntatore.. 7
29 30 void bubblesort( int *array, const int size ) 31 { 32 void swap( int *, int * ); 33 int pass, j; 34 for ( pass = 0; pass < size - 1; pass++ ) 35 36 for ( j = 0; j < size - 1; j++ ) 37 38 if ( array[ j ] > array[ j + 1 ] ) 39 swap( &array[ j ], &array[ j + 1 ] ); 40 } 41 42 void swap( int *element1ptr, int *element2ptr ) 43 { 44 int hold = *element1ptr; 45 *element1ptr = *element2ptr; 46 *element2ptr = hold; 47 } Data items in original order 2 6 4 8 10 12 89 68 45 37 Data items in ascending order 2 4 6 8 10 12 37 45 Output Nelle lezioni precedenti 103 void bubblesort( int a[] ) 104 { 105 int pass, j, hold; 106 107 for ( pass = 1; pass <= SIZE - 1; pass++ ) 108 109 for ( j = 0; j <= SIZE - 2; j++ ) 110 111 if ( a[ j ] > a[ j + 1 ] ) { 112 hold = a[ j ]; 113 a[ j ] = a[ j + 1 ]; 114 a[ j + 1 ] = hold; 115 } 116 } 8
Aritmetica con i puntatori Alcune operazioni aritmetiche possono essere utilizzate con i puntatori Incrementa/decrementa puntatori (++ o--) Si puo aggiungere/sottrarre un intero a/da un puntatore (+ o+=, - o -=) Puntatori possono essere sottratti uno dall altro Attenzione: Sono operazioni senza significato a meno che non siano effettuate su array. int v[5] Aritmetica con i puntatori (supp int e di 4 byte) vptr = v oppure vptr = &v[0] vptr punta al primo elementov[0]nella locazione 3000. (vptr = 3000) vptr +=2; assegna avptr valore3008 vptr punta a v[2], ma un int vale 4 byte! locazione 3000 3004 3008 3012 3016 v[0] v[1] v[2] v[3] v[4] variabile puntatore vptr 9
Aritmetica con i puntatori Sottrarre puntatori Restituisce il numero di elementi tra uno e l altro vptr2 = &v[2]; vptr = &v[0]; vptr2 - vptr = 2. (numero di elementi del vettore tra vptr2 e vptr ) Confronti tra puntatori ( <, ==, > ) Per vedere quale puntatore punta all elemento dellarray di indice maggiore Anche per controllare se un puntatore punta a Aritmetica con i puntatori Puntatori dello stesso tipo possono essere assegnati uno all altro Se non sono dello stesso tipo, deve essere usato un operatore cast Eccezione: puntatori avoid (tipovoid *) Puntatori generici, rappresentano qualunque tipo Non occorre casting per convertire un puntatore ad un puntatorevoid Puntatori void non possono essere dereferenziati 10