Sei sulla pagina 1di 45

Corso di Fondamenti di Informatica

Ingegneria delle Comunicazioni – BCOR


Ingegneria Elettronica – BELR

Introduzione al C

Unità 7 – Array

D. Bloisi, A. Pennisi, S. Peluso, S. Salza


Sommario – Unità 7
•  Array come collezione di elementi
•  Dichiarazione di variabili array
•  Creazione di array
•  Accesso agli elementi di un array
•  Espressioni che rappresentano array
•  Parametri di tipo array
•  Variabili array e puntatori
•  Ordinamento degli elementi di un array
•  Ricerca tra gli elementi di un array
•  Matrici

Array - Unità 7 2013/2014 Pagina 2


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 - Unità 7 2013/2014 Pagina 3


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 - Unità 7 2013/2014 Pagina 4
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 - Unità 7 2013/2014 Pagina 5


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 - Unità 7 2013/2014 Pagina 6


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 - Unità 7 2013/2014 Pagina 7
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 - Unità 7 2013/2014 Pagina 8


Esempio
int a[5]; // a e’ una variabile di tipo array di interi
// viene creato un array con 5 elementi di int
a[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 - Unità 7 2013/2014 Pagina 9


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 - Unità 7 2013/2014 Pagina 10


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.
Negli standard pre-C99 la lunghezza di un array deve
essere costante (nota a tempo di compilazione).
Array - Unità 7 2013/2014 Pagina 11
Esempio (2/3)
indice elemento variabile
0 ? a[0]
1 ? a[1]
2 ? a[2] int a[6];
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.

Array - Unità 7 2013/2014 Pagina 12


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 - Unità 7 2013/2014 Pagina 13


Creazione array in C99
#include <stdio.h>

int main() {
int a[6], b; Questa dichiarazione
a[0] = 15; è accettata dal C99
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));
}

Array - Unità 7 2013/2014 Pagina 14


Inizializzazione di array (1/3)
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;
Array - Unità 7 2013/2014 Pagina 15
Inizializzazione di array (2/3)
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

Array - Unità 7 2013/2014 Pagina 16


Inizializzazione di array (3/3)
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};

Array - Unità 7 2013/2014 Pagina 17


Errori in inizializzazione di array
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

Array - Unità 7 2013/2014 Pagina 18


Assegnazioni tra array
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

Array - Unità 7 2013/2014 Pagina 19


Relazione tra array e puntatori (1/2)
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.

Array - Unità 7 2013/2014 Pagina 20


Relazione tra array e puntatori (2/2)
Possiamo assegnare l’indirizzo (del primo
elemento) di un array ad una variabile puntatore.

int arr[7];
int *pi;
pi = arr;

L’ultima istruzione è equivalente a


pi = &arr[0];

Array - Unità 7 2013/2014 Pagina 21


Esempio: somma degli elementi di un
array
Frammento di codice che calcola la somma dei valori
contenuti in un array v di dimensione n.

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 - Unità 7 2013/2014 Pagina 22
Passaggio di parametri di tipo array
(1/2)
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 - Unità 7 2013/2014 Pagina 23


Passaggio di parametri di tipo array
(2/2)
La specifica del parametro formale int v[] sta ad
indicare che il tipo del parametro denotato da v è array di
int ma…

…in pratica, alla funzione viene passato il riferimento


all’array come int * v.

Attenzione: sizeof(v) non restituisce la dimensione


dell’array!

E’ possibile specificare il parametro direttamente come


int* v rendendo esplicito l’uso di un riferimento, ma
perdendo l’indicazione che il riferimento è ad un array.
Array - Unità 7 2013/2014 Pagina 24
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 - Unità 7 2013/2014 Pagina 25


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 - Unità 7 2013/2014 Pagina 26


Variabili array e puntatori
int A[4] = {1, 2, 3, 4};
int *B;
B = A;
int i;
for (i = 0; i < 4; i++)
printf("%d\n", B[i]);
B[0] = 10;
printf("A[0] = %d\n", A[0]);

