Laboratorio di Linguaggi lezione III Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in Informatica Anno Accademico 2006/07
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Laboratorio di Linguaggi docente: Marco Tarini ricevimento: Mercoledì dalle 11:00 o anche su appuntamento libro di testo consigliato: Kelley Al, Pohl Ira: "C Didattica e Programmazione" ("A Book on C") quarta edizione - anche la terza va bene
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Piccoli trucchi con i chars Caratteri ASCII e numeri di un byte sono proprio lo stesso tipo! /* restituisce 1 se il carattere e' una lettera minuscola, o 0 altrimenti */ int is_minuscolo(char c){ if ( (c>=a') && (c<=z') ) return 1; return 0; } /* restituisce la versione minuscola di un carattere dato*/ char minuscolo(char c){ } (ricordiamoci la filosofia del C: linguaggio che permette di dire tutto in poche righe di codice.) (poche e quindi talvolta criptiche. Usare commenti!) ? Es.: QUALE CODICE INSERIRE QUI ? (esercizio non facilissimo)
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Tipi Base : interi int long short char dimensione (in bytes) 1 2* 4* tipo minino valore assumibile massimo valore assumibile K +32K (-1) - 2*K*K*K +2*K*K*K (-1) (idem) * Di solito. Dipende dalla macchina. (remember: niente macchine astratte!)
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Tipi Base : virgola mobile long double double float dimensione (in bytes) 4* 8* tipo minino/massimo valore assumibile cifre decimali esprimibili (circa) * Di solito. Dipende dalla macchina. (remember: niente macchine astratte!) (idem) 6 15 (idem) * float è più efficiente in spazio, ma sorprendentemente può essere persino meno efficiente in tempo (es. su molti processori INTEL).
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a La dimensione dei vari tipi Si può chiedere al compilatore. Costrutto "sizeof" –sintassi: ad esempio, è una espressione (costante) che vale 4. –nota: non è una funzione (che restituisce 4): non c'è nessuna invocazione di funzione, il valore di "sizeof" è risolto staticamente sizeof( ) sizeof( int )
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Literals in virgola mobile 5.32f 5.32 un float che vale 5,32 un double (un float a precisione doppia) che vale 5, e-12 un double che vale 5,32 x e12 un double che vale 5,32 x e-12f un float che vale 5,32 x double epsilon = ; che è meglio (più chiaro, meno orrendo) di: double avogadro = 6.022e23; /* N molecole x mole */ esempi: double epsilon = 1e-18;
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Tipo delle espressioni viene indovinato dal compilatore… int x = 10, y; x = x / 3; double x = 10, y; y = x / 3; equivalente a: double x = 10.0, y; y = x / 3.0; float x = 10, y; y = x / 3; equivalente a: double x = 10.0f, y; y = x / 3.0f; NB: nelle operazioni miste viene convertito tutto al tipo più preciso. (double più preciso di float, float di int, int di short, short di char, etc).
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Cambiamento di tipo: espliciti si può anche cambiare esplicitamente: si tratta di un type-cast –sintassi: –altri esempi: double x = 10.0; y = ((int)x) / 3; /* y = 3.0 */ ( ) int pippo; (float)pippo... /* espressione: pippo come float */ (unsigned int)204 /* espressione: pippo come float */ float zap; (int)zap... /* espres.: zap come int (fa arrotondamento) */
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Cambiamento di tipo: negli assegnamenti Assegnamento base = = tipo T 0 tipo T 1 typecast automatico se T 0 diverso da T 1 (ma solo se esiste una conversione automatica). Ma e' sempre meglio (piu' chiaro) usare un typecast esplicito!
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Cambiamento di tipo: negli assegnamenti Assegnamento base = = tipo T 0 tipo T 1 expr di tipo T 0 typecast automatico se T 0 diverso da T 1 (ma solo se esiste una conversione automatica). Ma e' sempre meglio (piu' chiaro) usare un typecast esplicito! x = y = z = 10;
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Cambiamento di tipo Espliciti –typecast esplicito Nelle espressioni miste –conversione automatica al tipo più preciso Negli assegnamenti –conversione automatica al tipo più preciso ( ) SE POSSIBILE ! Non tutto si può trasformare in tutto (da tipo base a tipo base: ok) Se non possibile: errore di compilazione (errore buono)
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Campo minato ! float x ; x = 1 / 120; int numerone1, numerone2, media;... media= (numerone1 + numerone2) /2; float x ; int denominatore = 120.0; x = 1 / denominatore; media= (((unsigned int) numerone1)+numerone2) /2; Soluz: int gradi ; float circonferenza = ; /* in metri */ float arco;... arco = circonferenza * (gradi/360); /* calcolo lunghezza arco di cironferenza */
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Tipi in C: –Tipi base –Tipi definiti dall'untente
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Tipi definiti: il tipo enum. ("giorno" è una var che vale uno dei valori listati) enum { LUN, MAR, MERC, GIOV, VEN, SAB, DOM } giorno; esempio: 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)
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Tipi definiti: il tipo enum. typedef enum { LUN, MAR, MERC, GIOV, VEN, SAB, DOM } GiornoSettimana; GiornoSettimana ieri, oggi; semplicemente delle nuove costanti, che valgono 0, 1, 2, 3, 4, 5, 6 if ( (oggi > MERC) && (oggi <= VEN ) )... if ( oggi == DOM ) oggi = LUN; else oggi++; oggi = ( oggi + 5 ) % 7; come si fanno passare 5 giorni? sono implementati come interi, a tutti gli effetti.
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Tipi composti: il tipo struct typedef struct { char giorno; Mese mese; short anno; } Data; Data oggi, mio_compleanno; Data data_esame = { 28, OTTOBRE, 2004 }; int main(){ data_esame.mese = DICEMBRE;... }; definizione del tipo. MA NON E' UNA CLASSE: tutto "public" niente metodi niente costruttore… dichiarazione di alcune variabili con inizializzatore (nota la sintassi del literal, a dx del '=') accesso ai campi (come per le classi)
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Tipi composti: il tipo struct typedef struct { char giorno; Mese mese; short anno; } Data; sizeof(Data) si può chiedere la dimensione del nuovo tipo "Data": sizeof(char)+sizeof(Mese)+sizeof(short) che sarà uguale a: codifica di giornocodifica di mesecodifica di anno in fatti, in memoria, una struct e' codificata come la semplice concatenzaione delle codifiche dei suoi campi :
M a r c o T a r i n i L a b o r a t o r i o d i L i n g u a g g i / 0 7 U n i v e r s i t à d e l l I n s u b r i a Tipi composti: il tipo struct 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 };