Tipi di dati semplici in C (1/3) Il C ha quattro tipi di dato semplice principali: Caratteri, char Numeri interi, int Numeri reali in virgola mobile, float Numeri reali in virgola mobile a doppia precisione, double Tutti gli altri si ottengono da quelli citati con i modificatori Ogni modificatore anticipa la dichiarazione di tipo Altera il significato del “tipo base” per adattarlo meglio ad altri contesti Modificatori: signed, unsigned, long, short sono applicabili a int signed, unsigned possono essere applicati a char long può essere applicato anche a double In C esistono anche i tipi di dato strutturati: Non sono altro che aggregazioni molteplici dati semplici
Tipi di dati semplici in C (2/3) Un carattere tra apici rappresenta una costante intera Il carattere ‘a’ rappresenta l’intero 97, mentre ‘A’ è pari a 65 Il C non fa distinzione tra caratteri e interi: Esiste una corrispondenza biunivoca, data dalla tabella dei caratteri ASCII printf("%c",‘f') restituisce f, mentre printf("%d",‘f') restituisce 102 Anche i confronti tra caratteri (≤, ≥) si basano sull’ordine nella tabella ASCII Usare char o unsigned char cambia solo la corrispondenza interi-caratteri Con unsigned tutti caratteri corrispondono esattamente ai 255 numeri ASCII Senza, i caratteri oltre il 127 ASCII corrispondono a (NumASCII - 256) La rappresentazione interna (n°bit) dipende dal calcolatore L’aggiunta di modificatori non sempre cambia il range di valori ammissibili L’allocazione di memoria per ogni tipo rispetta sempre delle regole: Range(short int) ≤ Range(int) ≤ Range(long int) Range(signed int) = Range(int) = Range(unsigned int) Lo stesso vale per gli altri tipi La tabella seguente indica quella che è la rappresentazione più comune
Tipi di dati semplici in C (2/3) TIPO N. BIT VALORI RAPPRESENTABILI char 8 Da -128 a +127 (o caratteri ASCII corrispondenti) unsigned char Da 0 a 255 (o caratteri ASCII corrispondenti) signed char Gli stessi del tipo base “char” int 16 Da -32768 a +32767 unsigned int Da 0 a 65535 signed int Gli stessi del tipo base “int” short int unsigned short int Gli stessi del tipo “unsigned int” signed short int long int 32 Da -2147483648 a +2147483647 signed long int Gli stessi del tipo “long int” unsigned long int Da 0 a 4294967295 float Circa da -3,4x10 a +3,4x10 double 64 Circa da -1,8x10 a +1,8x10 long double 80 Circa da -1,2x10 a +1,2x10 38 38 308 308 4932 4932
Promozione e Cast (1/2) Nelle espressioni, il C ammette la combinazione di tipi Se i tipi coinvolti sono eterogenei, è necessaria una conversione La conversione rende omogenea l’espressione e permette di applicare l’operazione appropriata per il tipo omogeneo ottenuto In C esistono conversioni automatiche implicite oppure manuali esplicite Regole di conversione implicita (promozione) Se l’espressione rvalue è eterogenea, le variabili char o short (incluse le versioni signed e unsigned) sono convertite temporaneamente in int Se l’espressione è ancora eterogenea, si converte temporaneamente ogni variabile di tipo inferiore nel tipo superiore, secondo questa gerarchia int < long int < unsigned int < unsigned long int < float < double < long double Una volta resa omogenea, si applicano le operazioni sul tipo omogeneo Quindi il risultato dell’espressione rvalue avrà tipo uguale a quello più in alto, secondo la gerarchia, tra quelli presenti nell’espressione Se il tipo del risultato finale rvalue è inferiore al tipo di lvalue, il tipo finale di rvalue è promosso al tipo di lvalue per fare assegnamenti omogenei Viceversa, viene convertito nel tipo inferiore (perdita di precisione/informazione)
Promozione e Cast (2/2) Esempi: dati int n=5, m=2; float x=4.0; x = n+x n è promosso a float (5.0) e alla fine x vale 9.0 n = n/m la divisione è tra interi e quindi troncata, alla fine n vale 2 n = n/x n è promosso a float (5.0) e la divisione tra float restituisce 1.25 però con l’assegnamento a int viene troncata, e alla fine n vale 1 x = n/m la divisione tra interi è sempre troncata e restituisce 2 però con l’assegnamento a float il risultato è promosso a float e x vale 2.0 Si possono fare anche conversioni esplicite (cast) Si specifica il tipo in cui si desidera avere il risultato di una espressione mettendolo tra ( ) appena prima del rvalue Tutte le variabili in rvalue sono convertite a forza nel tipo indicato e le operazioni sono in seguito svolte su tale tipo Convertire in tipi inferiori comporta perdita di informazione (troncamento) x = (float) n/m n e m sono convertiti in float e la divisione tra float non è troncata ma restituisce un float, per cui alla fine x vale 2.5 n = (int) n/x x è convertito in int (4) e la divisione tra interi è troncata, per cui alla fine n vale 1 (perdita di precisione)