Array Un array è una sequenza di elementi omogenei. Un array viene dichiarato scrivendo, nell’ordine, il tipo degli elementi, il nome dell’array, e le sue dimensioni. tipo nome [dimensione]; dove tipo è il tipo degli elementi ( int, float ...) detto anche tipo base dell'array , nome è un identificatore e dimensione, che deve essere racchiuso tra parentesi quadre [], è la dimensione, ossia il numero di elementi, dell'array. La dichiarazione dell'array billy è: int billy [5]; ATTENZIONE: Il campo dimensione deve essere un valore costante in quanto gli array sono blocchi di memoria di dimensione prefissata ed il compilatore deve conoscere esattamente quanta memoria serve per l'array prima che il programma venga eseguito. Array Si noti che all’interno delle parentesi quadre non è possibile, in fase di dichiarazione dell’array, utilizzare nomi di variabili . E’ possibile, per specificare le dimensioni di un array, usare delle costanti definite, come ad esempio: #define ARRAY_UNO_MAX 10 #define ARRAY_DUE_MAX 20 …….. int array_uno[ARRAY_UNO_MAX]; char array_due[ARRAY_DUE_MAX]; ARRAY ATTENZIONE: se eseguiamo il seguente codice: int array_tre[10]; …… …… // L’array viene inizializzato for(int i=0; i < 14; i++) { cout << array_tre[i] << endl; } il risultato sarà corretto fino a quando la variabile i sarà minore o uguale a 9 (infatti la dimensione dell’array è stata definita essere uguale a 10). Quello che avverrà, quando il programma cercherà di andare a leggere i valori array_tre[10], array_tre[11], array_tre[12] e array_tre[13] è assolutamente casuale. Infatti, il programma andrà a leggere delle aree di memoria che non sono state inizializzate o, addirittura, che contengono dei valori relativi ad altre variabili, stampando quindi sullo schermo risultati inaspettati. ARRAY Come per le variabili semplici, anche per gli array è possibile specificare un valore iniziale. Ad esempio, con la dichiarazione: int billy [5] = { 16, 2, 77, 40, 12071 }; l'array viene inizializzato come segue: billy [0]=16; billy [1]=2; billy [2]=77; billy [3]=40; billy [4]=12071; Il numero di valori usati per l'inizializzazione (quelli posti tra le parentesi grafe {}) deve essere esattamente uguale alla dimensione dell'array. In C++ è possibile anche usare la notazione: int billy [] = { 16, 2, 77, 40, 12071 }; ed in questo caso viene assunto implicitamente come dimensione dell'array il numero di valori della lista di inizializzazione ARRAY altri esempi di inizializzazione esplicita al momento della creazione: int array_quattro[3] = {12, 0, 4}; char vocali[5] = {‘a’,'e’,'i’,'o’,'u’}; float decimali[2] = {1.329, 3.34}; Per inizializzare un array durante l’esecuzione del programma occorre accedere, generalmente con un ciclo, ad ogni elemento dell’array stesso ed assegnargli un valore. LEGGI e SCRIVI VETTORE #include <stdio.h> #include <iostream> …….. #define MAX 10 int main() { int a[MAX]; int i; for (i = 0;i < n;i++) cin>>a[i]; //lettura array // esempio con gli array( SOMMA) #include <iostream> …… int billy [] = {16, 2, 77, 40, 12071}; int n, risultato=0; int main () { for ( n=0 ; n<5 ; n++ ) risultato += billy[n]; for (i = 0;i < n;i++) cout<<a[i]); //scritturaarray return 0; } } cout << risultato; return 0; ARRAY In ogni punto del programma in cui un array risulta visibile possiamo accedere individualmente ad uno degli elementi dell'array per leggerlo o modificarlo esattamente come se esso fosse una normale variabile. Il formato è il seguente: name[index]; Ad esempio, se vogliamo memorizzare il valore terzo elemento di billy possiamo usare l'assegnazione: 75 nel billy[2] = 75; oppure, per copiare il variabile a possiamo usare: valore del a = billy[2]; terzo elemento nella Gli array vengono passati alle funzioni sempre per indirizzo. codice: …..void funzione (int arr[]) ; int main () { .... int numeri[3]; .... funzione (numeri); } void funzione (int arr[]) { ..... } L'argomento della funzione si può dichiarare anche : int *arr oppure int arr[3] Il passaggio di un array ad una funzione avviene sempre per indirizzo e mai per valore. Quando si passa un’array in effetti non si sta facendo altro che passare l’indirizzo (il puntatore) del primo elemento dell’array stesso. Ciò vuol dire che se all’interno della funzione vengono modificati i valori dell’array, tale modifica avrà effetto anche sull’array che si è passato alla funzione. Semplice programma che illustra il passaggio di un array ad una funzione #include <iostream.h> #define dimensione_array 5 int somma(int array[]); int main() { int vettore[size] = {1,2,3,4,5}; cout << "La somma degli elementi dell'array e' " << somma(vettore) << endl; return(0); } int somma(int array[]) {// la funzione prende come parametro un vettore e ne ritorna la somma degli elementi int somma = 0; for(int i=0; i < dimensione_array ; i++) somma += array[i]; return somma; } .................... void binario(int n); ………………… int main() { int n; char risposta; do { cout<<"Inserisci un numero decimale per convertirlo: "; cin>>n; if(n<0) cout<<"Impossibile convertire"; else { binario(n); cout<<endl<<"Vuoi continuare? [n=no,s=si]: "; cin>>risposta; } } while((risposta!='n') && (risposta!='N')); return 0; system(pause); } void binario(int n) { int A[100],c=0,i=0; cout<<"Conversione binaria: "; if(n==0) cout<<"0"; else while(n>0) { A[c]=n%2; n=n/2; c++; } for(i=c-1;i>=0;i--) cout<<A[i]; cout<<endl; } Stringhe di Caratteri Oltre alle variabili numeriche si possono anche dichiarare variabili i cui valori sono stringhe di caratteri. Tali variabili ci permettono di elaborare successioni di caratteri quali : parole, frasi, nomi, testi, eccetera. In C++ non vi è un tipo di variabile predefinito in grado di memorizzare delle stringhe di caratteri. Dobbiamo usare degli array di caratteri. La libreria standard del C++ contiene un file (che si può includere con il comando #include <string> ) in cui è definito un tipo string con il quale l'elaborazione di stringhe risulta molto agevolata. Il seguente array: char jenny [20]; può memorizzare una stringa di al più 20 caratteri. Possiamo rappresentarlo come segue: jenny: Naturalmente non è necessario usare tutti e 20 i caratteri dell'array. L'array jenny si può usare per memorizzare sia la stringa di 5 caratteri "Hello" sia la stringa di 15 caratteri "Merry Christmas". Siccome l'array può contenere stringhe più corte della sua dimensione occorre prevedere una indicazione del punto in cui termina la stringa. Ad esempio: Jenny=Hello\0; Jenny=Mery Christmas\0; Osserviamo che dopo il contenuto effettivo della stringa viene aggiunto un carattere nullo ('\0') per indicare la fine della stringa. Pertanto l'array jenny può contenere al più stringhe di 19 caratteri. Inizializzazione delle stringhe Per inizializzare una stringa di caratteri si può usare la stessa notazione usata per gli array: char mystring[ ] = { 'H', 'e', 'l', 'l', 'o', '\0' }; Abbiamo così inizializzato una stringa (array) di 6 valori di tipo parola Hello più il carattere nullo '\0'. char: la Possiamo anche inizializzare un array di caratteri usando una stringa costante. Alle stringhe costanti viene sempre aggiunto implicitamente un carattere nullo finale '\0'. char mystring [] = "Hello"; In entrambi i casi la dimensione dell'array mystring è di 6 elementi di tipo char: i 5 caratteri di Hello e il carattere nullo finale ( '\0' ). mystring[0]='H'; mystring[1]='e'; mystring[2]='l'; mystring[3]='l'; mystring[4]='o'; mystring[5] = '\0'; Attenzione…. La libreria standard (che si può includere con #include <string.h> ) contiene la definizione di un certo numero di funzioni quali. strcpy ( str ing co py) che si può richiamare nel seguente modo: strcpy (string1, string2); L'effetto è copiare il contenuto di string2 in string1. string2 può essere sia un array sia una stringa costante, il che ci permette di assegnare la stringa costante "Hello" all'array di caratteri mystring usando la seguente notazione: strcpy (mystring, "Hello"); // assegnazione a stringhe #include <iostream> #include <string> int main () { char stMyName [20]; strcpy (stMyName,“M.V.Avolio"); cout << stMyName; return 0; } Un altro modo per assegnare un valore ad un array di caratteri è quell di usare direttamente il flusso di input cin. Nella libreria iostream è infatti definita una funzione getline il cui prototipo è: cin.getline ( char buffer [], int length, char delimiter = ' \n'); #include <iostream> int main () { char nome [100]; cout << "Come ti chiami? "; cin.getline (nome, 100); cout << "Salve " << nome<< ".\n"; cout << “Il tuo colore preferito? "; cin.getline (nome,100); cout << “Il" << nome << " piace anche a me.\n"; return 0; } STRINGHE Si può anche usare l'operatore di estrazione (>>) per leggere delle stringhe da cin : cin >> nome; che funziona ma con le seguenti limitazioni che cin.getline non ha: •si possono leggere soltanto parole e non intere frasi in quanto l'operatore di estrazione usa come delimitatore qualsiasi occorrenza di un carattere invisibile (spazio, tabulazione, nuova linea, ritorno carrello). •non si può specificare la dimensione dell'array il che rende instabile il programma, nel caso in cui l'input sia una parola più lunga della dimensione dell'array. AlTRE OPERAZIONI CON LE STRINGHE strcat: char* strcat (char* dest , const char* src ); Aggiunge (appende) la stringa src alla fine della stringa dest. Ritorna dest strcmp: int strcmp (const char* str1, const char* str2 ); Confronta le stringhe str1 ed str2 . Ritorna 0 se sono uguali. strcpy: char* strcpy (char* dest, const char* src ); Copia il contenuto di src in dest. Ritorna dest. strlen: size_t strlen (const char* str); Ritorna la lunghezza di str. NOTA: char* ha lo stesso significato di char[] PAROLA PALINDROMA PSEUDO-CODICE: condizione=true; //LETTURA DELA PAROLA ………. //CONTROLLO DELLA PAROLA for (i=0; i<(lunghezza totale-1)/2; i++) if (parola[i]!=parola[lunghezza totale-1-i]) condizione=false; if (condizione==true) parola palindroma else parola non palindroma Esercizio 1 proposto (uso dell’array) : Compattazione di un vettore Scrivere un programma che legge N numeri interi da tastiera e li memorizza in un vettore. Il numero N viene inserito dall’utente ed è minore di 20. Il programma deve generare un secondo vettore che compatta i numeri contenuti nel primo vettore. In particolare: • ogni numero che compare ripetuto nel primo vettore, deve comparire una sola volta nel secondo vettore • ogni numero uguale a zero presente nel primo vettore non deve comparire nel secondo vettore. Il programma deve visualizzare il contenuto del secondo vettore. Ad esempio, si supponga N=8 e si consideri la sequenza di numeri 1 18 3 0 24 3 6 0 inseriti da tastiera. Il programma deve visualizzare 1 18 3 24 6. Esercizio 2 proposto (uso delle stringhe): Conta vocali e consonanti Scrivere un programma che legga una frase introdotta da tastiera. La frase è terminata dall’introduzione del carattere di invio. La frase contiene sia caratteri maiuscoli che caratteri minuscoli, e complessivamente al più 100 caratteri. Il programma dovrà stampare su schermo le seguenti informazioni: • per ognuna delle lettere dell’alfabeto, il numero di volte che la lettera compare nella stringa • il numero di consonanti presenti nella stringa • il numero di vocali presenti nella stringa. Esercizio 3proposto (uso delle matrici): Concorso di intelligenza In un concorso di intelligenza, N giudici esprimono il loro giudizio su K candidati. Il giudizio è un valore numerico tra 0 e 5. Si scriva un programma per determinare il candidato più intelligente,ed il giudice più severo.