L'output è 2, 2, significa che il programma ha restituito la radice quadrata di 5 come 2 e la radice quadrata di 8 anche come 2. Quindi, le prime due dichiarazioni in principale() La funzione ha piazzato le risposte della radice quadrata di 5 e la radice quadrata di 8. Questo articolo non discute di pavimenti o soffitto in C++. Piuttosto, questo articolo discute la conversione di un tipo C ++ in un altro tipo C ++ appropriato; indicando qualsiasi approssimazione in valore effettuato, perdita di precisione o vincolo aggiunto o rimosso. La conoscenza di base di C ++ è un prerequisito per comprendere questo articolo.
Contenuto dell'articolo
Conversioni integrali
Le conversioni integrali sono conversioni interi. I numeri interi non firmati includono "Carbone senza segno", "Short Int non firmato", "Insigned Int", "Unsigned Long Int" e "Unsigned Long Long Int."I numeri interi firmati corrispondenti includono" Char firmato "," Short int "," int "," long int "e" long long int."Ogni tipo int dovrebbe essere tenuto in tanti byte quanto il suo predecessore. Per la maggior parte dei sistemi, un tipo di entità può essere convertito in un tipo corrispondente senza alcun problema. Il problema si verifica durante la conversione da un tipo di intervallo più grande in un tipo di intervallo più piccolo o quando si converte un numero firmato in un numero non firmato corrispondente.
Ogni compilatore ha un valore massimo che può essere necessario per il breve int. Se un numero superiore a quel. Se il programmatore è fortunato, il compilatore avvertirà di problemi con una conversione inappropriata. La stessa spiegazione si applica alle conversioni di altri tipi int.
L'utente dovrebbe consultare la documentazione del compilatore per determinare i valori limitanti per ciascun tipo di entità.
Se un numero INT a breve firmato negativo deve essere convertito in un numero INT breve non firmato, il compilatore seguirà un po 'di algoritmo e restituirà un numero positivo all'interno dell'intervallo del breve int non firmato. Questo tipo di conversione dovrebbe essere evitato. La stessa spiegazione si applica alle conversioni di altri tipi int.
Qualsiasi numero intero, tranne 0, può essere convertito in true booleano. 0 viene convertito in falso booleano. Il seguente codice illustra questo:
int a = -27647;1 significa vero e 0 significa falso nell'output
Conversioni a punta mobile
I tipi di punto mobile includono "galleggiante", "doppio" e "lungo doppio."I tipi di punto mobile non sono raggruppati in firmati e non firmati, come numeri interi. Ogni tipo può avere un numero firmato o non firmato. Un tipo a punto mobile dovrebbe avere almeno la stessa precisione del suo predecessore. Cioè, "lungo doppio" dovrebbe avere una precisione uguale o maggiore a "doppio" e "doppio" dovrebbe avere una precisione uguale o maggiore per "galleggiare."
Ricorda che l'intervallo di un tipo a punto mobile non è continuo; Piuttosto, è in piccoli gradini. Maggiore è la precisione del tipo, minori sono i passaggi e maggiore è il numero di byte per archiviare il numero. Quindi, quando un numero di punto mobile viene convertito da un tipo di precisione inferiore a un tipo di precisione più elevato, il programmatore deve accettare un falso aumento della precisione e un possibile aumento del numero di byte per il numero di archiviazione. Quando un numero di punto mobile viene convertito da un tipo di precisione più elevato a un tipo di precisione inferiore, il programmatore deve accettare una perdita di precisione. Se il numero di byte per il numero di archiviazione deve essere ridotto, il compilatore seguirà un po 'di algoritmo e restituirà un numero come sostituto (che probabilmente non è ciò che il programmatore vuole). Inoltre, tieni presente problemi fuori portata.
Conversioni fluttuanti
Un numero di punto mobile viene convertito in un numero intero troncando la parte frazionaria. Il seguente codice illustra questo:
float f = 56.953;Quando un intero viene convertito in un galleggiante, il valore visualizzato come galleggiante è lo stesso che è stato digitato come un numero intero. Tuttavia, l'equivalente del galleggiante potrebbe essere il valore esatto o avere una leggera differenza frazionaria che non viene visualizzata. Il motivo della differenza frazionaria è che i numeri a punto mobile sono rappresentati nel computer in piccole fasi frazionarie, e quindi rappresentare esattamente l'intero sarebbe una coincidenza. Quindi, sebbene l'intero visualizzato come un galleggiante sia lo stesso di digitazione, il display può essere un'approssimazione di ciò che è memorizzato.
Classifica di conversione interi
Qualsiasi tipo di intero ha un grado che è stato dato. Questa classifica aiuti nella conversione. La classifica è relativa; I ranghi non sono a livelli fissi. Tranne Char e firmato Char, non ci sono due numeri interi firmati hanno lo stesso rango (supponendo che Char sia firmato). I tipi di interi non firmati hanno la stessa classifica dei corrispondenti tipi interi firmati. La classifica è la seguente:
Promozioni integrali
Le promozioni integrali sono promozioni interi. Non vi è alcun motivo per cui un numero intero di meno byte non possa essere rappresentato da un numero intero di byte più grandi. Le promozioni Integer si occupa di tutto ciò che segue:
Conversioni aritmetiche solite
Considera il seguente codice:
fluttuare f = 2.5;C ++ ha normali conversioni aritmetiche che il programmatore deve sapere per evitare errori nella codifica. Le solite conversioni aritmetiche sugli operatori binari sono le seguenti:
Altrimenti, la promozione intera si svolgerà come segue:
Promozione a punta mobile
I tipi di punto mobile includono "galleggiante", "doppio" e "lungo doppio."Un tipo a punto mobile dovrebbe avere almeno la stessa precisione del suo predecessore. La promozione a punta mobile consente la conversione dal galleggiante al doppio o dal doppio a doppio lungo.
Conversioni di puntatore
Un puntatore di un tipo di oggetto non può essere assegnato a un puntatore di un tipo di oggetto diverso. Il seguente codice non si compilerà:
int id = 6;Un puntatore null è un puntatore il cui valore dell'indirizzo è zero. Un puntatore nullo di un tipo di oggetto non può essere assegnato a un puntatore null di un tipo di oggetto diverso. Il seguente codice non si compilerà:
int id = 6;Un const puntatore null di un tipo di oggetto non può essere assegnato a un const puntatore null di un tipo di oggetto diverso. Il seguente codice non si compilerà:
int id = 6;Un puntatore null può essere assegnato un valore di indirizzo diverso per il suo tipo. Il seguente codice illustra questo:
float idf = 2.5;L'output è 2.5.
Come previsto, una costante di punta nullo non può essere assegnato alcun valore dell'indirizzo del suo tipo. Il seguente codice non si compilerà:
float idf = 2.5;Tuttavia, è possibile assegnare una costante di puntatore nullo a un normale puntatore, ma dello stesso tipo (questo è prevedibile). Il seguente codice illustra questo:
float idf = 2.5;L'output è 0.
Due valori di puntatore null dello stesso tipo confronta (==) uguali.
Un puntatore a un tipo di oggetto può essere assegnato a un puntatore da vuoto. Il seguente codice illustra questo:
float idf = 2.5;Il codice si compila senza un avviso o un messaggio di errore.
Funzione a conversioni di punta
Un puntatore a una funzione che non lancerebbe un'eccezione può essere assegnato a un puntatore per funzionare. Il seguente codice illustra questo:
#includereL'output è con noxcept.
Conversioni booleane
In C ++, le entità che possono causare false includono "zero", "puntatore null" e "puntatore membro null."Tutte le altre entità si traducono in vera. Il seguente codice illustra questo:
bool a = 0.0; cout << a <<'\n';L'output è:
0 // per falseLVALUE, PRVALUE E XVALUE
Considera il seguente codice:
int id = 35;L'output è 35. Nel codice, ID e ID1 sono LValues perché identificano una posizione (oggetto) in memoria. L'output 35 è un prvalue. Qualsiasi letterale, tranne una corda letterale, è un prvalue. Altri prvalori non sono così evidenti, come negli esempi che seguono. Considera il seguente codice:
int id = 62;PTR è un LVALUE perché identifica una posizione (oggetto) in memoria. D'altra parte, Pter non è un LVALUE. Pter è un puntatore, ma non identifica alcuna posizione in memoria (non punta a nessun oggetto). Quindi, Pter è un prvalue.
Considera il seguente codice:
void fn ()Fn () e (*func) () sono espressioni LValue perché identificano un'entità (funzione) nella memoria. D'altra parte, (*functn) () non è un'espressione di lValue. (*functn) () è un puntatore a una funzione, ma non identifica alcuna entità in memoria (non punta a nessuna funzione in memoria). Quindi, (*functn) () è un'espressione prvalue.
Ora, considera il seguente codice:
Struttura sS è una classe e OBJ è un oggetto istanziato dalla classe. OBJ identifica un oggetto in memoria. Una classe è un'unità generalizzata. Quindi, S non identifica realmente nessun oggetto in memoria. Si dice che S sia un oggetto senza nome. S è anche un'espressione prvalue.
Il focus di questo articolo è sui prvalori. Prvalue significa puro rValue.
XValue
XValue sta per un valore in scadenza. I valori temporanei stanno scaduti valori. Un lValue può diventare un XValue. Un prvalue può anche diventare un XValue. Il focus di questo articolo è sui prvalori. Un XValue è un LVALUE o un riferimento RValue senza nome il cui spazio di archiviazione può essere riutilizzato (di solito perché è vicino alla fine della sua vita). Considera il seguente codice che funziona:
Struttura sL'espressione “int q = s ().N;" copie qualunque valore n mantiene a q. S () è solo un mezzo; Non è un'espressione regolarmente usata. S () è un prvalue il cui uso lo ha convertito in un XVALUE.
Conversioni da lValue-to-ralue
Considera la seguente dichiarazione:
int ii = 70;70 è un prvalue (rvalue) e II è un lValue. Ora, considera il seguente codice:
int ii = 70;Nella seconda affermazione, II è nella situazione di un prvalue, quindi II diventa un prvalue lì. In altre parole, il compilatore converte II in un prvalue implicitamente. Cioè, quando viene utilizzato un LVALUE in una situazione in cui l'implementazione si aspetta un punto.
Conversioni di array-to-pointer
Considera il seguente codice che funziona:
char* p;L'output è B. La prima affermazione è un'espressione ed è un puntatore a un personaggio. Ma a quale personaggio è l'affermazione che punta? - Nessun carattere. Quindi, è un prvalue e non un lValue. La seconda affermazione è un array in cui Q [] è un'espressione di LValue. La terza affermazione trasforma il prvalue, p, in un'espressione di lValue, che indica il primo elemento dell'array.
Conversioni da funzione a pointer
Considera il seguente programma:
#includereL'espressione "void (*func) ();" è un puntatore a una funzione. Ma a quale funzione è l'espressione che punta? - Nessuna funzione. Quindi, è un prvalue e non un lValue. Fn () è una definizione di funzione, dove fn è un'espressione di lValue. In main (), “Func = &fn;"Trasforma il prvalue, func, in un'espressione di lValue che indica la funzione, fn ().
Conversioni di materializzazione temporanea
In C ++, un prvalue può essere convertito in un XValue dello stesso tipo. Il seguente codice illustra questo:
Struttura sQui, il prvalue, s (), è stato convertito in un XValue. Come XValue, non durerebbe a lungo - vedi più spiegazioni sopra.
Conversioni di qualificazione
Un tipo qualificato CV è un tipo qualificato dalla parola riservata, "const" e/o dalla parola riservata, "volatile."
La qualificazione CV è anche classificata. Nessuna qualificazione CV è inferiore alla qualifica "const", che è inferiore alla qualifica "const volatile". Nessuna qualificazione CV è inferiore alla qualifica "volatile", che è inferiore alla qualificazione "const volatile". Quindi, ci sono due flussi di classifica delle qualifiche. Un tipo può essere più qualificato con un altro.
Un tipo di qualificato CV inferiore può essere convertito in un tipo di prvalue qualificato più CV. Entrambi i tipi dovrebbero essere puntatore a CV.
Conclusione
Le entità C ++ possono essere convertite da un tipo in un tipo correlato implicitamente o esplicitamente. Tuttavia, il programmatore deve capire cosa può essere convertito e cosa non può essere convertito e in quale forma. La conversione può avvenire nei seguenti domini: conversioni integrali, conversioni a punta mobile, conversioni integrali galleggianti, conversioni aritmetiche usuali, conversioni di punta , Conversioni da funzione a pointer, conversioni di materializzazione temporanea e conversioni di qualificazione.