ePerTutti


Appunti, Tesina di, appunto informatica

Conversioni di tipo

ricerca 1
ricerca 2

Conversioni di tipo


Per conversione di tipo si intende una operazione volta a trasformare un valore di un certo tipo in un altro valore di altro tipo. Questa operazione è molto comune in tutti i linguaggi, anche se spesso il programmatore non se ne rende conto; si pensi ad esempio ad una operazione aritmetica (somma, divisione) applicata ad un operando di tipo int e uno di tipo float. Le operazioni aritmetiche sono definite su operandi dello stesso tipo e pertanto non è possibile eseguire immediatamente l'operazione; si rende pertanto necessario trasformare gli operandi in modo che assumano un tipo comune su cui è possibile eseguire l'operazione. Quello che generalmente fa, nel nostro caso, un compilatore di un qualsiasi linguaggio e convertire il valore intero in un reale e poi eseguire la somma tra reali, restituendo un reale.




Non sempre comunque le conversioni di tipo sono decise dal compilatore, in alcuni linguaggi (C, C++, Turbo Pascal) le conversioni di tipo possono essere richieste dal programmatore. Si distingue quindi tra conversioni implicite e conversioni esplicite: le prime (dette anche coercizioni) sono eseguite dal compilatore in modo del tutto trasparente al programmatore, mentre le seconde sono quelle richieste esplicitamente:


int i = 5;

float f = 0.0;

double d = 1.0;


d = f + i;


d = (double)f + (double)i;

// questa riga è da leggere come

// d = ( ( (double)f ) + ( (double)i ) );


L'esempio precedente mostra entrambi i casi.


Nel primo assegnamento, l'operazione di somma è applicata ad un operando intero e uno di tipo float, per poter eseguire la somma il compilatore C++ prima converte i al tipo float, quindi esegue la somma (entrambi gli operandi hanno lo stesso tipo) e poi, poiché la variabile d è di tipo double, converte il risultato al tipo double e lo assegna alla variabile.


Nel secondo assegnamento, il programmatore richiede esplicitamente la conversione di entrambi gli operandi al tipo double prima di effettuare la somma e l'assegnamento (la conversione ha priorità maggiore delle operazioni aritmetiche).


Una conversione di tipo esplicita viene richiesta con la sintassi


( <NuovoTipo> ) <Valore>


// oppure


<NuovoTipo> ( <Valore> )


// ma questo metodo può essere utilizzato solo con

// nomi semplici (ad esempio non funziona con char*)


NuovoTipo può essere una qualsiasi espressione di tipo, anche una che coinvolga tipi definiti dall'utente; ad esempio:


int a = 5;

float f =2.2;


(float) a

// oppure

float (a)


// se Persona è un tipo definito

// dal programmatore


(Persona) f

// oppure

Persona (f)


Le conversioni tra tipi primitivi sono già predefinite nel linguaggio e possono essere utilizzate in qualsiasi momento, il compilatore comunque le utilizza solo se il tipo di destinazione è compatibile con quello di origine (cioè può rappresentare il valore originale). Le conversioni da e a un tipo definito dall'utente richiedono che il compilatore sia informato riguardo a come eseguire l'operazione.

Per convertire un tipo primitivo (float, int, unsigned int) in uno definito dall'utente è necessario che il tipo utente sia una classe (o una struttura) e che sia definito un costruttore (pubblico) che ha come unico argomento un parametro del tipo primitivo:


class Test ;


Test::Test(int a)


Il metodo va naturalmente bene anche quando il tipo di partenza è un tipo definito dall'utente.

Per convertire invece un tipo utente ad un tipo primitivo è necessario definire un operatore di conversione; con riferimento al precedente esempio, il metodo da seguire è il seguente:


Test::operator int()


Se cioè si desidera poter convertire un tipo utente X in un tipo primitivo T bisogna definire un operatore con nome T:


X::operator T()


Si noti che non è necessario indicare il tipo del valore restituito, è indicato dal nome dell'operatore stesso; si faccia inoltre attenzione quando si definisce un operatore di conversione, poiché questo non è disponibile solo al programmatore, ma anche al compilatore che potrebbe utilizzarlo senza dare alcun avviso al programmatore.


Questa tecnica funziona anche per conversioni verso tipi definiti dal programmatore e in effetti per il compilatore le due tecniche sono praticamente equivalenti e non c'è motivo per preferire una tecnica all'altra; tuttavia, poiché i tipi predefiniti non sono classi, non è possibile utilizzare la tecnica del costruttore per trasformare un tipo utente in uno predefinito (ad esempio int o char * ).


Un fattore da tenere presente, quando si parla di conversioni, è che non sempre una conversione di tipo preserva il valore:


ad esempio nella conversione da float a int in generale si riscontra una perdita di precisione, perché la rappresentazione adottata per gli interi è incompatibile con quella adottata per i reali. Da questo punto di vista si può distinguere tra conversione di tipo con perdita di informazione e conversione di tipo senza perdita di informazione. In particolare in quest'ultimo caso si parla di conversioni triviali e promozione di tipo.


Le conversioni triviali sono:


DA:     A:


T   T&

T&  T

T[ ]    T*

T(args)     T (*) (args)

T   const T

T   volatile T

T*  const T*

T*  volatile T*



Per promozione di tipo si intende invece una conversione che trasforma un valore di un tipo in un valore di un tipo più 'grande', ad esempio un int in un long int oppure in un float, un tipo cioè il cui insieme di valori rappresentabili includa l'insieme dei valori del tipo di partenza.





Privacy

© ePerTutti.com : tutti i diritti riservati
:::::
Condizioni Generali - Invia - Contatta