2012-05-10 23 views
5

define una variable flotante a, convierte a flotador & y int &, ¿qué significa esto? Después de la conversión, a es una referencia de sí mismo? ¿Y por qué los dos resultados son diferentes?¿Qué significa esto? (int &) a

#include <iostream> 
using namespace std; 
int 
main(void) 
{ 
    float a = 1.0; 
    cout << (float &)a <<endl; 
    cout << (int &)a << endl; 

    return 0; 
} 


thinkpad ~ # ./a.out 
1 
1065353216 
+0

¿Es esta tarea? – caskey

Respuesta

14
cout << (float &)a <<endl; 
cout << (int &)a << endl; 

La primera se trata a los bits en una como si fuera un flotador. El segundo trata los bits como si fuera un int. Los bits de flotador 1.0 acaba de pasar a ser los bits para número entero 1065353216.

Es básicamente el equivalente de:

float a = 1.0; 
int* b = (int*) &a; 
cout << a << endl; 
cout << *b << endl; 

(int &) a proyecta una a una referencia a un número entero. En otras palabras, una referencia entera a a. (Que, como ya he dicho, trata el contenido de a como un entero.)

Editar: Estoy mirando ahora para ver si esto es válido. Sospecho que no es así. Depende de que el tipo sea menor o igual que el tamaño real.

+4

Eso es interesante.No sabía que el casting a un tipo de referencia era efectivamente equivalente a realizar un elenco de reinterpretación. –

+0

@OliCharlesworth No sé si estás hablando en serio o es sarcástico, así que por favor explica si no lo haces en serio. (No estoy seguro de si esto es válido o no. Hasta ahora, nunca he visto un reparto como referencia a un tipo no relacionado. Estoy intentando buscar algo del estándar, pero no tengo mucha suerte.) Editar: Para aclarar un poco, en mi publicación, estoy explicando lo que está sucediendo, no lo que está garantizado que sucederá. Supongo que debería aclarar eso en la respuesta. – Corbin

+0

ahora, la primera parte que entiendo. pero la parte secundaria, (int &) a, estoy un poco confundida, porque cuando definimos una referencia, debemos inicializar la referencia, ¿verdad? como int &a = b; pero este caso, ¿cómo explicarlo? (int &) a ahora es una referencia entera, ¿pero no conocemos la variable a la que se refiere? –

2

Los valores son diferentes porque interpretar un float como int & (referencia a int) abre las puertas de par en par. a no es un int, por lo que casi cualquier cosa podría suceder cuando lo haga. Da la casualidad que mirar float como int le da 1065353216, pero dependiendo de la arquitectura de la máquina subyacente podría ser 42 o un elefante en un tutú rosa o incluso un choque.

Tenga en cuenta que esto no es lo mismo que fundir a int, que comprende cómo convertir de float a . Casting al int & solo mira los bits en la memoria sin entender cuál es el significado original.

+0

¿Está diciendo que esto es un comportamiento indefinido, o simplemente definido por la implementación? –

+0

@OliCharlesworth No sé lo que dice, pero el estándar dice claramente que es un comportamiento indefinido. (El estándar también deja bastante claro que la intención es que una implementación haga lo que una persona familiarizada con la arquitectura de la máquina esperaría, lo que en algunas arquitecturas podría significar el bloqueo de ciertos valores de punto flotante. (Nunca escuché hablar de una arquitectura) donde esperaría un elefante en un tutú rosa, sin embargo) –

+0

Quiero decir que es un comportamiento indefinido, sí. El elefante en un tutú rosa es improbable, pero está permitido por el estándar ... –

9

Significa un comportamiento indefinido :-).

En serio, es una forma de tipo de juego de palabras. a es un float, pero a es también un bloque de memoria (normalmente cuatro bytes) con bits en él. (float&)a significa tratar ese bloque de memoria como si fuera un float (en otras palabras, lo que realmente es); (int&)a significa tratarlo como int. Formalmente, el acceso a un objeto (como a) a través de una expresión lvalue con un tipo diferente al tipo real del objeto es un comportamiento indefinido, a menos que el tipo sea un tipo de carácter. Prácticamente, si los dos tipos tienen el mismo tamaño, esperaría que los resultados fueran una reinterpretación del patrón de bits. En el caso de float, el patrón de bits contiene bits para el signo, un exponente y una mantisa. Normalmente, el exponente usará alguna notación de exceso-n, y solo 0.0 tendrá 0 como exponente. (Algunas representaciones, incluida la utilizada en las PC, no almacenarán el bit de orden alto de la mantisa, ya que en una forma normalizada en la base 2, siempre debe ser 1. En tales casos, la mantisa almacenada para 1.0 tendrá todos los bits 0.) También típicamente (y no conozco ninguna excepción aquí), el exponente se almacenará en los bits de orden superior. El resultado es que cuando "escribe un juego de palabras" con un valor de coma flotante en un entero del mismo tamaño, el valor será bastante grande, independientemente del valor del punto flotante.

+0

Pero lo mismo significa reinterpret_cast, por lo tanto, lo que sucede es la implementación definida. O, ¿estoy equivocado? –

+1

@VJovic En este caso, se trata de un 'reinterpret_cast'. La conversión misma está más o menos bien definida (siempre que no se violen las restricciones de alineación). la conversión es un comportamiento formalmente indefinido (pero la intención es que hagan lo que alguien familiarizado con la arquitectura subyacente esperaría). –

Cuestiones relacionadas