Hai fatto questo:
union NumericType Values = { 10 }; // iValue = 10
printf("%d\n", Values.iValue);
Values.dValue = 3.1416;
Come un compilatore utilizza la memoria per questa unione è simile ad usare la variabile con la più grande dimensione e l'allineamento (nessuno di loro se ci sono diversi), e reinterpretare getto quando uno degli altri tipi del sindacato è scritto/accesso, come in:
double dValue; // creates a variable with alignment & space
// as per "union Numerictype Values"
*reinterpret_cast<int*>(&dValue) = 10; // separate step equiv. to = { 10 }
printf("%d\n", *reinterpret_cast<int*>(dValue)); // print as int
dValue = 3.1416; // assign as double
printf("%d\n", *reinterpret_cast<int*>(dValue)); // now print as int
il problema è che nella creazione dValue a 3,1416 hai completamente sovrascritto i bit che utilizzate per contenere il numero 10. il nuovo valore potrebbe sembrare spazzatura, ma è semplicemente il risultato dell'interpretazione di t egli prima (sizeof int) byte del doppio 3.1416, credendo ci sia un valore int utile lì.
Se si desidera che le due cose siano indipendenti, quindi l'impostazione del doppio non influisce sull'int iniziale memorizzata, è necessario utilizzare struct
/class
.
Essa può aiutare a prendere in considerazione questo programma:
#include <iostream>
void print_bits(std::ostream& os, const void* pv, size_t n)
{
for (int i = 0; i < n; ++i)
{
uint8_t byte = static_cast<const uint8_t*>(pv)[i];
for (int j = 0; j < 8; ++j)
os << ((byte & (128 >> j)) ? '1' : '0');
os << ' ';
}
}
union X
{
int i;
double d;
};
int main()
{
X x = { 10 };
print_bits(std::cout, &x, sizeof x);
std::cout << '\n';
x.d = 3.1416;
print_bits(std::cout, &x, sizeof x);
std::cout << '\n';
}
che, per me, ha prodotto questo output:
00001010 00000000 00000000 00000000 00000000 00000000 00000000 00000000
10100111 11101000 01001000 00101110 11111111 00100001 00001001 01000000
Fondamentalmente, la prima metà di ogni riga mostra i 32 bit che sono usato per iValue: nota il binario 1010 nel byte meno significativo (a sinistra su una CPU Intel come la mia) è 10 decimale. La scrittura 3.1416 modifica l'intero 64 bit in un modello che rappresenta 3.1416 (vedere http://en.wikipedia.org/wiki/Double_precision_floating-point_format). Il vecchio modello 1010 è sovrascritto, rovinato, non c'è più una memoria elettromagnetica.
si tratta di un problema di conversione endian? ~ Definisci "spazzatura". Questo ci aiuterebbe davvero a rispondere alla tua domanda. – jcolebrand
@drachenstern: La sua domanda sembra perfettamente formulata e formattata ... molto meglio del solito "mostrami teh codez" che riceviamo dai nuovi arrivati. – mpen
@Mark ~ Sono d'accordo. Ma dal momento che è nuovo, potrebbe essere bello avere un riferimento al sito. Inoltre, abbiamo bisogno di sapere cosa definisce "spazzatura" e sarebbe stata una buona inclusione. Almeno non l'ho collegato direttamente all'articolo di JonSkeet;) ... L'ho appena fatto per molti nuovi arrivati come un po 'di pulizie. Benvenuto nel club, sii un buon membro della comunità, quel genere di cose. Non era inteso come post dannoso. – jcolebrand