Tipi derivati: Array
Array
¤ Gli array (o vettori) sono composti da elementi omogenei (cioè hanno tutti lo stesso tipo base)
¤ ogni elemento è identificato all'interno dell'array da un numero d’ordine detto indice dell'elemento
¤ il numero di elementi di un array è detto lunghezza (o dimensione)
¤ array = sequenza di variabili aventi tutte lo stesso tipo
¤ Array di interi con 8 elementi
¤ Notate che il primo elemento ha indice 0, mentre l’ultimo ha indice 7
¤ In generale, in un array con N elementi, gli indici sono compresi nell'intervallo [0,..,N-1]
1 4 6 3 9 7 3 5 0 1 2 3 4 5 6 7
Array – dichiarazione
¨ Dichiarazione di variabili di tipo array
<tipo-base> <nome-array> [lunghezza];
¨ Dove:
¤ tipo-base è il tipo degli elementi che l'array conterrà;
¤ nome-array è il nome identificatore dell'array e segue le stesse regole degli identificatori di variabile
¤ lunghezza è una espressione - anche complessa - di tipo int (ovviamente espressioni reali non avrebbero senso)
¨ Alcuni esempi:
#define M 7 #define N 3
int ai[M]; //array di interi con M elementi float af[N];//array di float con N elementi double ad[N+M];//array di double con M+N elementi char ac[M-N];//array di char con M-N elementi
Array – inizializzazione
¨ Gli elementi del vettore possono essere inizializzati con valori costanti contestualmente alla dichiarazione del vettore.
Esempio: int n[4] = {11, 22, 33, 44};
¨ l'inizializzazione deve essere contestuale alla dichiarazione Esempio: int n[4];
n = {11, 22, 33, 44}; //errore!
¨ l'inizializzazione può essere parziale e gli elementi non inizializzati sono posti a 0 Esempio: int n[10] = {3}; azzera i rimanenti 9 elementi del vettore
float af[5] = {0.0}; pone i 5 elementi pari a 0.0 int x[5] = {}; //errore!
¨ Se ci sono più inizializzatori che posizioni nell'array, si ha un errore alla compilazione Esempio: int v[2] = {1, 2, 3}; //errore!
¨ Se si scrive una lista di inizializzatori, si può evitare di specificare la lunghezza e viene presa la lunghezza della lista
Esempio: int n[] = {1,2,3}; equivale a int n[3] = {1,2,3};
Operazioni sugli array
¨ In C, l'unica operazione possibile sugli array è l'accesso agli elementi
¨ Conseguenze:
¤ Una volta dichiarato, il C non fornisce (in generale) modi per conoscere la dimensione di un array
¤ Non si possono effettuare direttamente assegnazioni tra array Esempio:
int a[3] = {11, 22, 33};
int b[3];
b = a; // errore!
¨ l'accesso a un elemento con indice i nell'array a avviene per mezzo dell'indice dell'elemento stesso, secondo la sintassi
a[i]
¨ L’espressione a[i] restituisce il valore della variabile con indice i, quindi il tipo di questa espressione è il tipo base dell'array.
Accesso agli elementi di un array
¨ int a[20]; //array a con 20 elementi interi
¨ Per accedere al primo elemento sarà sufficiente scrivere a[0], che esprime la “variabile” con indice 0 dell’array.
¨ Questo vuol dire che posso utilizzare l'espressione a[0] come se fosse una variabile di tipo intero. Esempi:
a[0] = 25+30;
a[0] = a[0]-7;
¨ Poiché l’array contiene 20 elementi, sono corretti gli accessi in memoria:
a[0], a[1], a[2], ..., a[19]. La locazione a[20] NON fa parte dell’array.
¨ Attenzione! Né al momento della compilazione, né durante l'esecuzione sono effettuati controlli per evitare che il vostro programma acceda a una locazione al di fuori dell’array → l’onere dei controlli ricade interamente sul programmatore!
Esempio: Lettura e Stampa di un array
#include <stdio.h>
#define SIZE 5 int main(void) {
int a[SIZE]; /* array con SIZE elementi, indicizzati da 0 a SIZE-1 */
int i;
for (i = 0; i < SIZE; i++) {
printf("Inserisci l'elemento di indice %d: ", i);
scanf("%d", &a[i]);
}
printf("Indice - Elemento:\n");
for (i = 0; i < SIZE; i++) printf("%d - %d\n", i, a[i]);
return 0;
}
¨ a[i] è analogo a una variabile di tipo primitivo: si legge e si scrive allo stesso modo, usando scanf e printf e i caratteri di controllo
Esempio: Lettura e Stampa di un array con dimensione inserita dall'utente
#include <stdio.h>
int main(void) { int i,size;
printf("Inserisci la dimensione dell'array: ");
scanf("%d", &size);
int a[size];
for (i=0; i<size; i++) {
printf("\nInserisci l'elemento con indice %d: ", i);
scanf("%d", &a[i]);
}
printf("\nl'array inserito è:\n");
printf("[");
for (i=0; i<size; i++) printf("%d, " , a[i]);
printf("\b\b]\n"); //cancella lo spazio e la virgola return 0;
}
Esempio: somma degli elementi di un array
#include <stdio.h>
#define SIZE 20 int main(void) { int i, sum, a[SIZE];
for (i = 0; i < SIZE; i++) //legge i SIZE elementi scanf("%d", &a[i]); //dell'array
sum = 0; //variabile accumulatore for (i = 0; i < SIZE; i++)
sum+= a[i]; /* sum è la somma di tutti gli elementi di a considerati fino a questo momento (cioè fino all'i-esimo passo) */
printf("La somma degli elementi letti è: %d", sum);
return 0;
}
Esempio
Si consideri il seguente programma. Cosa fa?
Il sorgente contiene (almeno) tre errori: quali sono?
#include <stdio.h>
#define SIZE 5 int main(void) { int a[SIZE];
printf("Inserisci dei numeri interi (Ctrl+D per terminare):\n");
int numelements = 0;
while (scanf("%d", a[numelements]) == 1) numelements++;
int sum = 0, i;
for (i = 0; i < numelements; i++) sum += a[i];
float mean = sum / numelements;
printf("\nLa media degli elementi letti è: %g\n", mean);
return 0;
}
Esempio
¨ Il programma nella slide precedente accetta in input una sequenza di interi terminati da EOF e ne calcola la media
¨ Il primo errore riguarda la scanf (correggerlo)
¨ Il secondo errore riguarda il fatto che la media, scritta in questo modo, sarà sempre intera (correggerlo)
¨ Il terzo errore riguarda il numero di elementi dell’array: cosa succede se l’utente inserisce più di 5 numeri?
¨ Il runtime C non segnala nessun errore e scrive in locazioni di memoria che non appartengono all’array. Questo porta a un comportamento indefinito.
¨ Esercizio: modificare il programma in modo da correggere questo errore 1 4 6 3 9 7 3 5
0 1 2 3 4