• Non ci sono risultati.

Array. Unità 7. Corso di Laboratorio di Informatica Ingegneria Clinica BCLR. Domenico Daniele Bloisi

N/A
N/A
Protected

Academic year: 2022

Condividi "Array. Unità 7. Corso di Laboratorio di Informatica Ingegneria Clinica BCLR. Domenico Daniele Bloisi"

Copied!
42
0
0

Testo completo

(1)

Corso di Laboratorio di Informatica Ingegneria Clinica – BCLR

Unità 7

Array

Domenico Daniele Bloisi

(2)

Docente

Ing. Domenico Daniele Bloisi, PhD Ricercatore

Dipartimento di Ingegneria Informatica, Automatica e Gestionale “Antonio Ruberti”

Via Ariosto 25

(adiacente Piazza Dante, Manzoni

Tram 3 fermata via Labicana) email: bloisi@dis.uniroma1.it

home page: http://www.dis.uniroma1.it/~bloisi

(3)

Ricevimento

In aula, subito dopo le lezioni

Su appuntamento (tramite invio di una email) presso:

Dipartimento di Ingegneria Informatica, Automatica e Gestionale “Antonio Ruberti”,

via Ariosto 25 - II piano, stanza A209

Si invitano gli studenti a controllare regolarmente la bacheca degli avvisi

http://www.dis.uniroma1.it/~bloisi/didattica/labinf1415.html#Avvisi

(4)

Orari

Lunedì 12.00 – 13.30

Aula 4, via del Castro Laurenziano 7A

Martedì 14.00 – 17.15

Aula 15, Laboratorio Didattico via Tiburtina 205

Mercoledì 12.00 – 13.30

Aula 4, via via del Castro Laurenziano 7A

(5)

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

• Passaggio di parametri di tipo array

• Variabili array e puntatori

• Ordinamento degli elementi di un array

• Ricerca tra gli elementi di un array

• Matrici

(6)

Array

Un array è

Una collezione di elementi dello stesso tipo

Ogni elemento è indicizzato (cioè identificato) da un numero

Una variabile di tipo array è

un riferimento alla collezione di elementi che costituisce l’array

(7)

Array

Per usare un array in C si deve:

1. Dichiarare una variabile di tipo array,

specificandone la dimensione (cioè il 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).

(8)

Array

(9)

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

(10)

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

(11)

Cassettiera

typedef int cassetto;

cassetto cassettiera[7];

cassettiera è una variabile di tipo riferimento ad array di 7 cassetti

(cioè variabili di tipo cassetto)

(12)

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 byte\n", sizeof(a));

printf("dimensione array %d elementi\n", sizeof(a)/sizeof(int));

Se un int ha dimensione 4 byte la stampa sarà

dimensione array 20 byte (= 4 byte × 5 elementi)

dimensione array 5 elementi (= 20 byte / 4 byte)

(13)

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.

(14)

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.

(15)

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

l’array può, quindi, essere direttamente utilizzato.

(16)

Importante

Se l’array contiene N elementi (N=5 nell’esempio), gli indici devono essere necessariamente interi

nell’intervallo [0, N-1], altrimenti potrebbe verificarsi un errore in esecuzione.

Nell’esempio precedente, si potrebbe avere un errore durante l’esecuzione dell’istruzione

a[5]=16;

(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, poichè corrispondono alla

scrittura/lettura di valori che non riguardano l’array!

(18)

Compilatore C e Array

#include <stdio.h>

int main() { int a[5];

a[0] = 23;

a[4] = 92;

a[5] = 16;

}

Il compilatore gcc non segnala alcun errore.

(19)

Esempio (1/3)

int a[6];

Alloca un array di 6 elementi, cioè 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).

(20)

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];

(21)

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?

(22)

Creazione array in C99

#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

(23)

Inizializzazione di array

E’ possibile, in C, scrivere espressioni che denotino array, specificando una lista di espressioni del tipo degli elementi dell’array della forma:

{ espressione_1, espressione_2, ..., espressione_k } Esempio

