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 III: tipi base, espressioni, type-cast Marco Tarini Tipi Base • tipi base: – intero – floating point – booleano • tipi derivati: – enumerazione – strutture – arrays int x; ... if (x) a(); else b(); esegue b se e solo se x è zero. esegue a in tutti gli altri casi (anche se x è negativo) vale anche per i tipi non interi... Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Tipi Base : interi tipo dimensione minino valore assumibile (in bytes) massimo valore assumibile char 1 - 128 +127 short 2* - 32K +32K (-1) int 4* - 2*K*K 2*K*K (-1) long 4* (idem) (idem) * Di solito. Dipende dalla macchina. (remember: niente macchine astratte!) Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Tipi Base : interi Variante unsigned Esempio: unsigned int pippo; con questa variante, si risparmia il bit del segno. tipo dimensione minino valore assumibile (in bytes) massimo valore assumibile char 1 0 +255 short 2* 0 +64K (-1) int 4* 0 +4*K*K*K (-1) long 4* 0 (idem) * Di solito. Dipende dalla macchina. (remember: niente macchine astratte!) Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Literals interi • Molti modi per scriverle… const int PIPPO = 12; int a,c = 16, b; int main(){ char pippo= 67; if (pippo + a > 21) { ... } else { b = 4; ... } } Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Literals interi • Molti modi per scriverle… const int PIPPO = 12; int a,c = 0x10, b; codifica base 16: 0123456789ABCDEF 0xFFFF 0xA000 0xFFFFFFFFFF int main(){ codifica ASCII char pippo= 'C'; if (pippo + a > 025) { ... } else { b = 4; ... } } Marco Tarini - Laboratorio di Linguaggi - (per caratteri). 'A' =65 'B' =66 'a' =97 'b' =98 '+' =43 '?' =67 etc. (256 "caratteri" in tutto) codifica base 8: 01234567 013 0100 2007/08 - Università dell’Insubri Piccoli trucchi con i chars • Caratteri ASCII e numeri di un byte sono proprio lo stesso tipo! char c0, c1; ... if (c0<c1) { /* c0 viene prima di c1 in ordine alfabetico */ ... } else { /* c0 viene dopo di c1 in ordine alfabetico, o c0==c1 */ ... } (ricordiamoci la filosofia del C: linguaggio che permette di dire tutto in poche righe di codice.) (poche e quindi talvolta criptiche. Usare commenti!) Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri 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 maiuscola, 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){ if ( (c>='A') && (c<='Z') ) return c - 'A' + 'a'; return c; } (ricordiamoci la filosofia del C: linguaggio che permette di dire tutto in poche righe di codice.) (poche e quindi talvolta criptiche. Usare commenti!) Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Tipi Base : virgola mobile tipo minino/massimo cifre decimali dimensione valore esprimibili (circa) (in bytes) assumibile float 4* 10±38 6 double 8* 10±308 15 long double 8* (idem) (idem) * Di solito. Dipende dalla macchina. (remember: niente macchine astratte!) * float è più efficiente in spazio, ma sorprendentemente può essere persino meno efficiente in tempo (es. su alcuni processori). Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Literals in virgola mobile 5.32 5.32f un double (un float a precisione doppia) che vale 5,32 un float che vale 5,32 5.32e12 un double che vale 5,32 x 1012 5.32e-12 un double che vale 5,32 x 10-12 5.32e-12f un float che vale 5,32 x 10-12 esempi: double avogadro = 6.022e23; /* N molecole x mole */ double epsilon = 1e-18; che è meglio (più chiaro, meno orrendo) di: double epsilon = 0.000000000000000001; Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri La dimensione dei vari tipi • Si può chiedere al compilatore. • Costrutto "sizeof" – sintassi: sizeof( <tipo> ) • ad esempio, sizeof( int ) è una espressione (costante) che vale 4. – nota: non è una funzione, no invocazione di funz, il valore di "sizeof" è risolto staticamente Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Tipo delle espressioni • Reminder: tutte le espressioni hanno un tipo – sempre! – di solito, è il tipo degli operandi 5 + 3 5.0 + 3.0 int x; ... x – 3 – il tipo degli operandi determina anche l’operazione 7 / 3 divisione intera (fra interi) 7.0 / 3.0 7.0f / 3.0f divisione con virgola (fra double) Marco Tarini - Laboratorio di Linguaggi - divisione con virgola (fra float) 2007/08 - Università dell’Insubri Cambiare il tipo di una espressione • operazione detta type-cast (esplicito) – sintassi: ( <tipo di arrivo> ) <espressione> • esempio: double int int x; ( double ) (x+1) Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Cambiare il tipo di una espressione (<tipo di destinazione>) <espressione> • esempi: int pippo; ... ... (float)pippo ... (unsigned int)204 float zap; ... ... (int)zap ... /* espressione: pippo come float */ /* espressione: */ /* 204 come intero senza segno */ /* espres.: zap come int (fa arrotondamento) */ Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Cambiare il tipo di una espressione: in automatico 1/2 Regola generale 1: – in una espressione mista, l’operando di tipo “meno preciso” viene auto-convertito a quello “più preciso” (se possibile – else errore) – avviene un type-cast implicito – precisione: • double > float > int > short > char ... double x , y; ... y = x / 3; typecast implicito! equivalente a: Marco Tarini - Laboratorio di Linguaggi - y = x / (double) 3; 2007/08 - Università dell’Insubri Assegnamenti • Assegnamento base = <left value> = <expr> tipo T0 tipo T1 typecast automatico se T0 diverso da T1 (ma solo se esiste una conversione automatica). Ma e' sempre meglio (piu' chiaro) usare un typecast esplicito! Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Cambiare il tipo di una espressione: in automatico 2/2 Regola generale 2: – in un assegnamento, l’espressione dopo il segno = viene auto-convertita al tipo della variabile asseganta (se possibile – else errore) – avviene un type-cast implicito int x; double y; ... x = 3.0 / y; typecast implicito! equivalente a: x = (int) (3.0 / y); nota: in questo caso, c’è perdita di precisione (da double a int!). I compilatori bene educati avvertono (con un “warning” del comp). Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Assegnamenti a catena • Assegnamento base = expr di tipo T0 <left value> = <expr> tipo T0 tipo T1 x = y = z = 10; Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Cambiamento di tipo: sommario • Espliciti – typecast esplicito (<tipo di destinazione>) <espressione> • 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) Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Esempi pratici di uso (tre quiz) • N. 1: double x; x = 1 / 3; /* x e’ un terzo... o no? */ • N. 2: double x, y, div; div = ???; /* voglio che div il ris della divisione intera fra x e y */ • N. 3: int numerone1, numerone2, media; ... /* i due numeroni sono MOLTO grandi, fra 2 e 4 miliardi, ma positivi */ media= (numerone1 + numerone2) /2; Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Campo minato ! float x ; x = 1 / 120; float x ; int denominatore = 120.0; x = 1 / denominatore; int numerone1, numerone2, media; ... media= (numerone1 + numerone2) /2; Soluz: media= (((unsigned int) numerone1)+numerone2) /2; int gradi ; float circonferenza = 1000.0; /* in metri float arco; ... arco = circonferenza * (gradi/360); */ /* calcolo lunghezza arco di cironferenza */ Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri Definiamo un nuovo tipo typedef <descrizione del tipo> <identificatore del tipo>; typedef unsigned char Byte; Byte a,b,c; int main(){ Byte pippo=21, panco; ... } (ricordiamoci la filosofia del C: linguaggio scarno, ma estendibile!) Marco Tarini - Laboratorio di Linguaggi - 2007/08 - Università dell’Insubri