18 aprile 2002
Avvisi:
• Risultati 1o Esonero: disponibili entro una settimana
nella pag. WEB + nella bacheca fuori dal corridoio 2o
dente, piano terra.
• Progetti: gia’ disponibili nella pag. WEB.
Array bi-(multi-)dimensionali
– Tabelle con righe e colonne (array m x n )
– Esempio, le matrici: specifico riga e colonna
Riga 0
Riga 1
Riga 2
Colonna 0
a[0][0]
a[1][0]
a[2][0]
Colonna 1
a[0][1]
a[1][1]
a[2][1]
Colonna 2
a[0][2]
a[1][2]
a[2][2]
Colonna 3
a[0][3]
a[1][3]
a[2][3]
Indice di Colonna
Nome Array
Indice di Riga
Array bi-(multi-)dimensionali
• Dichiarazione
– Come per gli array unidimensionali,
specificando le varie dimensioni.
int b[ 2 ][ 2 ];
double d[ 5 ][ 7 ][ 2 ];
– Non esistono limiti sulle dimensioni di un array
(il limite e’ dato dalla memoria disponibile … )
– Il C memorizza un’array mettendo una riga
dopo l’altra… cioe’ un array multidimensionale
e’ di fatto un array di array.
Array multidimensionali
• Inizializzazione
– Inizializzatori seguono l’ordine seguente:
a[0][0]
1
a[0][1]
2
a[0][2]
3
a[0][3]
4
a[1][0]
5
a[1][1]
6
a[1][2]
7
a[1][3]
8
a[2][0]
9
a[2][1]
10
a[2][2]
11
a[2][3]
12
Esempio: per inizializzare il seguente vettore b:
int b[ 2 ][ 2 ] = {1, 2, 3, 4};
1
2
3
4
Array multidimensionali
– Initializzatori raggruppati per righe:
int b[ 2 ][ 2 ] = { {1, 2}, {3, 4} };
1
2
3
4
– Gli elementi non specificati vengono
inizializzati a zero automaticamente:
int b[ 2 ][ 2 ] = { {1}, {3, 4} };
1
0
3
4
Array multidimensionali
• Riferimenti agli elementi
Specifica prima la riga, poi la colonna
Nella matrice:
1
2
3
4
printf( "%d", b[ 0 ][ 1 ] );
stampa il numero 2
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
/* Fig6_21.c Inizializzazione di un array multibidimensionale */
#include <stdio.h>
void printArray(int [][3]);
Nota che la seconda
dimensione e’ necessaria!
main()
{
int array1[2][3] = { {1, 2, 3}, {4, 5, 6} },
array2[2][3] = { 1, 2, 3, 4, 5 },
array3[2][3] = { {1, 2}, {4} };
printf("Values in array1 by row are:\n");
printArray(array1);
printf("Values in array2 by row are:\n");
printArray(array2);
printf("Values in array3 by row are:\n");
printArray(array3);
return 0;
}
18.
19.
20.
21.
void printArray(int a[][3])
{
int i, j;
for (i = 0; i <= 1; i++) {
22.
23.
for (j = 0; j <= 2; j++)
printf("%d ", a[i][j]);;
24.
25.
printf("\n");
}
Values in array1 by row are:
1 2 3
4 5 6
Values in array2 by row are:
1 2 3
4 5 0
Values in array3 by row are:
1 2 0
4 0 0
1
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/* fig06_22.c
Esempio di array bi-dimensionale
#include <stdio.h>
#define STUDENTS 3
#define EXAMS 4
int minimum( const int [][ EXAMS ], int, int );
int maximum( const int [][ EXAMS ], int, int );
double average( const int [], int );
void printArray( const int [][ EXAMS ], int, int );
int main()
{
int student;
const int studentGrades[ STUDENTS ][ EXAMS ] =
{ { 77, 68, 86, 73 },
{ 96, 87, 89, 78 },
{ 70, 90, 86, 81 } };
Ogni riga e’ un particolare
studente, ogni colonna e’ il
voto dell’esame
printf( "The array is:\n" );
printArray( studentGrades, STUDENTS, EXAMS );
printf( "\n\nLowest grade: %d\nHighest grade: %d\n",
minimum( studentGrades, STUDENTS, EXAMS ),
maximum( studentGrades, STUDENTS, EXAMS ) );
for ( student = 0; student <= STUDENTS - 1; student++ )
printf( "The average grade for student %d is %.2f\n",
student,
average( studentGrades[ student ], EXAMS ) );
return 0;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/* Trova il minimo */
int minimum( const int grades[][ EXAMS ],
int pupils, int tests )
{
int i, j, lowGrade = 100;
for ( i = 0; i <= pupils - 1; i++ )
for ( j = 0; j <= tests - 1; j++ )
if ( grades[ i ][ j ] < lowGrade )
lowGrade = grades[ i ][ j ];
return lowGrade;
}
/* Trova il massimo*/
int maximum( const int grades[][ EXAMS ],
int pupils, int tests )
{
int i, j, highGrade = 0;
for ( i = 0; i <= pupils - 1; i++ )
for ( j = 0; j <= tests - 1; j++ )
if ( grades[ i ][ j ] > highGrade )
highGrade = grades[ i ][ j ];
return highGrade;
}
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/* Determina il voto medio per un particolare esame */
double average( const int setOfGrades[], int tests )
{
int i, total = 0;
for ( i = 0; i <= tests - 1; i++ )
total += setOfGrades[ i ];
return ( double ) total / tests;
}
/* Stampa l’array */
void printArray( const int grades[][ EXAMS ],
int pupils, int tests )
{
int i, j;
printf( "
[0]
[1]
[2]
[3]" );
for ( i = 0; i <= pupils - 1; i++ ) {
printf( "\nstudentGrades[%d] ", i );
for ( j = 0; j <= tests - 1; j++ )
printf( "%-5d", grades[ i ][ j ] );
}
}
The array is:
[0]
studentGrades[0] 77
studentGrades[1] 96
studentGrades[2] 70
[1]
68
87
90
[2]
86
89
86
[3]
73
78
81
Lowest grade: 68
Highest grade: 96
The average grade for student 0 is 76.00
The average grade for student 1 is 87.50
The average grade for student 2 is 81.75
Output
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
/* Uso dell’operatore sizeof() */
#include <stdio.h>
/* Dichiara tre arrai di 100 elementi */
int intarray[100];
float floatarray[100];
double doublearray[100];
main()
{
/* Mostra la dimensione di vari tipi numerici */
printf("\n\nSize of int = %d bytes", sizeof(int));
printf("\nSize of short = %d bytes“, sizeof(short));
printf("\nSize of long = %d bytes", sizeof(long));
printf("\nSize of float = %d bytes", sizeof(float));
printf("\nSize of double = %d bytes", sizeof(double));
/* Mostra la dimensione di tre array */
printf("\nSize of intarray = %d bytes“, sizeof(intarray));
printf("\nSize of floatarray = %d bytes",
sizeof(floatarray));
printf("\nSize of doublearray = %d bytes\n",
sizeof(doublearray));
return 0;
}
Size of int = 4 bytes
Size of short = 2 bytes
Size of long = 4 bytes
Size of float = 4 bytes
Size of double = 8 bytes
Size of intarray = 400 bytes
Size of floatarray = 400 bytes
Size of doublearray = 800 bytes
Output
Esercizi
Esercizio 6.19
Scrivere un programma C che simuli il lancio di due dadi. Il
programma dovra’ utilizzare rand per lanciare il primo dado e
poi invocarla nuovamente per lanciare il secondo dado: poi
calcolera’ la somma dei due valori. (Nota: tale somma puo’
variare tra 2 e 12). Tale programma dovra’ lanciare i due dadi
36.000 volte e poi dovra’ visualizzare i seguenti risultati:
• Un vettore di frequenze F per i risultati di ogni lancio cioe’
tale che F(i) rappresenta quante volte la somma dei due dadi
e’ stata uguale ad i con i=2,3,…12.
• Una matrice D 6x6 tale che D(i,j) rappresenta quante volte
si e’ ottenuto i col primo dado e j con il secondo dado con
i,j=1,2,…,6.
Variabili puntatore
– Contengono come loro valore degli indirizzi di memoria
count
– Le variabili normali contengono un valore specifico
7
(riferimento diretto)
– I puntatori contengono l’ indirizzo di una variabile che
ha uno specifico valore (riferimento indiretto)
countPtr
count
7
– Dereferenziazione – riferimento a un valore mediante il
puntatore
Dichiarazione e Inizializzazione
• * si usa per dichiarare variabili puntatore
– int *myPtr;
– Dichiara un puntatore ad un intero (puntatore di tipo int *)
– Per dichiarare vari puntatori, usare tanti *
int *myPtr1, *myPtr2;
– Si possono dichiarare puntatori di ogni tipo di dato
– I puntatori si possono inizializzare a 0, NULL, o ad un indirizzo
• 0 o NULL – non puntano a nessun dato (NULL piu’ comune)
Operatori sui Puntatori
• & (operatore di indirizzo)
– Restituisce l’indirizzo dell’operando
int y = 5;
int *yPtr;
yPtr = &y;
//yPtr prende l’indirizzo di y
– yPtr “punta a ” y
yPtr
y
5
yptr
500000
600000
y
600000
Indirizzo di y
e’ il valore di
yptr
5
Operatori sui Puntatori
• * (operatore di dereferenziazione)
– Restituisce un “sinomino”/alias all’oggetto puntato dal
suo operando
– *yptr restituisce y (perche’ yptr punta a y)
– * puo’ essere usato per un assegnazione
*yptr = 7; // cambia y in 7
– Un puntatore dereferenziato (operando di *) deve
essere una variabile (non una costante)
Operatori sui Puntatori
• * e & sono uno inverso dell’altro
– Si annullano a vicenda
*&yptr
->
* (&yptr) -> * (indirizzo di yptr)->
Restituisce un “alias all’oggetto puntato dal suo operando -> yptr
&*yptr -> &(*yptr) -> &(y) -> restituisce l’indirizzo di y,
che e’ yptr -> yptr
1 /* Fig. 7.4: fig07_04.c
2
Using the & and * operators */
3 #include <stdio.h>
L’indirizzo di a e’ il valore di
4
aPtr.
5 int main()
6 {
7
int a;
/* a e’ intero */
8
int *aPtr; /* aPtr e’ puntatore ad un intero */
9
10
a = 7;
11
aPtr = &a;
/* aPtr inizializzato come
aPtr punta ad a, e
12
l’indirizzo di a
*aPtr restituisce a.
*/
13
printf( "The address of a is %p"
14
"\nThe value of aPtr is %p", &a, aPtr );
15
16
printf( "\n\nThe value of a is %d"
17
"\nThe value of *aPtr is %d", a, *aPtr
);
18
Nota come * e &
19
printf( "\n\nShowing that * and & are inverses
sono uno inverso
of
20 "
"each other.\n&*aPtr = %p"
dell’altro
21
"\n*&aPtr = %p\n", &*aPtr, *&aPtr );
22
23
return 0;
24 }
The address of a is 0012FF88
The value of aPtr is 0012FF88
The value of a is 7
The value of *aPtr is 7
Proving that * and & are complements of each other.
&*aPtr = 0012FF88
*&aPtr = 0012FF88
Output