Laboratorio di Linguaggi lezione III: tipi base, espressioni, type-cast Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in Informatica Anno Accademico 2007/08
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 / U n i v e r s i t à d e l l I n s u b r i a 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...
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 / 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 2*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 / 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 (-1) +4*K*K*K (-1) (idem) * Di solito. Dipende dalla macchina. (remember: niente macchine astratte!) unsigned Variante unsigned int pippo; Esempio: con questa variante, si risparmia il bit del segno.
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 / U n i v e r s i t à d e l l I n s u b r i a 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;... }
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 / U n i v e r s i t à d e l l I n s u b r i a Literals interi Molti modi per scriverle… const int PIPPO = 12; int a,c = 0x10, b; int main(){ char pippo= 'C'; if (pippo + a > 025) {... } else { b = 4;... } codifica base 16: ABCDEF 0xFFFF 0xFFFFFFFFFF 0xA000 codifica base 8: codifica ASCII (per caratteri). 'A' 'a' 'B' =97 =65=66 'b' =98 '+' =43 '?' =67 etc. (256 "caratteri" in tutto)
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 / 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! 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!)
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 / 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 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!)
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 / 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!) 10 ±38 10 ±308 (idem) 6 15 (idem) * float è più efficiente in spazio, ma sorprendentemente può essere persino meno efficiente in tempo (es. su alcuni processori).
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 / 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 / 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, no invocazione di funz, 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 / U n i v e r s i t à d e l l I n s u b r i a Tipo delle espressioni Reminder: tutte le espressioni hanno un tipo –sempre! –di solito, è il tipo degli operandi / 37.0 / f / 3.0f int x;... x – –il tipo degli operandi determina anche loperazione divisione intera (fra interi) divisione con virgola (fra double) divisione con virgola (fra float)
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 / U n i v e r s i t à d e l l I n s u b r i a Cambiare il tipo di una espressione operazione detta type-cast (esplicito) –sintassi: esempio: ( ) int x; ( double ) (x+1) intdouble
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 / U n i v e r s i t à d e l l I n s u b r i a Cambiare il tipo di una espressione esempi: ( ) int pippo; (float)pippo... /* espressione: pippo come float */ (unsigned int)204 /* espressione: */ /* 204 come intero senza segno */ 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 / U n i v e r s i t à d e l l I n s u b r i a Cambiare il tipo di una espressione: in automatico 1/2 Regola generale 1: –in una espressione mista, loperando 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; equivalente a: y = x / (double) 3; typecast implicito!
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 / U n i v e r s i t à d e l l I n s u b r i a 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 / U n i v e r s i t à d e l l I n s u b r i a Cambiare il tipo di una espressione: in automatico 2/2 Regola generale 2: –in un assegnamento, lespressione 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; equivalente a: x = (int) (3.0 / y); typecast implicito! nota: in questo caso, cè perdita di precisione (da double a int!). I compilatori bene educati avvertono (con un warning del comp).
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 / U n i v e r s i t à d e l l I n s u b r i a Assegnamenti a catena Assegnamento base = = tipo T 0 tipo T 1 expr di tipo T 0 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 / U n i v e r s i t à d e l l I n s u b r i a Cambiamento di tipo: sommario 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 / U n i v e r s i t à d e l l I n s u b r i a Esempi pratici di uso (tre quiz) N. 1: double x; x = 1 / 3; /* x e un terzo... o no? */ int numerone1, numerone2, media;... /* i due numeroni sono MOLTO grandi, fra 2 e 4 miliardi, ma positivi */ media= (numerone1 + numerone2) /2; double x, y, div; div = ???; /* voglio che div il ris della divisione intera fra x e y */ N. 2: N. 3:
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 / 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 / U n i v e r s i t à d e l l I n s u b r i a Definiamo un nuovo tipo Byte a,b,c; int main(){ Byte pippo=21, panco;... } typedef unsigned char Byte; (ricordiamoci la filosofia del C: linguaggio scarno, ma estendibile!) typedef unsigned char Byte; typedef ;