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