2 maggio 2002 Avvisi: • Risultati I Esonero disponibili nella pag. WEB e affissi nella bacheca piano terra secondo dente • Soluzioni I Esonero disponibili nella pag. WEB Lezione di oggi • Conclusione su puntatori/array • Soluzioni esercizi I Esonero • Visione compiti corretti Puntatori e Array • Array e puntatori sono strettamente collegati – Il nome di un array e’ di fatto un puntatore costante – I puntatori possono essere utilizzati nelle operazioni che coinvolgono gli indici negli array… • Dichiaro un array b[5] e un puntatore bPtr,….. bPtr = b; e Sono assegnazioni equivalenti! bPtr = &b[0] Puntatori e Array • Elemento b[n] – puo’ essere ottenuto come *( bPtr + n ) – n - offset o scostamento – Per gli array si puo’ usare l’aritmentica dei puntatori. b[3] equivale a *(b + 3) – Si possono usare indici su puntatori bPtr[3] equivale a b[3] 1. /* Fig7_20.c Using subscripting and pointer notations with arrays */ 2. #include <stdio.h> 3. main() 4. { 5. int i, offset, b[] = {10, 20, 30, 40}; 6. int *bPtr = b; 7. printf("Array b printed with:\n Array subscript notation\n"); 8. for (i = 0; i <= 3; i++) 9. /* set bPtr to point to array b */ printf("b[%d] = %d\n", i, b[i]); 10. printf("\nPointer/offset notation where the pointer is the array name\n"); 11. for (offset = 0; offset <= 3; offset++) 12. printf("*(b + %d) = %d\n", offset, *(b + offset)); 13. printf("\nPointer subscript notation\n"); 14. for (i = 0; i <= 3; i++) 15. printf("bPtr[%d] = %d\n", i, bPtr[i]); 16. printf("\nPointer/offset notation\n"); 17. for (offset = 0; offset <= 3; offset++) 18. 19. 20. } printf("*(bPtr + %d) = %d\n", offset, *(bPtr + offset)); return 0; Array di puntatori • Esempio: creo un array di stringhe char *suit[4] = {"Hearts", "Diamonds", "Clubs", "Spades" }; – Una stringa e’ un puntatore al primo carattere – char * - ogni elemento di suit e’ un puntatore a char – Le stringhe non sono veramente nell’array – nell’array ci sono solo i puntatori a stringhe suit[0] ’H’ ’e’ ’a’ ’r’ ’t’ ’s’ ’\0’ suit[1] ’D’ ’i’ ’a’ ’m’ ’o’ ’n’ ’d’ suit[2] ’C’ ’l’ ’u’ ’b’ ’s’ ’\0’ suit[3] ’S’ ’p’ ’a’ ’d’ ’e’ ’s’ ’s’ ’\0’ ’\0’ • L’array suit ha dimensione fissata ma le stringhe possono essere di qualunque dimensione. Simulazione di un “mescolatore” di carte – Usa un array di puntatori a stringhe – Usa una matrice (2 indici corrispondenti a: suit, face) 0 Hearts Diamonds Clubs Spades Ace 1 Two 2 ThreeFour Five Six SevenEightNine Ten Jack QueenKing 3 4 5 6 7 8 9 10 11 12 0 1 2 3 deck[2][12] rappresenta King of Clubs Clubs King 1 /* Fig. 7.24: fig07_24.c 2 Card shuffling dealing program */ 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <time.h> 6 7 void shuffle( int [][ 13 ] ); 8 void deal( const int [][ 13 ], const char *[], const char *[] ); 9 10 int main() 11 { 12 const char *suit[ 4 ] = 13 { "Hearts", "Diamonds", "Clubs", "Spades" }; 14 const char *face[ 13 ] = 15 { "Ace", "Deuce", "Three", "Four", 16 "Five", "Six", "Seven", "Eight", 17 "Nine", "Ten", "Jack", "Queen", "King" }; 18 int deck[ 4 ][ 13 ] = { 0 }; 19 20 srand( time( 0 ) ); 21 22 shuffle( deck ); 23 deal( deck, face, suit ); 24 25 return 0; 26 } 27 28 void shuffle( int wDeck[][ 13 ] ) 29 { 30 int row, column, card; 31 32 for ( card = 1; card <= 52; card++ ) { 33 do { 34 row = rand() % 4; 35 column = rand() % 13; 36 } while( wDeck[ row ][ column ] != 0 ); 37 38 39 40 } 41 wDeck[ row ][ column ] = card; } I numeri 1-52 sono uniformemente distribuiti in un array deck. 42 void deal( const int wDeck[][ 13 ], const char *wFace[], 43 const char *wSuit[] ) 44 { 45 int card, row, column; 46 47 for ( card = 1; card <= 52; card++ ) 48 49 for ( row = 0; row <= 3; row++ ) Cerca in deck il numero di card poi scrive face e suit. 50 51 for ( column = 0; column <= 12; column++ ) 52 53 if ( wDeck[ row ][ column ] == card ) 54 printf( "%5s of %-8s%c", 55 wFace[ column ], wSuit[ row ], 56 card % 2 == 0 ? '\n' : '\t' ); 57 } Osservazione: i due cicli for interni fanno “piu’ lavoro del necessario”! Six Ace Ace Queen Ten Ten Ten Four Six Eight Nine Deuce Five Deuce Five King Deuce Ace Three Nine Four Eight Jack Five Four Jack of of of of of of of of of of of of of of of of of of of of of of of of of of Clubs Spades Hearts Clubs Hearts Spades Diamonds Diamonds Diamonds Hearts Hearts Spades Clubs Diamonds Spades Diamonds Hearts Clubs Clubs Clubs Hearts Diamonds Diamonds Hearts Clubs Clubs Seven Ace Queen Seven Deuce Three Four Ten Six Three Three Six Eight Eight King Jack Queen King King Nine Queen Nine Seven Five Jack Seven of of of of of of of of of of of of of of of of of of of of of of of of of of Diamonds Diamonds Diamonds Hearts Clubs Spades Spades Clubs Spades Diamonds Hearts Hearts Clubs Spades Clubs Spades Hearts Spades Hearts Spades Spades Diamonds Clubs Diamonds Hearts Spades Output Esercizi Esercizio 6.28 (Eliminazione dei duplicati) Scrivere un programma che produca 20 numeri casuali tra 1 e 20. Il programma dovra’ immagazzinare in un vettore i suddetti numeri considerando solo quelli distinti. Utilizzare un vettore piu’ piccolo possibile per questo compito Esercizi Esercizio 6.30 (Crivello di Eratostene) Scrivere un programma che utilizza un vettore di 1000 elementi per calcolare tutti i numeri primi tra 1 e 999 utilizzando la tecnica del “crivello di Eratostene”: •Creare un vettore con tutti gli elementi inizializzati a 1 (alla fine il valore 1 indichera’ che il numero,corrispondente all’indice e’ primo, 0 che non e’ primo) •Partendo dall’indice 2, se il valore e’ 1, scorrere il resto del vettore azzerando tutti i valori corrispondenti a multipli di 2. (questo azzerera’ tutti i valori corrispondenti a indici pari). Poi andare all’indice 3 e se il valore e’ 1, scorrere il resto del vettore azzerando tutti i valori corrispondenti a multipli di 3. Poi andare all’indice 4, 5,… e rifare sempre lo stesso. Alla fine restera’ valore 1 solo in corrispondenza dei numeri primi. Vediamo e commentiamo delle possibili soluzioni per gli esercizi del I Esonero….