• dichiarazioni e accesso agli elementi • indici di array • cicli for per

Array
• dichiarazioni e accesso agli elementi
• indici di array
• cicli for per accesso sequenziale
• elementi di array come argomenti di funzioni
• array come argomenti di funzioni
• ricerca e ordinamento
• array multidimensionali
1
Struttura dati
collezione di dati correlati, a cui viene associato un
unico nome simbolico
Array
collezione di dati dello stesso tipo;
i dati appartenenti all’array sono detti elementi dell’array;
gli elementi dell’array vengono memorizzati in
celle di memoria contigue
2
Dichiarazione di array
double x[8];
associa 8 celle di memoria al nome x;
ogni elemento dell’array x può contenere un singolo
valore di tipo double
3
Accesso agli elementi dell’array
per utilizzare i dati contenuti nell’array, accedo agli
elementi specificando il nome dell’array e la posizione
dell’elemento nell’array
la variabile indiciata x[0] si riferisce al primo elemento
dell’array; x[1] si riferisce all’elemento seguente e
x[7] all’ultimo elemento
l’intero tra parentesi quadre si chiama indice dell’array;
il suo valore deve essere compreso tra 0 e
numero_di_celle - 1
4
Esempio
x[0] x[1] x[2] x[3] x[4] x[5] x[6] x[7]
16.0 12.0
6.0
8.0
printf(“%.1f”, x[0]);
x[3] = 25.0;
sum = x[0] + x[1];
sum += x[2];
x[3] += 1.0;
x[2] = x[0] + x[1];
2.5
12.0 14.0 -54.5
visualizza 16.0
memorizza 25.0 in x[3]
memorizza 28.0 in sum
aggiunge 6.0 a sum, il cui
contenuto diventa 34.0
aggiunge 1.0 a x[3], il cui
contenuto diventa 26.0
memorizza 28.0 in x[2]
x[0] x[1] x[2] x[3] x[4] x[5] x[6] x[7]
16.0 12.0 28.0 26.0
2.5
12.0 14.0 -54.5
5
Esempio
memorizzazione dei voti degli studenti all’esame di
Laboratorio 1
#define NUM_STUDENTI 80
int matr[NUM_STUDENTI];
int voto[NUM_STUDENTI];
array paralleli: due o più array, aventi lo stesso numero
di elementi, utilizzati per memorizzare informazioni
correlate
6
Esempio
punteggio ottenuto da uno studente negli esercizi svolti
durante la settimana
#define NUM_CLASS_DAYS 5;
typedef enum {monday, tuesday, wednesday,
thursday, friday}
class_day_t;
int score[NUM_CLASS_DAYS];
score[tuesday] = 8;
7
Esempio
double x[5], sum, y[6];
int factor[11], n, index;
posso dichiarare più array in una singola
dichiarazione;
posso dichiarare insieme array e variabili semplici.
8
Inizializzazione di array
E’ possibile inizializzare un array al momento della
sua dichiarazione.
Se l’array viene inizializzato completamente, posso
omettere la dimensione (che verrà dedotta dal numero di
elementi nella lista di inizializzazione)
int prime_lt_50[] = {1, 2, 3, 5, 7, 11, 13,
17, 19, 23, 29, 31, 37,
41, 43, 47};
9
Dichiarazione di array
sintassi
element_type aname[size];
element_type aname[size] = {initialization_list};
element_type aname[ ] = {initialization_list};
esempio
double a[A_SIZE];
char vowels[ ] = {‘a’, ‘e’, ‘i’, ‘o’, ‘u’};
10
Dichiarazione di array
Viene allocato spazio in memoria per contenere l’array
aname, costituito da size elementi.
Ogni elemento può contenere un dato di tipo element_type
(es. int, double, char).
Si accede ai singoli elementi mediante le variabili indiciate
aname[0], aname[1], . . ., aname[size - 1].
La dimensione size è un’espressione costante di tipo int.
11
Dichiarazione di array
Nella dichiarazione con inizializzazione, la dimensione
size è opzionale; se viene omessa, la dimensione dell’
array è data dalla lunghezza di initialization_list.
La initialization_list è formata da una sequenza di
espressioni costanti di tipo element_type, separate
da virgole.
L’elemento 0 dell’array viene inizializzato con il primo
valore in initialization_list, l’elemento 1 viene
inizializzato con il secondo valore, e così via.
12
Indici di array
Gli indici sono utilizzati per manipolare i singoli
elementi dell’array.
Un indice è un’espressione di tipo int; un indice è
valido se assume un valore compreso tra 0 e la dimensione
dell’array meno 1.
x[0] x[1] x[2] x[3] x[4] x[5] x[6] x[7]
16.0 12.0
6.0
8.0
2.5
12.0 14.0 -54.5
se i vale 3, allora il valore di x[i] è 8.0
se i vale 0, allora il valore di x[i] è 16.0
13
Esempio
x[0] x[1] x[2] x[3] x[4] x[5] x[6] x[7]
16.0 12.0
6.0
8.0
2.5
12.0 14.0 -54.5
i = 5;
printf(“%d %.1f”, 4, x[4]); stampa 4 e 2.5 (valore di x[4])
printf(“%d %.1f”, i, x[i]); stampa 5 e 12.0 (valore di x[5])
printf(“%.1f”, x[i] + 1);
stampa 13.0 (valore di x[5] più 1)
printf (“%.1f”, x[i] + i);
stampa 17.0 (valore di x[5] più 5)
printf (“%.1f”, x[i+1]);
stampa 14.0 (valore di x[6])
printf (“%.1f”, x[i+i]);
NO (tenta di stampare x[10])
printf (“%.1f”, x[2*i-3]);
stampa -54.5 (valore di x[7])
printf (“%.1f”, x[(int)x[4]]); stampa 6.0 (valore di x[2])
14
Esempio
x[0] x[1] x[2] x[3] x[4] x[5] x[6] x[7]
16.0 12.0
6.0
printf (“%.1f”, x[i++]);
printf(“%.1f”, x[--i]);
x[i - 1] = x[i];
x[i] = x[i + 1];
x[i] - 1 = x[i];
8.0
2.5
12.0 14.0 -54.5
stampa 12.0 (valore di x[5])
assegna 6 (5 più 1) ad i
assegna 5 (6 meno 1) ad i
stampa 12.0 (valore di x[5])
assegna 12.0 (valore di x[5]) ad x[4]
assegna 14.0 (valore di x[6]) ad x[5]
assegnamento illegale
15
Variabili indiciate
sintassi
aname[subscript];
esempio
b[i + 1];
subscript è un’espressione di tipo int;
il compilatore valuta subscript, e il valore ottenuto
determina a quale elemento dell’array aname ci riferiamo.
Nota: il programmatore deve garantire che il valore di
subscript sia compreso tra 0 e la dimensione dell’array
meno 1; solo in certi casi si verifica un errore a tempo
di esecuzione.
16
Cicli for per accesso sequenziale
E’ spesso necessario elaborare gli elementi di un array
in sequenza, partendo dal primo elemento (es.
inizializzazione o stampa del contenuto dell’array,
somma degli elementi).
Si utilizza un ciclo for, la cui variabile di controllo viene
usata come indice dell’array.
17
Cicli for per accesso sequenziale
Esempio
Memorizzare i quadrati dei numeri da 0 a 10 nell’array
square.
#define SIZE 11
int square[SIZE], i;
for (i = 0; i < SIZE; i++)
square[i] = i * i;
18
Cicli for per accesso sequenziale
Esempio
punteggio ottenuto da uno studente negli esercizi svolti
durante la settimana: 9, 7, 5, 3, 1
#define NUM_CLASS_DAYS 5;
typedef enum {monday, tuesday, wednesday,
thursday, friday}
class_day_t;
int score[NUM_CLASS_DAYS], cscore;
class_day_t today;
cscore = 9;
for (today = monday; today <= friday; today++) {
score[today] = cscore;
cscore -=2;
}
19
Utilizzo di array per calcoli
statistici
Programma che prende in input un insieme di dati,
ne calcola la media e lo scostamento di ogni singolo
dato dalla media.
20
/*
* Computes the mean of an array of data and displays
* the difference between each value and the mean.
*/
#include <stdio.h>
#include <math.h>
#define MAX_ITEM
8
/* maximum number of items
*/
int
main(void)
{
double x[MAX_ITEM], /* data list
*/
mean,
/* mean (average) of the data */
sum,
/* sum of the data
*/
int
i;
/* Gets the data
*/
printf("Enter %d numbers separated by <return>\n> ",
MAX_ITEM);
21
for
(i = 0; i < MAX_ITEM;
scanf("%lf", &x[i]);
++i)
/* Computes the sum of all data */
sum = 0;
for
(i = 0; i < MAX_ITEM; ++i)
sum += x[i];
/* Computes and prints the mean */
mean = sum / MAX_ITEM;
printf("The mean is %.2f.\n", mean);
/* Displays the difference between each item
and the mean
*/
printf("\n Differences between data values and mean\n");
printf("Index
Item
Difference\n");
for (i = 0; i < MAX_ITEM; ++i)
printf("%3d%4c%9.2f%5c%9.2f\n", i, ' ', x[i],
' ', x[i] - mean);
return (0);
}
22
Elementi di array utilizzati come
argomenti di funzioni
printf("%3d%4c%9.2f%5c%9.2f\n", i, ' ', x[i],
' ', x[i] - mean);
x[i] è passata come argomento di input alla funzione printf;
se i = 2, viene stampato il contenuto di x[2]
scanf("%lf", &x[i]);
l’elemento x[i] è utilizzato come argomento di output
dalla funzione scanf;
se i = 4, il valore inserito dall’utente viene memorizzato
in x[4]
23
Elementi di array utilizzati come
argomenti di funzioni
void do_it(double arg1, double *arg2_p,
double *arg3_p);
prototipo di funzione con un parametro di input e
due parametri di output
do_it(x[0], &x[1], &x[2]);
chiamata a funzione che utilizza il primo elemento dell’
array x come argomento di input e il secondo e terzo
elemento come argomenti di output
24
Area dati del
chiamante
[0]
[1]
[2]
[3]
[4]
[5]
[6]
[7]
Area dati della
funzione do_it
x
arg1
16.0
12.0
6.0
8.0
2.5
12.0
14.0
16.0
arg2_p
arg3_p
-54.5
25
Array come argomenti a funzioni
Se tra gli argomenti di una chiamata a funzione appare
un nome di array senza indici, nel corrispondente
parametro formale viene memorizzato l’indirizzo del
primo elemento dell’array.
Nel corpo della funzione utilizzo gli indici per accedere ai
singoli elementi dell’array.
Poichè la funzione manipola l’array originario, e non una
sua copia, ogni assegnamento a un elemento dell’array
effettuato nel corpo della funzione effettua una modifica
al contenuto dell’array originario.
26
Esempio: fill_array
Funzione che setta tutti gli elementi dell’array al valore
specificato da in_value.
/*
* Sets all elements of its array parameter to in_value.
* Pre: n and in_value are defined.
* Post: list[i] = in_value, for 0 <= i < n.
*/
void
fill_array (int list[],
/* output - list of n integers
int n,
/* input - number of list elements
int in_value) /* input - initial value
{
int i;
for
}
*/
*/
*/
/* array subscript and loop control */
(i = 0; i < n; ++i)
list[i] = in_value;
27
Esempio: fill_array
Il parametro formale di tipo array e’ dichiarato come
segue:
int list[]
questa dichiarazione non specifica quanti elementi sono
contenuti nell’array list.
Poichè non viene allocato spazio per contenere una copia
dell’intero array, il compilatore non ha bisogno di
conoscere la dimensione dell’array passato come parametro.
La funzione fill_array può quindi gestire array di
interi di qualunque dimensione.
28
fill_array(y, 5, -7);
Memoria all’inizio dell’esecuzione di fill_array:
Area dati del chiamante
[0]
y
??
[1]
??
[2]
??
[3]
??
[4]
??
Area dati di fill_array
list
n
5
in_value
-7
i
??
29
fill_array(y, 5, -7);
Memoria al termine dell’esecuzione di fill_array:
Area dati del chiamante
[0]
y
-7
[1]
-7
[2]
-7
[3]
-7
[4]
-7
Area dati di fill_array
list
n
5
in_value
-7
i
5
30
*list vs list[ ]
Le seguenti dichiarazioni di parametri formali sono
equivalenti:
int list[]
int *list
Attenzione: se specifichiamo un parametro formale
come puntatore, è legale passare come argomento
attuale un array dello stesso tipo.
31
Array come parametri di input
Il qualificatore const, utilizzato nella dichiarazione
di parametri formali di tipo array, informa il compilatore
che l’array viene passato in input e non deve essere
modificato dalla funzione:
int
get_max(const int list[],
int n)
Ogni tentativo di modificare gli elementi dell’array
list all’interno della funzione viene segnalato come
errore.
32
/*
* Returns the largest of the first n values in array list
* Pre: First n elements of array list are defined and n > 0
*/
int
get_max(const int list[ ], /* input - list of n integers
*/
int
n) /* input - number of list elements to examine */
{
int i,
cur_large; /* largest value so far */
/* Initial array element is largest so far.
cur_large = list[0];
*/
/* Compare each remaining list element to the largest so far; save the larger */
for (i = 1; i < n; ++i)
if (list[i] > cur_large)
cur_large = list[i];
return (cur_large);
}
33
Array come parametri di input
sintassi
const element_type array_name[ ]
esempio
const int list[ ]
La parola riservata const indica che la variabile di tipo
array è un parametro di input e non deve essere modificata
dalla funzione.
Poichè il parametro formale corrispondente equivale a
un puntatore al primo elemento di array_name, se const
viene omesso è possibile modificare gli elementi dell’array
passato come argomento.
34
Array come parametri di input
Il tipo degli elementi dell’array è element_type.
Le [ ] dopo array_name indicano che il parametro è un
array.
Al momento della chiamata, nel parametro formale
array_name verrà memorizzato l’indirizzo del primo
elemento dell’array passato come argomento.
E’ possibile utilizzare la dichiarazione equivalente
const element_type *array_name
35
Ritornare un risultato di tipo array
In C il tipo del valore ritornato da una funzione non
può essere un array.
Per ritornare un oggetto di tipo array è necessario
utilizzare un parametro di output di tipo array.
La funzione fill_array utilizza l’array list come
parametro di output.
Esempio:
funzione che effettua la somma di due array
36
/*
* Adds corresponding elements of arrays ar1 and ar2, storing
* the result in arsum. Processes first n elements only.
* Pre: First n elements of ar1 and ar2 are defined.
*
arsum's corresponding actual argument has a declared
*
size >= n (n >= 0)
*/
void
add_arrays(const double ar1[], /* input */
const double ar2[], /* arrays being added
*/
double
arsum[],/* output - sum of corresponding
elements of ar1 and ar2
*/
int
n)
/* input - number of element
pairs summed
*/
{
int i;
/* Adds corresponding elements of ar1 and ar2
for (i = 0; i < n; ++i)
arsum[i] = ar1[i] + ar2[i];
*/
}
37
add_arrays(x, y, x_plus_y, 3);
Area dati chiamante
Area dati add_arrays
array x
1.5
2.0
5.1
ar1
n
3
array y
2.0
7.2
0.0
ar2
??
arsum
array x_plus_y
??
??
38
operatore &
add_arrays(x, y, x_plus_y, 3);
nella chiamata a add_arrays non c’è differenza di
notazione tra i riferimenti agli array di input x e y e
il riferimento all’array di output x_plus_y.
A differenza di quanto avviene per i parametri di tipo
semplice, parametri di output di tipo array non sono
preceduti da &.
In C il passaggio di array avviene in entrambi i casi
memorizzando l’indirizzo del primo elemento dell’array
nel corrispondente parametro formale.
39
Array riempiti parzialmente
Alcuni programmi manipolano sequenze di dati
di lunghezza diversa.
Posso riutilizzare lo stesso array per contenere
sequenze diverse:
• dichiaro un array di dimensioni sufficienti a contenere
la sequenza più lunga
• tengo traccia del numero di elementi contenuti
nella sequenza che sto utilizzando
40
/*
* Gets data to place in dbl_arr until value of sentinel is
* encountered in the input.
* Returns number of values stored through dbl_sizep.
* Stops input prematurely if there are more than dbl_max data
* values before the sentinel or if invalid data is encountered.
* Pre: sentinel and dbl_max are defined and dbl_max is the
*
declared size of dbl_arr
*/
void
fill_to_sentinel(int
dbl_max, /* input - declared size of
dbl_arr
*/
double sentinel, /* input - end of data value
in input list
*/
double dbl_arr[], /* output - array of data
*/
int
*dbl_sizep) /* output - number of data values
stored in dbl_arr
*/
{
double data;
int
i, status;
41
/* Sentinel input loop */
i = 0;
status = scanf("%lf", &data);
while (status == 1 && data != sentinel
dbl_arr[i] = data;
++i;
status = scanf("%lf", &data);
}
&&
i < dbl_max) {
/* Issues error message on premature exit */
if (status != 1) {
printf("\n*** Error in data format ***\n");
printf("*** Using first %d data values ***\n", i);
} else if (data != sentinel) {
printf("\n*** Error: too much data before sentinel ***\n")
printf("*** Using first %d data values ***\n", i);
}
/* Sends back size of used portion of array
*dbl_sizep = i;
*/
}
42
/* Driver to test fill_to_sentinel function */
#define A_SIZE 20
#define SENT
-1.0
int
main(void)
{
double arr[A_SIZE];
int
in_use,
/* number of elements of arr in use */
i;
fill_to_sentinel(A_SIZE, SENT, arr, &in_use);
printf("List of data values\n");
for (i = 0; i < in_use; ++i)
printf("%13.3f\n", arr[i]);
return (0);
}
43
Agli array parzialmente riempiti corrispondono 2
grandezze:
• la dimensione dell’array, specificata nella dichiarazione
• il numero di elementi effettivamente utilizzati
Nel main, dopo la chiamata a fill_to_sentinel, la
visualizzazione del contenuto dell’array viene effettuata
utilizzando la variabile in_use (numero di elementi
dell’array che sono stati riempiti) e non A_SIZE
(dimensione dichiarata dell’array).
Notare la differenza nel passaggio di argomenti di output
di tipo semplice (in_use) e di tipo array (arr) nella
chiamata a fill_to_sentinel.
44
Pila (stack)
Collezione di dati dello stesso tipo.
I dati vengono inseriti in cima alla pila.
Posso rimuovere solo l’elemento in cima alla pila.
Es. pila di vassoi in mensa.
push
inserisce un nuovo elemento in cima alla pila
pop
rimuove l’elemento in cima alla pila
45
Pila di caratteri
C
+
5
C
+
5
pop ritorna ‘C’ e trasforma
la pila in
+
5
push ‘z’
trasforma la pila in
z
C
+
5
46
Implementazione mediante array
C
+
5
[0]
[1]
[2]
[3]
s
s_top
5
+
C
2
[STACK_SIZE]
47
Implementazione pila vuota
s
[0]
[1]
[2]
[3]
s_top
-1
[STACK_SIZE]
48
Funzione push per pile di caratteri
void
push(char stack[],
char item,
int
*top,
int
max_size)
/* input/output - the stack */
/* input - data being pushed
onto the stack */
/* input/output - pointer to top
of stack */
/* input - maximum size of stack */
{
if (*top < max_size-1) {
++(*top);
stack[*top] = item;
}
}
49
Funzione pop per pile di caratteri
char
pop(char stack[],
int *top)
/* input/output - the stack */
/* input/output - pointer to top
of stack */
{
char item;
/* value popped off the stack */
if (*top >= 0) {
item = stack[*top];
--(*top);
} else {
item = STACK_EMPTY;
}
return (item);
}
50
Esempio
#define STACK_SIZE 100
#define STACK_EMPTY @
...
char s[STACK_SIZE];
int s_top = -1;
/* a stack of characters */
/* stack s is empty
*/
...
push(s, ‘5’, &s_top, STACK_SIZE);
push(s, ‘+’, &s_top, STACK_SIZE);
push(s, ‘C’, &s_top, STACK_SIZE);
51
Progetti
• programma che prende in input una sequenza di
caratteri e la stampa in ordine inverso
• programma che prende in input un’espressione
aritmetica con parentesi tonde, quadre e graffe e
controlla che le parentesi siano bilanciate
• programma che prende in input un’espressione
in forma postfissa, ne controlla la correttezza e
la valuta
52
Ricerca
Determinare la posizione di un elemento, detto target,
in un array.
Ricerca lineare:
utilizzo un ciclo per esaminare gli elementi dell’array
uno alla volta, confrontandoli con il target;
quando trovo un valore uguale al target, esco dal ciclo.
Utilizzo un flag per indicare che il valore è stato
trovato e posso uscire dal ciclo.
53
Algoritmo di ricerca lineare
1. inizializza il flag per indicare che il target non è ancora
stato trovato
2. inizia dal primo elemento dell’array
finchè non viene trovato il target e ci sono ancora
elementi da esaminare:
4. se l’elemento corrente è uguale al target
5. setta il flag per indicare che il target è stato
trovato
altrimenti
6. passa al prossimo elemento
7. se il target è stato trovato
8. ritorna l’indice dell’elemento uguale al target
altrimenti
54
9. ritorna -1
#define NOT_FOUND -1
/* Value returned by search function if
target not found
*/
/*
* Searches for target item in first n elements of array arr
* Returns index of target or NOT_FOUND
* Pre: target and first n elements of array arr are defined
*
and n>=0
*/
int
search(const int arr[], /* input - array to search
*/
int
target, /* input - value searched for
*/
int
n)
/* input - number of elements
to search
*/
{
int i,
found = 0,
/* whether or not target has been found */
where;
/* index where target found or NOT_FOUND */
55
/* Compares each element to target
i = 0;
while (!found && i < n) {
if (arr[i] == target)
found = 1;
else
++i;
}
*/
/* Returns index of element matching target or NOT_FOUND */
if (found)
where = i;
else
where = NOT_FOUND;
return (where);
}
56
Ricerca su array ordinati
Per effettuare la ricerca di un elemento in un array in
cui gli elementi sono ordinati posso utilizzare la
ricerca binaria.
E’ simile al metodo utilizzato per cercare un numero
nell’elenco telefonico:
• apro l’elenco a metà e guardo il nome a metà pagina
• se non è il nome che sto cercando, decido se viene
prima o dopo il nome che sto cercando
• scelgo la metà appropriata dell’elenco e ripeto i passi
precedenti finchè non trovo il nome cercato
57
Algoritmo di ricerca binaria
1. sia bottom l’indice del primo elemento
2. sia top l’indice dell’ultimo elemento
3. pongo found a false
4. ripeti finchè bottom non è maggiore di top e il target non
è stato trovato
5. sia middle l’indice dell’elemento a metà strada tra
bottom e top
6. se l’elemento alla posizione middle è il target
7. setta found a vero e index a middle
altrimenti se l’elemento alla posizione middle è
maggiore del target
8. poni top a middle - 1
altrimenti
58
9. poni bottom a middle + 1
Ordinamento
Selection sort:
per ordinare un array di n elementi (indici da 0 a n-1),
cerco l’elemento più piccolo dell’array e lo scambio con
l’elemento in posizione 0; a questo punto, la posizione 0
contiene l’elemento più piccolo dell’array.
Poi, cerco il più piccolo elemento nel sottoarray con
indici da 1 a n-1, lo scambio con l’elemento nella
posizione 1, e così via.
59
Algoritmo di selection sort
1. per ogni valore di fill da 0 a n-2
2. cerca index_of_min, l’indice del più piccolo
elemento nel sottoarray non ordinato da
list[fill] a list[n-1]
3. se fill non è la posizione dell’elemento più
piccolo (index_of_min)
4. scambia l’elemento più piccolo con
l’elemento nella posizione fill
60
Esempio
[0]
[1]
[2]
[3]
61
/*
*
*
*
*
*
*
*
*/
int
Finds the position of the smallest element in the subarray
list[first] through list[last].
Pre: first < last and elements 0 through last of array list
are defined.
Post: Returns the subscript k of the smallest element in the
subarray; i.e., list[k] <= list[i] for all i in the
subarray.
get_min_range(int list[], int first, int last);
Esercizio: scrivere il corpo di get_min_range
62
/*
* Sorts the data in array list
* Pre: first n elements of list are defined and n >= 0
*/
void
select_sort(int list[],
/* input/output - array being sorted */
int n)
/* input - number of elements to sort */
{
int fill,
/* first element in unsorted subarray */
temp,
/* temporary storage
*/
index_of_min;
/* subscript of next smallest element */
for (fill = 0; fill < n-1; ++fill) {
/* Find position of smallest element in unsorted subarray */
index_of_min = get_min_range(list, fill, n-1);
/* Exchange elements at fill and index_of_min */
if (fill != index_of_min) {
temp = list[index_of_min];
list[index_of_min] = list[fill];
list[fill] = temp;
}
}
}
63
Tempo di esecuzione
Il tempo necessario per eseguire un programma può
essere misurato utilizzando le funzioni di libreria
dichiarate in time.h.
clock_t clock(void);
restituisce il tempo di cpu utilizzato dal programma
dall’inizio dell’esecuzione, espresso in unità di clock.
clock_t è un tipo numerico definito in time.h.
CLOCKS_PER_SEC
numero di unità di clock al secondo.
64
Tempo di esecuzione
double start, finish, elapsed;
start = (double) clock() / CLOCKS_PER_SEC;
...istruzioni...
finish = (double) clock() / CLOCKS_PER_SEC;
elapsed = finish - start;
65
Differenza tra clock e time
clock_t clock(void);
viene utilizzato per calcolare il tempo utilizzato
esclusivamente per l’esecuzione del programma.
time_t time(time_t *p);
viene utilizzato per misurare il tempo trascorso
dall’inizio dell’esecuzione del programma.
In un sistema time-sharing i due tempi possono
essere diversi.
66
Array multidimensionali
array con due o più dimensioni
char tris[3][3];
riga 0
1
2
0
colonna
2
1
x
o
o
o
x
x
x
o
x
tris[1][2]
67
Dichiarazione array multidimensionali
sintassi (allocazione di memoria)
element_type aname [size1] [size2] ... [sizen]
sintassi(parametro formale)
element_type aname [size1] [size2] ... [sizen]
element_type aname [ ] [size2] ... [sizen]
esempi
double table[NROWS][NCOLS];
void
process_matrix(int in[ ][4], /* input matrix */
int out[ ][4], /* output matrix */
int nrows) /* input - number of rows */
68
Dichiarazione array multidimensionali
Viene allocata memoria per l’array aname costituito
da size1 size2 . . . sizen celle di memoria.
Ogni cella può contenere un dato di tipo element_type.
L’accesso agli elementi dell’array è effettuato mediante
le variabili indiciate da aname[0][0]...[0] a
aname[size1] [size2]...[sizen].
Nella dichiarazione di un array multidimensionale come
parametro di una funzione è possibile omettere la prima
dimensione (il numero di righe). Come per gli array
unidimensionali, il valore effettivamente memorizzato in
un parametro formale di tipo array è l’indirizzo del primo
elemento dell’argomento attuale.
69
/*
Checks whether a tris board is completely filled. */
int
filled(const char tris_brd[3][3]) /* input - tris board */
{
int r, c, /* row and column subscripts
*/
ans;
/* whether or not board filled */
/* Assumes board is filled until blank is found
ans = 1;
/* Resets ans to zero if a blank is found
for (r = 0; r < 3; ++r)
for (c = 0; c < 3; ++c)
if (tris_brd[r][c] == ' ')
ans = 0;
*/
*/
return (ans);
}
70
Inizializzazione di array
multidimensionali
Per inizializzare un array multidimensionale, occorre
raggruppare gli elementi per righe:
char tris[3][3] = { {‘ ‘, ‘ ‘, ‘ ‘},
{‘ ‘, ‘ ‘, ‘ ‘},
{‘ ‘, ‘ ‘, ‘ ‘} };
71
Esempio
int celsius[100];
int i;
i = 99;
printf(“%d”, celsius[i]);
printf(“%d”, celsius[i+1]);
L’accesso agli elementi dell’array celsius avviene mediante
le variabili indiciate celsius[0] ... celsius[99].
La seconda printf effettua un accesso ad un elemento
dell’array inesistente (celsius[100]).
Di solito non viene segnalato alcun errore a tempo di
esecuzione, ma il programma si comporta in modo scorretto.
72
Esempio
int a[10];
int i;
for (i = 0; i<=10; i++)
if (a[i-1] > a[i])
printf(“Array non ordinato.\n”);
Errore: accesso ad elementi inesistenti all’inizio del
for (a[-1]) e alla fine del for (a[10]).
Nell’accesso ad elementi mediante variabile di controllo
di cicli controllati da contatore, verificare la correttezza
dell’indice per il valore iniziale e il valore finale della
variabile di controllo del ciclo.
73
/*
* scambia il
* elemento e
* puntata da
*/
void
min_first(int
Esempio
minimo elemento di arr con il primo
mette il minimo nella locazione
minp
arr[],int n, int *minp);
...
int a[10], min_a;
min_first(&a, 10, min_a);
Errore: l’argomento a non deve essere preceduto da &;
l’argomento min_a deve essere preceduto da &.
Chiamata corretta: min_first(a, 10, &min_a);
74
Esempio
/*
* prende in input da tastiera un numero naturale
* e lo memorizza nella locazione puntata da p
*/
void
get_nat(int *p);
int a[100];
for (i=0; i<100; i++)
get_nat(a[i]);
Errore: devo passare l’indirizzo di a[i].
Chiamata corretta: get_nat(&a[i]);
75