int v[4] = { 4, 6, 3, 1 };

è equivalente a:

int v[4];

v[0] = 4; v[1] = 6; v[2] = 3; v[3] = 1;

(24)

Errori in inizializzazione

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

(25)

Inizializzazione

Se sono presenti meno inizializzazioni del totale degli elementi, gli elementi rimanenti verranno inizializzati a 0 int n[10] = {3}; // azzera i rimanenti 9

// elementi del vettore

float f[5] = {0.0f} // pone i 5 elementi a 0.0 int y[7] = {}; // ERRORE

(26)

Esempio

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};

(27)

Inizializzazione

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};

(28)

Assegnazioni tra array

Non si possono effettuare direttamente delle assegnazioni tra array.

int a[3] = {11, 22, 33};

int b[3];

b = a; // ERRORE

Il frammento di codice riportato sopra genera un errore in compilazione

(29)

Relazione tra array e puntatori (1/3)

In generale, data una cella, non è possibile sapere cosa contengano le celle di memoria adiacenti ad essa.

L’unico caso in cui è possibile conoscere quali siano le locazioni di memoria successive e cosa

contengano si ha quando vengono utilizzati degli array.

(30)

Relazione tra array e puntatori (2/3)

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.

(31)

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 a pi = &arr[0];

Un array è un puntatore costante e può essere assegnato a una variabile di tipo puntatore.

(32)

Creazione di un array con allocazione dinamica della memoria

Invece di far puntare pi ad un vettore allocato attraverso una dichiarazione (quindi creato nello stack), possiamo farlo

puntare a una zona di memoria allocata dinamicamente (creata nello heap):

int *pi, dim;

scanf("%d", &dim);

pi = malloc(dim * sizeof(int));

if(pi != NULL)

pi[dim-1] = 3;

(33)

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.

Esempio

Inserire N:

4

Inserire 4 interi:

12 34 56 78 78 56 34 12

(34)

Esempio: somma degli elementi di un array di interi

Il seguente frammento di codice 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.

(35)

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;

}

(36)

Passaggio di parametri di tipo array

La specifica del parametro formale int v[] sta ad indicare che il tipo del parametro denotato da v è un 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.

(37)

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));

}

(38)

Nota

Il passaggio di un array è un passaggio per

indirizzo. Quindi, la funzione può modificare gli elementi dell’array che viene passato come

parametro.

Questo è possibile perchè quando si passa un

array come parametro ad una funzione, in realtà si sta passando l’indirizzo dell’elemento di indice 0 dell'array e non una copia dell’array.

(39)

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);

return EXIT_SUCCESS;

(40)

Esercizi

Esercizio 7.2

Scrivere una funzione

prodottoScalare(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.

(41)

Esercizi

Esercizio 7.3

Scrivere una funzione

int 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 contaPari.

(42)

Esercizi

Esercizio 7.4

Scrivere una funzione

double max(double A[], int n)

che restituisca il valore massimo contenuto nell’array passato come argomento (che ha dimensione n).

Scrivere un programma per verificare il comportamento della funzione max.

Riferimenti

Documenti correlati

¨  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 costruttore che consente di definire una nuova TabellaVoti; il costruttore deve prendere in ingresso un array di stringhe che definisce la sequenza dei nomi degli studenti,

codice strumento prezzo FLT flauto 2500 VLN violino 8000. $inv_art

dove numero_elementi deve essere o un valore intero, o un’espressione costante oppure una variabile che sia stata però istanziata prima della definizione dell'array; ad esempio,

I: il valore di ciascun elemento dello array bidimensionale Pi: il numero degli elementi da inserire non può essere maggiore della cardinalità dell’array. U: l’array

Prima di chiamare la free sull'array chiamarla su ogni

– Soluzione: si passa alla funzione un ulteriore parametro di tipo array, che viene “riempito” con il risultato.. E i parametri di

● Se gli estremi degli scaglioni e/o le percentuali cambiano, devo cambiare solo l'array e non il programma che fa la ricerca!.. Algoritmi su