La variabile array A può essere assegnata ad una


variabile puntatore ad interi B. Dopo l’assegnazione B
può essere usata come una variabile array.

Array - Unità 7 2013/2014 Pagina 27


Esecuzione
Il frammento di codice precedente, se eseguito,
produce il seguente output
1
2
3
4
A[0] = 10

Nota: una variabile array non può essere


assegnata ad un’altra variabile array.

Array - Unità 7 2013/2014 Pagina 28


Ricerca sequenziale di un elemento in
un array
Scriviamo una funzione cercaArray che prende come
parametri un array di interi a, un intero n corrispondente
alla dimensione dell’array ed un intero e da cercare
nell’array. La funzione restituisce 1 se il valore e è
presente nell’array, e 0 altrimenti:

int cercaArray(int a[], int n, int e) {


int i;
for (i = 0; i < n; i++) {
if (e == a[i])
return 1; //true
}
return 0; //false
} Array - Unità 7 2013/2014 Pagina 29
Esempio d’uso
int main() {
const int n = 3;
int x[n];
x[0] = 1; x[1] = 2; x[2] = 3;
printf("Array-x:\n");
int i;
for (i = 0; i < n; i++)
printf("%d\n", x[i]);
// cerca il valore 2 nell’array x
if ( cercaArray(x, n, 2) ) {
// l’elemento è stato trovato
printf("trovato\n");
}
else {
// l’elemento non è stato trovato
printf("non trovato\n");
}
}
Array - Unità 7 2013/2014 Pagina 30
Ricerca del valore massimo in un
array
Scriviamo una funzione massimoArray che prende come
parametro un array a e la sua lunghezza n e restituisce il
massimo valore in a (si assuma che l’array contenga
almeno un elemento).
Una possibile realizzazione è la seguente:
long massimoArray(long a[], int n) {
long max = a[0];
int i;
for (i = 1; i < n; i++)
if (a[i] > max)
max = a[i];
return max;
}
Array - Unità 7 2013/2014 Pagina 31
Esempio d’uso
int main () {
// creazione array x di 5 long
long x[5] = { 5, 3, 9, 1, 2 };
int i;
for (i = 0; i < 5; i++) // stampa 5 3 9 1 2
printf("%ld ", x[i]);
printf("\nmassimo = %ld\n",
massimoArray(x,5));
}
Output
5 3 9 1 2
massimo = 9
Array - Unità 7 2013/2014 Pagina 32
Invertire l’ordine dei valori di un array
Scriviamo una funzione rovesciaArray che prende come
parametro un array e ne modifica il contenuto mettendo gli
elementi in ordine inverso, dall’ultimo al primo.

void scambia(int *i, int *j)


{ int t=*i; *i=*j; *j=t; }

void rovesciaArray(int a[], int n) {


int temp;
int i;
for (i=0; i < n/2; i++)
scambia(&a[i],&a[n-i-1]);
return;
}
Array - Unità 7 2013/2014 Pagina 33
Esempio d’uso
int main () {
const int n = 5;
// creazione array x di 5 int
int x[n];
// inizializzazione
x[0] = 5; x[1] = 3; x[2] = 9; x[3] = 5; x[4] = 12;
int i;
for (i = 0; i < n; i++) // stampa 5 3 9 5 12
printf("%d ", x[i]);
printf("\n");
rovesciaArray(x, n); // rovescia l’array x
for (i = 0; i < n; i++) // stampa 12 5 9 3 5
printf("%d ", x[i]);
printf("\n");
return 0;
}
Array - Unità 7 2013/2014 Pagina 34
Matrici
Una matrice è una collezione in forma tabellare
di elementi dello stesso tipo, ognuno dei quali è
indicizzato da una coppia di numeri che
identificano riga e colonna dell’elemento.

Una matrice può essere rappresentata in C


mediante un array multidimensionale.

Array - Unità 7 2013/2014 Pagina 35


