Università dell’Insubria
Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese
Corso di Laurea in Informatica
Anno Accademico 2007/08
Laboratorio di Linguaggi
lezione IV:
tipi definiti dall’utente
Marco Tarini
Tipi definiti: il tipo enum.
• esempio:
enum
{ LUN, MAR, MERC, GIOV, VEN, SAB, DOM } giorno;
("giorno" è una var che vale uno dei valori listati)
• meglio definire un tipo:
typedef
enum { LUN, MAR, MERC, GIOV, VEN, SAB, DOM }
GiornoSettimana;
GiornoSettimana ieri, oggi;
("GiornoSettimana" è il tipo delle variabili che possono
assumere i valori listati, e "ieri" e "oggi" sono due variabili di
tale tipo)
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Tipi definiti: il tipo enum.
semplicemente delle
nuove costanti, che
valgono 0, 1, 2 , 3, 4, 5, 6
typedef
enum { LUN, MAR, MERC, GIOV, VEN, SAB, DOM }
GiornoSettimana;
GiornoSettimana ieri, oggi;
• sono implementati come interi, a tutti gli effetti.
if ( (oggi > MERC) && (oggi <= VEN ) ) ...
if ( oggi == DOM ) oggi = LUN; else oggi++;
• come si fanno passare 5 giorni?
oggi = ( oggi + 5 ) % 7;
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Tipi composti: il tipo struct
Il nuovo tipo
definizione del tipo.
MA NON E' UNA
CLASSE:
tutto "public"
niente metodi
niente costruttore…
typedef
struct {
char giorno;
Mese mese;
short anno;
}
Data;
Il nome
scelto per il
nuovo tipo
dichiarazione di
alcune variabili
Data oggi, mio_compleanno;
con inizializzatore
(nota la sintassi del
literal, a dx del '=')
Data data_esame = { 28, OTTOBRE, 2004 };
accesso ai campi
(come per le classi)
int main(){
data_esame.mese = DICEMBRE ;
...
}
Nota: un literal di tipo “Data”
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Il tipo struct: in memoria
typedef
struct {
char giorno;
Mese mese;
short anno;
}
Data;
• in memoria, una struct e' codificata come
la semplice concatenzaione delle codifiche dei suoi campi :
codifica della Data
codifica di giorno
codifica di mese
codifica di anno
offset del campo “anno”
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Il tipo struct: in memoria
typedef
struct {
char giorno;
Mese mese;
short anno;
}
Data;
• in memoria, una struct e' codificata come
la semplice concatenzaione delle codifiche dei suoi campi :
codifica della Data a
codifica di giorno
indirizzo di a.anno
a.anno
codifica di mese
=
codifica di anno
(indirizzo base di a) + (offsett campo anno)
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Il tipo struct: dimensione
typedef
struct {
char giorno;
Mese mese;
short anno;
}
Data;
• si può chiedere
la dimensione
del nuovo tipo "Data": sizeof(Data)
• che di solito sarà uguale a:
sizeof(char)+sizeof(Mese)+sizeof(short)
• Ma ci possono essere problemi di allineamento (es, dimensioni che
devono essere multipli di 4)... usare sizeof!
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Il tipo struct: strutture innestate (nested)
typedef
struct {
char giorno;
Mese mese;
short anno;
}
Data;
typedef
struct {
Data partenza;
Data arrivo;
int numero_stanza;
}
Prenotazione;
Prenotazione p = {
{ 28, OTTOBRE, 2004 },
{ 2, NOVEMBRE, 2004 },
23
}; /* definizione var p, con inizializzazione */
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Il tipo struct: asseganmenti
typedef
struct {
char giorno;
Mese mese;
short anno;
}
Data;
typedef
struct {
Data partenza;
Data arrivo;
int numero_stanza;
}
Prenotazione;
Prenotazione pren1, pren2;
...
pren1 = pren2; /* assegnamento fra struct:
* copia diretta della memoria
* (quindi di tutti i campi)
*/
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Gli array
• simile a java…
/* cartella della tombola, contiene 15 numeri*/
int cartella[15];
deve essere una costante!
(il comp. deve sapere quanti elementi allocare)
• come prima, si può definire il tipo
senza dichiarare nessuna variabile...
typedef int Cartella[15];
• Esempio
int main(){
Cartella mia, sua;
mia[2]=31;
}
si usano solo tipi interi per indicizzare. (qui: da 0 a 14)
NB: no range checking !
Segmentation faults sempre in agguato.
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Gli array: inizializzazione
• Inizializzazione di array (opzionale, come sempre)
int cartella[15]={
10,21,33,13,4,
12,4, 53, 1,78,
2,54,31,86,78,
};
l'ultima virgola è
tollerata
se si inizializza un
int cartella[]={
10,21,33,13,4,
12,4, 53, 1,78,
2,54,31,86,78,
};
Marco Tarini - Laboratorio di Linguaggi -
array, allora non è
necessario
specificare il numero
di elementi
(li conta il
compilatore per noi)
2007/08 - Università dell’Insubri
Gli array: inizializzazione
• Inizializzazione di array:
– gli array di caratteri godono di un inizializzatore speciale:
– questa inizializzazione:
char nome[]={'m','a','r','c','o',' ','t','a','r','i','n','i',0};
– si può scrivere equivalentemente così:
char nome[]= "marco tarini";
la costante char 0.
Si può scrivere anche
così:
'\0'
nome[ 5]
nome[ 6]
nome[12]
vale
vale
vale
' '
't'
'\0'
Marco Tarini - Laboratorio di Linguaggi -
Per convenzione, è
usato come terminatore
delle stringhe:
2007/08 - Università dell’Insubri
Gli array: in memoria
• Importante:
– in memoria, gli elementi di un array sono memorizzati
in una serie di celle contigue
– ogni cella ha la stessa grandezza
– per questo gli array sono random access!
int cartella[5]={
10,21,33,13,4,
};
indirizzo
base
di "cartella"
dimensione
cella (=4)
10
indirizzo di
21
33
13
4
cartella[3] = (indirizzo base) + 3 x (dimensione cella)
cartella[3]
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Problema
• Cosa succede, se non si sa a priori quanti
elementi dovremo allocare?
– (a tempo di esecuzione)
• Necessità allocazione dinamica di array.
• Per la soluzione di
questo (e molti altri) problema,
useremo i puntatori
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
E' arrivato il momento de...
I PUNTATORI
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Puntatori: intro
• Una tipo variabile che contiene
un indirizzo di una locazione di memoria:
– l'indirizzo di un'altra variabile!
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Puntatori: sintassi della dichiarazione
int* pippo;
" pippo " è una var di tipo int*,
cioè puntatore ad intero
o se preferite:
int *pippo;
" *pippo "
(cioè il valore puntato da pippo)
è una var di tipo intero
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Puntatori: sintassi dell'uso
pippo
*pippo
il valore del puntatore.
il valore dell'oggetto puntato.
entrambi possono essere sia letti che assegnati
(possono comparire da entrambi i lati di un assegnamento)
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Puntatori: preambolo
Cosa succede normalmente…
int pippo = 0xA0;
Inoltre, riserva quei
quattro byte per la
variabile pippo.
0x612A0214 00 00 00 FF
0x612A0218 01 22 00 AB
0x612A021C 21 2A 02 2C
0x612A0220 12 23 D2 FF
0x612A0224 FF 02 41 A4
RAM
Ad esempio, la
locazione 0x612A22C
0x00000000
spazio degli indirizzi logici
il compilatore assegna
alla variabile pippo
una locazione di memoria.
0x612A0228 21 00 00 00
0x612A022C 00 00 00 A0
0x612A0230 12 33 A3 D0
0xFFFFFFFF
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Puntatori: preambolo
Cosa succede normalmente…
Ad esempio, la
locazione 0x612A22C
Inoltre, riserva quei
quattro byte per la
variabile pippo.
variabile
pippo
tipo locazione
Inoltre
int 0x612A22C
STORE 0x0612A22C 0x00AABB00
0x00000000
0x612A0214 00 00 00 FF
0x612A0218 01 22 00 AB
0x612A021C 21 2A 02 2C
0x612A0220 12 23 D2 FF
0x612A0224 FF 02 41 A4
RAM
il compilatore assegna
alla variabile pippo
una locazione di memoria.
dopo la complazione
spazio degli indirizzi logici
int pippo = 0xA0;
pippo = 0x00AABB00;
0x612A0228 21 00 00 00
00 BB
00 00
A0
0x612A022C 00 AA
0x612A0230 12 33 A3 D0
0xFFFFFFFF
Marco Tarini - Laboratorio di Linguaggi -
2007/08 - Università dell’Insubri
Scarica

ppt