Upload
khangminh22
View
0
Download
0
Embed Size (px)
Citation preview
Corso di Fondamenti di Informatica
Ingegneria delle Comunicazioni BCOR
Ingegneria Elettronica BELR
Parte 7
Array
Domenico Daniele Bloisi
2010/2011Array
Parte 7
Pagina 2
Docenti
Parte I – prof. Silvio Salza
http://www.dis.uniroma1.it/~salza/fondamenti.htm
Parte II – ing. Domenico Daniele Bloisi
http://www.dis.uniroma1.it/~bloisi/didattica/fondinf1011.html
Nota: %7E corrisponde alla tilde ~
Pagina 3
Informazioni Generali
ing. Domenico Daniele Bloisi, PhD
Dipartimento di Informatica e Sistemistica
Via Ariosto 25
(adiacente Piazza Dante,
A fermate Manzoni, Vittorio Emanuele,
Tram 3 fermata via Labicana)
mailto:[email protected]
http://www.dis.uniroma1.it/~bloisi
2010/2011Array
Parte 7
Ricevimento
Pagina 4
Martedì 15.00 – 17.00
DIS, via Ariosto 25
Aula docenti adiacente aula A4
Si consiglia di inviare una email per conferma e
di controllare la bacheca degli avvisi
http://www.dis.uniroma1.it/~bloisi/didattica/fondinf1011.html#Avvisi
2010/2011Array
Parte 7
Pagina 52010/2011
Sommario – Parte 7
• Array come collezione di elementi
• Dichiarazione di variabili array
• Creazione di array
• Accesso agli elementi di un array
• Espressioni che rappresentano array
• Passaggio di parametri di tipo array
• Variabili array e puntatori
• Ordinamento degli elementi di un array
• Ricerca tra gli elementi di un array
• Matrici
Array
Parte 7
Pagina 62010/2011
Array
Un array contiene una collezione di elementi dello
stesso tipo, ognuno dei quali è indicizzato (ovvero
identificato) da un numero.
Una variabile di tipo array contiene un riferimento
alla collezione di elementi che costituisce l’array.
Array
Parte 7
Pagina 72010/2011
Array
Array
Parte 7
Per usare un array in C dovremo:
1. dichiarare una variabile di tipo array
specificandone la dimensione (numero di
elementi dell’array);
2. accedere mediante la variabile array agli
elementi dell’array per assegnare o per leggere
i loro valori (come se fossero singole variabili).
Pagina 92010/2011
Dichiarazione di variabili array
Sintassi
tipo nomeArray [n] ;
dove
tipo è il tipo degli elementi dell'array a cui si
riferisce la variabile che si sta dichiarando
nomeArray è il nome della variabile (riferimento
ad) array che si sta dichiarando
n è il numero di elementi dell'array che si sta
dichiarando
Array
Parte 7
Pagina 102010/2011
Semantica
Dichiara una variabile nomeArray che potrà
riferirsi ad un array di n elementi di tipo tipo.
Esempio
int a[5]; // a e’ una variabile di
// tipo riferimento ad
// array di 5 interi
Array
Parte 7
Pagina 112010/2011
Cassettiera
typedef int cassetto;
cassetto cassettiera[7];
cassettiera e’ una variabile di tipo
riferimento ad array di 7 cassetti(i.e., variabili di tipo cassetto)
Array
Parte 7
Pagina 122010/2011
Array e funzione sizeof
La funzione sizeof() consente di avere informazioni
sulle dimensioni di un array dichiarato staticamente.
Esempio
int a[5];
printf("dimensione array %d bytes\n",
sizeof(a));
printf("dimensione array %d elementi\n",
sizeof(a)/sizeof(int));
Se un int ha dimensione 4 bytes la stampa sarà
dimensione array 20 bytes (= 4 bytes × 5 elementi)
dimensione array 5 elementi (= 20 bytes / 4 bytes)
Array
Parte 7
Pagina 132010/2011
Accesso ai singoli elementi di un array
Sintassi
nomeArray[indice]
dove
nomeArray è il nome della variabile array che
contiene un riferimento all'array a cui si vuole
accedere indice è una espressione di tipo int non
negativa che specifica l'indice dell'elemento a
cui si vuole accedere.
Array
Parte 7
Pagina 142010/2011
Semantica
Accede all'elemento di indice indice dell'array
nomeArray per leggerlo o modicarlo.
Se l'array nomeArray contiene n elementi, la
valutazione dell'espressione indice deve fornire
un numero intero nell'intervallo [0, n-1]
Se ciò non avviene, si ha un comportamento non
predicibile, con la possibilità di ottenere un errore
in esecuzione.
Array
Parte 7
Pagina 152010/2011
Esempio
int a[5]; // a e’ una variabile di tipo array di interi
// viene creato un array con 5 elementi di inta[0] = 23; // assegnazione al primo elemento dell’array
a[4] = 92; // assegnazione all’ultimo elemento dell’array
a[5] = 16; // ??????: l’indice 5 non e’ nell’intervallo [0,4]
Si osservi che dichiarando una variabile di tipo array,
viene contestualmente creato l’array a cui essa si
riferisce, e quindi l’array può essere direttamente
utilizzato.
Array
Parte 7
Pagina 162010/2011
Importante
Se l’array contiene N elementi (N=5 nell’esempio),
gli indici devono essere necessariamente interi
nell’intervallo [0, N-1], altrimenti può verificarsi un
errore quando il programma viene eseguito.
Nell’esempio precedente, si può avere un errore quando viene eseguita l’istruzione a[5]=16;
Array
Parte 7
Pagina 17
Compilatore C e Array
Mentre esistono dei linguaggi di programmazione
che sono in grado di segnalare errori di
superamento dei limiti dell’array, il compilatore C
in genere non aiuta il programmatore.
Errori di questo tipo possono avere effetti poco
comprensibili dato che corrispondono alla
scrittura/lettura di valori che non riguardano
l’array!
Array
Parte 7
2010/2011
Pagina 182010/2011
Esempio (1/3)
int a[6];
Alloca un array di 6 elementi, ovvero 6 locazioni di
memoria consecutive, ciascuna contenente un
intero.
6 è la lunghezza dell’array.
In C l’indice degli elementi va sempre da 0 a
lunghezza - 1.
Array
Parte 7
Negli standard pre-C99 la lunghezza di un array deve
essere costante (nota a tempo di compilazione).
Pagina 192010/2011
Esempio (2/3)
indice elemento variabile
0 ? a[0]
1 ? a[1]
2 ? a[2]
3 ? a[3]
4 ? a[4]
5 ? a[5]
a[i] denota l’elemento dell’array a di indice i.
Ogni elemento dell’array è una variabile.
int a[6];
Array
Parte 7
Pagina 202010/2011
Esempio (3/3)
int a[6], b;
a[0] = 15;
b = a[0];
a[1] = a[0] + b;
printf("%d\n", a[0] + a[1]);
Cosa stampa questo
frammento di codice?
Array
Parte 7
Pagina 212010/2011
Creazione array in C99
Array
Parte 7
#include <stdio.h>
int main() {
int a[6], b;
a[0] = 15;
b = a[0];
a[1] = a[0] + b;
printf("b = %d\n", b);
int c[b];
printf("elementi di c = %d\n",
sizeof(c)/sizeof(int));
}
Questa dichiarazione
è accettata dal C99
Pagina 222010/2011
Inizializzazione di array
Array
Parte 7
E’ possibile in C scrivere espressioni che
denotano array, specificando una lista di
espressioni del tipo degli elementi dell’array
della forma:
{ espressione1, espressione2, ..., espressionek }
Esempio
int v[4] = { 4, 6, 3, 1 };
è del tutto equivalente a:
int v[4];
v[0] = 4; v[1] = 6; v[2] = 3; v[3] = 1;
Pagina 232010/2011
Errori in inizializzazione
Array
Parte 7
Le espressioni che denotano array possono
essere usate solo contestualmente alla
dichiarazione di un array.
Il seguente esempio produce un errore in
compilazione:
int v[4];
v = { 4, 6, 3, 1 }; // ERRORE
Pagina 242010/2011
Inizializzazione
Array
Parte 7
Se sono presenti meno inizializzazioni del totale degli
elementi, gli elementi rimanenti vengono posti a 0
int n[10] = {3}; // azzera i rimanenti 9
// elementi del vettore
float f[5] = {0.0} // pone i 5 elementi pari
// a 0.0
int y[7] = {}; // ERRORE
Pagina 252010/2011
Esempio
Array
Parte 7
indice elemento variabile
0 3 a[0]
1 0 a[1]
2 0 a[2]
3 0 a[3]
4 0 a[4]
5 0 a[5]
a[i] denota l’elemento dell’array a di indice i.
Ogni elemento dell’array è una variabile.
int a[6] = {3};
Pagina 262010/2011
Inizializzazione
Array
Parte 7
Se si omette la dimensione dell’array in una
inizializzazione tramite lista di elementi, la
lunghezza dell’array sarà la lunghezza di tale lista
Esempio
int n[] = {1, 2, 3};
equivale a
int n[3] = {1, 2, 3};
Pagina 272010/2011
Assegnazioni tra array
Array
Parte 7
Non si possono effettuare direttamente delle
assegnazioni tra array.
int a[3] = {11, 22, 33};
int b[3];
b = a; // ERRORE
Questo codice genera un errore in
compilazione
Pagina 282010/2011
Relazione tra array e puntatori (1/3)
Array
Parte 7
In generale non sappiamo cosa contengono le
celle di memoria adiacenti una data cella.
L’unico caso in cui sappiamo quali sono le
locazioni di memoria successive e cosa
contengono si ha quando utilizziamo degli array.
Pagina 292010/2011
Relazione tra array e puntatori (2/3)
Array
Parte 7
In C il nome di un array è in realtà l’indirizzo
dell’elemento di indice 0.
int array[10];
printf("%p %p", array, &array[0]);
array e &array[0] hanno lo stesso valore.
printf("%p %p", array, &array[0]);
stampa 2 volte lo stesso indirizzo.
Pagina 302010/2011
Relazione tra array e puntatori (3/3)
Possiamo far puntare un puntatore al primo elemento di
un vettore.
int arr[7];
int *pi;
pi = arr;
L’ultima istruzione è equivalente api = &arr[0];
Un array è un puntatore costante e possiamo
assegnarlo ad una variabile di tipo puntatore.
Array
Parte 7
Pagina 312010/2011
Creazione di un array con allocazione
dinamica della memoria
Invece di far puntare pi ad un vettore allocato attraverso
una dichiarazione (quindi statico, creato nello stack),
possiamo farlo puntare ad una zona di memoria allocata
dinamicamente (quindi nello heap):
int *pi, dim;
scanf("%d", &dim);
pi = malloc(dim * sizeof(int));
if(pi != NULL)
pi[dim-1] = 3;
Array
Parte 7
Pagina 322010/2011
Esercizio
Esercizio 7.1
Scrivere un programma che legga un intero N da tastiera,
allochi dinamicamente un array di N interi, legga N interi
da tastiera e stampi gli N interi in ordine inverso.
EsempioInserire N:
4
Inserire 4 interi:
12 34 56 78
78 56 34 12
Array
Parte 7
Pagina 332010/2011
Esempio: somma degli elementi di un
array di interi
Frammento di codice che calcola la somma dei valori
contenuti in un array
int i, somma = 0;
for (i = 0; i < n; i++)
somma += v[i];
Nella variabile somma viene memorizzata la somma
parziale degli elementi dell’array fino al valore corrente
dell’indice.
Si noti il riferimento alla variabile n che contiene la
dimensione dell’array.
Array
Parte 7
Pagina 342010/2011
Passaggio di parametri di tipo array
La funzione sommaValoriArray prende come
parametro un array di interi e restituisce la
somma dei valori contenuti nell’array
int sommaValoriArray(int v[], int n) {
int i, somma = 0;
for (i = 0; i < n; i++)
somma += v[i];
return somma;
}
Array
Parte 7
Pagina 352010/2011
Passaggio di parametri di tipo array
La specifica del parametro formale int v[] sta
ad indicare che il tipo del parametro denotato da v è array di int.
In pratica, alla funzione viene passato il
riferimento all’array.
Sarebbe stato possibile specificare il parametro anche come: int* v rendendo esplicito l’uso di
un riferimento, ma perdendo l’indicazione
esplicita che il riferimento è ad un array.
Array
Parte 7
Pagina 362010/2011
Esempio d’uso
int main() {
const int n = 4;
// creazione array di n elementi
int x[n];
// l’elemento con indice i di x contiene i
int i;
for (i = 0; i < n; i++)
x[i] = i;
// stampa la somma dei primi N numeri
printf("%d\n", sommaValoriArray(x,n));
}
Array
Parte 7
Pagina 372010/2011
Nota
Il passaggio di un array è un passaggio per
indirizzo. Quindi, la funzione può modificare gli
elementi dell’array che viene passato come
parametro.
Il motivo è legato al fatto che quando si passa
un array come parametro ad una funzione, in
realtà si sta passando l’indirizzo dell’elemento
di indice 0.
Array
Parte 7
Pagina 382010/2011
Esempio
E’ spesso utile passare la dimensione dell’array come
ulteriore parametro.
void stampa(double arr[], int arr_dim) {
int i;
for (i = 0; i < arr_dim; i++)
printf("%d: %f\n", i, arr[i]);
}
int main() {
double d[4] = {1.1, 2.2, 3.3, 4.4};
stampa(d, 4);
}
Array
Parte 7
Pagina 392010/2011
Esercizi
Esercizio 7.2
Scrivere una funzioneprodottoScalare(double A[], double B[], int n)
che calcoli il prodotto scalare degli array A e B,
assumendo che essi abbiano lo stesso numero di elementi pari ad n.
Si ricorda che il prodotto scalare di A per B è ottenuto
come somma dei prodotti A[i]*B[i] per ogni i,
0 ≤ i < n, dove n è il numero di elementi dell’array.
Scrivere un programma per verificare il comportamento
della funzione.
Array
Parte 7
Pagina 402010/2011
Esercizi
Array
Parte 7
Esercizio 7.3
Scrivere una funzioneint contaPari(int array[], int n)
che restituisca il numero di elementi pari contenuti
nell’array passato come argomento.
Scrivere un programma per verificare il comportamento
della funzione.