Esempi

Dichiarazione di una matrice 3x5 accessibile


mediante la variabile m:
int m[3][5];

Dichiarazione di una matrice NxM mat


int mat[N][M];

Array - Unità 7 2013/2014 Pagina 36


Accesso agli elementi di una matrice
Per accedere ai singoli elementi della matrice si può
procedere come segue:

// assegnazione dell’elemento della matrice m


// alla riga 1, colonna 2
m[1][2] = 39;
// assegnazione dell’elemento della matrice m
// alla riga 0, colonna 0
m[0][0] = 4;
printf("%d\n", m[1][2]); // stampa 39

Array - Unità 7 2013/2014 Pagina 37


Rappresentazione in memoria

int M[3][2]; //Matrice con 3 righe e 2 colonne


!

I riga II riga III riga

&(M[i][j]) == M[0] + 2 * i + j;!

Array - Unità 7 2013/2014 Pagina 38


Espressioni che denotano oggetti
matrice
Poiché una matrice è semplicemente un array i cui
elementi sono a loro volta array, nella definizione di
matrici è possibile utilizzare espressioni che denotano
matrici come nel seguente esempio:

int m[][2] = {
{ 3, 5 },
{ 9, 12 }
};

Si noti che solo la prima dimensione dell’array può


essere non specificata.

Array - Unità 7 2013/2014 Pagina 39


Esempio
int main () {
int m[][2] = {
{ 3, 5 }, Cosa stampa questo
{ 9, 12 } programma?
};
int i, j;
for(i = 0; i < 2; i++) {
for(j = 0; j < 2; j++) {
printf("%d ", m[i][j]);
}
printf("\n");
}
}
Array - Unità 7 2013/2014 Pagina 40
Numero di righe e colonne di una
matrice
Usando la funzione sizeof è possibile risalire al numero
di elementi dell’array, anche nel caso multidimensionale.

int x[][2]= {{ 3, 5}, {9, 12}};


printf("dimensione array %d bytes\n",
sizeof(x));

Stampa il valore 16, che corrisponde al numero di byte


per memorizzare 4 int (4 byte ciascuno)

Array - Unità 7 2013/2014 Pagina 41


Stampa di una matrice per righe

for (i = 0; i < N; i++) {


for (j = 0; j < M; j++)
printf("%d ", m[i][j]);
printf("\n");
}

Si noti che per accedere a tutti gli elementi della matrice m usiamo
due cicli for annidati: quello esterno scandisce le righe (i), quello
interno scandisce gli elementi di ogni riga (j).
Quando tutti gli elementi di una riga sono stati stampati, viene
scritto un ritorno a capo.
Array - Unità 7 2013/2014 Pagina 42
Stampa di una matrice per colonne

for (i = 0; i < M; i++) {


for (j = 0; j < N; j++)
printf("%d ", m[j][i]);
printf("\n");
}

Array - Unità 7 2013/2014 Pagina 43


Somma di matrici
Si assuma che A e B abbiano le stesse dimensioni (stesso
numero di righe e stesso numero di colonne).
Vogliamo definire i valori di una nuova matrice C ottenuta
sommando gli elementi corrispondenti di A e B.

for (i = 0; i < N; i++)


for (j = 0; j < M; j++)
C[i][j] = A[i][j] + B[i][j];

Per accedere a tutti gli elementi della matrice A (e a


quelli di B) usiamo due cicli for annidati: quello esterno
scandisce le righe (i), quello interno scandisce gli
elementi di ogni riga (j).
Array - Unità 7 2013/2014 Pagina 44
Passaggio di parametri matrice
Nel passaggio dei parametri per le matrici (e in generale
per array multi-dimensionali) è necessario specificare
nell’intestazione della funzione tutte le dimensioni
dell’array, eccetto la prima.
Per le matrici, è quindi necessario specificare il numero di
colonne.

void stampaMatrice (int A[][3], ...)


{
...
}

Array - Unità 7 2013/2014 Pagina 45