¿Por qué veo valores extraños cuando imprimo variables no inicializadas?

En el siguiente código, la variable no tiene valor inicial e imprimió esta variable.

int var; cout << var << endl; 

salida: 2514932

 double var; cout << var << endl; 

salida: 1.23769e-307

No entiendo estos números de salida. ¿Puede alguien explicarme esto?

En pocas palabras, var no se inicializa y leer una variable no inicializada conduce a un comportamiento indefinido .

Entonces no lo hagas En el momento en que lo haga, ya no se garantiza que su progtwig hará lo que usted diga.


Formalmente, “leer” un valor significa realizar una conversión lvalue-r-value en él. Y §4.1 afirma “… si el objeto no está inicializado, un progtwig que necesita esta conversión tiene un comportamiento indefinido”.

Pragmáticamente, eso solo significa que el valor es basura (después de todo, es fácil ver la lectura de un int , por ejemplo, solo obtiene bits aleatorios), pero no podemos concluir esto, o estaríamos definiendo un comportamiento indefinido.

Para un ejemplo real, considere:

 #include  const char* test() { bool b; // uninitialized switch (b) // undefined behavior! { case false: return "false"; // garbage was zero (zero is false) case true: return "true"; // garbage was non-zero (non-zero is true) default: return "impossible"; // options are exhausted, this must be impossible... } } int main() { std::cout << test() << std::endl; } 

Naïvely, uno concluiría (a través del razonamiento en los comentarios) que esto nunca debería imprimir "impossible" ; pero con un comportamiento indefinido, todo es posible. Comstackrlo con g++ -02 .

Cuando tu lo hagas:

int var;

Usted solo está declarando un entero llamado var . No lo inicializa con un valor, por lo que en cualquier ubicación que var sea, serán datos basura.

int var = 5;

Declararía var e lo inicializaría a 5.

Ver más: http://en.wikipedia.org/wiki/Uninitialized_variable

Lo que obtienes es cualquier dato que haya estado en la stack en el lugar donde el comstackdor decidió que la variable debería interpretarse como un entero o un doble. Probablemente será el mismo cada vez que se ejecute su progtwig porque los progtwigs generalmente se comportan de manera determinista. Aunque también hay muchos casos en los que terminará siendo el mismo desde la ejecución de su progtwig. Si cambia su progtwig en lo más mínimo, o si toma decisiones basadas en los comentarios del usuario antes de llegar a ese código, puede o no obtener diferentes números.

Básicamente, el valor de una variable que no ha inicializado no está especificado y puede ser absolutamente cualquier cosa. No hay rima o razón para lo que hay allí.

Hacer esto es generalmente una mala práctica. Desea progtwigs que se comporten de manera predecible, y tener variables no inicializadas es una fuente de imprevisibilidad. Tenga en cuenta que no es una fuente de aleatoriedad, simplemente imprevisibilidad. La mayoría de los comstackdores se quejarán de un código como ese si activa todas las advertencias.

En C ++, cuando declaras una variable, el comstackdor le asigna una dirección de memoria. Y eso es todo, no se realiza ninguna limpieza. Esto se debe principalmente a C ++ (y C) donde se construye teniendo en cuenta el rendimiento. C ++ no pierde tiempo inicializando una dirección a menos que se lo indique explícitamente.

Y la llamada basura que ves es lo que quedó en esa dirección por la última variable que lo usó.

Otros idiomas inicializarán los datos por ti. De hecho, C # no le permitirá usar la variable hasta que la inicialice. Esos lenguajes están diseñados para ser seguros , en un sentido que no le permiten escribir un código que utiliza una dirección no inicializada erróneamente y que bloquea su progtwig o, lo que es peor, daña sus datos.

no inicializó var en ninguno de los casos, por lo que obtiene salida de basura.

habías hecho

const int var(5);

sería inicializado con el valor 5

Cuando declaras var, se le asigna una ubicación en la memoria. Sin embargo, esa memoria no está configurada de manera predeterminada, por lo que puede recoger lo que haya antes. Este será un valor de basura que no tiene ningún significado.

En C ++ esto es cierto tanto para las variables miembro como para las variables locales. Sin embargo, en idiomas como Java y C # sus variables de miembro se inicializan automáticamente a 0 para tipos de números, falso para booleanos y nulo para referencias. Esto no se hace para las variables locales y (al menos en el comstackdor de C #) su comstackción fallará si intenta tomar el valor de una variable no inicializada.