L'uso degli array risulta comodo quando c'è l'esigenza di memorizzare temporaneamente in ram i dati letti da file per elaborarli in un momento successivo (eventualmente per rileggerli più volte).
L'array è una variabile che consente di memorizzare temporaneamente più dati dello stesso tipo (primitivi o di riferimento); è un dato strutturato, i cui elementi (o componenti) si distinguono tra loro per la posizione che occupano all’interno, indicata da un numero detto indice.
L’utilizzo dell’indice determina un ordine interno conferendo alla variabile una struttura, cioè un’organizzazione interna che facilita il reperimento e il trattamento dei dati nelle elaborazioni; quindi l’array è un insieme ordinato di dati (dello stesso tipo), in cui esiste una corrispondenza biunivoca tra indice ed elemento.
Grazie all’utilizzo di questa variabile, in una prima fase carico tutti i dati necessari, i voti; poi scandisco, o “leggo” con un ciclo dal primo all’ultimo elemento (da 0 a N-1) l’array sommando i voti (anche se potevo farlo durante l’inserimento) per calcolare la media; successivamente rileggo l’’array controllando (o contando) quali voti superano il valore medio.
ATTENZIONE: nel linguaggio C (come in molti altri) la memorizzazione di N elementi in un array parte dalla posizione 0: la prima posizione è 0, la seconda è 1 …l’ultima posizione è la N-1; quindi, se devo memorizzare N elementi, le posizioni vanno da 0 a N-1.
Un array si dichiara con: tipo nomevettore[dimensione];
Ad esempio:
int temperature[26]; float voti[MAX]; // con MAX costante.
Occorre definire a priori una dimensione fisica massima (26, oppure anche usando una costante come MAX); successivamente è possibile utilizzare una dimensione logica inferiore alla dimensione fisica massima, ridimensionando il vettore.
I compilatori moderni permettono di dichiarare un array usando una variabile come dimensione. In questo caso la variabile deve essere inizializzata prima della dichiarazione del vettore e, ovviamente, la modifica del valore della variabile non influisce sulla dimensione del vettore, che rimane costante.
int n=26;
int temperature[n];
Devono essere acquisiti i valori da memorizzare in ogni cella dell’array; ogni elemento è identificato dalla posizione (VOTO[1], VOTO[2],…VOTO[I]).
Il seguente esempio assegna il valore 0 a tutti gli elementi di un array (cioè inizializza l'array a 0).
int i, vettore[N_ELEMENTI]; for(i=0;i<N_ELEMENTI; i++) vettore[i]=0;
Il prossimo esempio riempie un array con valori acquisiti in input.
int i; float temperature[N_GIORNI]; // Gli indici variano da 0 a N_GIORNI-1 for(i=0;i<N_GIORNI; i++){ // Memorizzo la temperatura del giorno i+1 nell'elemento di indice i printf("Inserisci la temperatura del giorno %d: ", i+1); scanf("%d", &temperature[i]); }
L'array può essere caricato con gli elementi in fase di dichiarazione:
int v[5]={1,2,3,4,5}; char v[7]={'e','n','r','i','c','a','\0'};
Per “passare” l’array a una funzione si utilizza il puntatore (cioè si fa riferimento all’indirizzo di memoria del primo elemento); l’array si passa sempre per indirizzo (o meglio, si passa per valore l’indirizzo di memoria) anche se non viene modificato dalla funzione.
Il seguente esempio mostra il prototipo di una funzione che accetta come parametro un array di numeri reali.
Il primo parametro è un puntatore a float e accoglierà l'indirizzo del primo elemento dell'array.
Il secondo parametro (int) rappresenta il numero di elementi dell'array.
float calcolaMedia(float* array, int nElementi);
Infatti l’array viene allocato a partire da una locazione di memoria: in tale locazione viene posto il primo elemento.
Conoscendo l’indirizzo del primo elemento (inizio dell’array), i successivi elementi sono recuperabili conoscendo la dimensione del tipo di dato (numero di byte del tipo di dato). Il puntatore è una variabile in grado di memorizzare un indirizzo di memoria.
Nella chiamata della funzione occorre specificare il nome assegnato all'array (che indica l'indirizzo del primo elemento) e il numero di elementi.
float temperature[26]; float media; ... // Il nome dell'array rappresenta l'indirizzo del primo elemento media=calcolaMedia(temperature, 26);
ARRAY DI ARRAY
Un array di array è un array i cui elementi sono array, cioè un array a due dimensioni.
Posso immaginarlo come una tabella:
Ogni riga può essere pensata come un array.
Ogni singolo elemento è individuato da una posizione di riga i e di colonna j, che devono essere gestiti.
In realtà la matrice in memoria è un insieme di elementi consecutivi.
// MAXR e MAXC sono il numero massimo di righe e colonne (dimensione fisica)int matrice[MAXR][MAXC];
Per passare una matrice a una funzione posso omettere il numero di righe, ma devo specificare obbligatoriamente il numero di colonne.
Come sempre, è buona norma passare il numero di righe come parametro.
void funzione1(int nRighe, int mat[][30]);
Oppure:
// Passo un puntatore ad un array di 30 elementi,// cioè un puntatore alla prima riga della matricevoid funzione2(int nRighe, int (*mat)[30]);
I moderni compilatori C permettono di passare entrambe le dimensioni come parametri, ripetendo i nomi dei parametri all'interno delle parentesi quadre.
In questo modo posso rendere la funzione indipendente dalle dimensioni della matrice.
void funzione3(int r, int c, int mat[r][c]);
Nella chiamata, la matrice viene passata alla funzione specificandone il nome (corrispondente al puntatore alla prima riga della matrice).
int m[10][20]; funzione1(10,m); funzione2(10,m); funzione3(10,20,m);
#define MAXC 30// Carica le prime n righe e m colonne della matrice mat con valori inseriti dall'utente.// La dimensione fisica di ogni riga è rappresentata dalla costante MAXC.void carica(int r,int c,int (*mat)[MAXC]) { int i,j; if(c>MAXC) c=MAXC; // Controllo la dimensione specificata dal parametro c for(i=0; i<r; i++) //per ogni riga for(j=0; j<c; j++) //per ogni colonna scanf("%d",&mat[i][j]); } // Stampa gli elementi della matricevoid stampa(int r,int c,int (*m)[MAXC]) { int i,j; for(i=0; i<r; i++) { //per ogni riga for(j=0; j<c; j++) //per ogni colonna della riga printf("%d ",m[i][j]); //stampa il dato con un spazio printf("\n"); //al termine va a capo per la riga successiva } }
Oppure, con i moderni compilatori:
// Carica la matrice mat di r righe e c colonne con valori inseriti dall'utente.void carica(int r,int c,int mat[r][c]) { int i,j; for(i=0; i<r; i++) //per ogni riga for(j=0; j<c; j++) //per ogni colonna scanf("%d",&mat[i][j]); } // Stampa gli elementi della matricevoid stampa(int r,int c,int m[r][c]) { int i,j; for(i=0; i<r; i++) { //per ogni riga for(j=0; j<c; j++) //per ogni colonna della riga printf("%d ",m[i][j]); //stampa il dato con un spazio printf("\n"); //al termine va a capo per la riga successiva } }