Por que vejo valores estranhos ao imprimir variables ​​não inicializadas?

No código a seguir, a variável não possui valor inicial e imprimiu essa variável.

int var; cout << var << endl; 

produção: 2514932

 double var; cout << var << endl; 

produção: 1.23769e-307

Eu não entendo esses números de saída. Alguém pode explicar isso para mim?

Simplificando, var não é inicializado e ler uma variável não inicializada leva a um comportamento indefinido .

Então não faça isso. No momento em que você fizer isso, seu programa não terá mais a garantia de fazer qualquer coisa que você disser.


Formalmente, “ler” um valor significa executar uma conversão de lvalor para rvalue. E o §4.1 afirma “… se o object não for inicializado, um programa que necessite dessa conversão tem um comportamento indefinido”.

Pragmaticamente, isso significa apenas que o valor é lixo (afinal, é fácil ver a leitura de um int , por exemplo, apenas recebe bits randoms), mas não podemos concluir isso, ou você estaria definindo um comportamento indefinido.

Para um exemplo 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, poder-se-ia concluir (através do raciocínio nos comentários) que isso nunca deveria imprimir "impossible" ; mas com comportamento indefinido, tudo é possível. Compile com g++ -02 .

Quando você faz:

int var;

Você está apenas declarando um inteiro chamado var . Você não o inicializa com um valor, portanto, qualquer que seja o local var , serão dados inúteis.

int var = 5;

Declararia var e inicializaria para 5.

Veja mais: http://en.wikipedia.org/wiki/Uninitialized_variable

O que você está obtendo é qualquer dado que esteja na pilha no local em que o compilador decidiu que a variável deve ser interpretada como um inteiro ou um duplo. Ele provavelmente será o mesmo toda vez que seu programa for executado, porque os programas geralmente se comportam de forma determinista. Embora existam também muitos casos em que acabará por não ser o mesmo de corrida para execução do seu programa. Se você mudar o seu programa ou tomar decisões com base na input do usuário antes de chegar ao código, você pode ou não obter números diferentes.

Basicamente, o valor de uma variável que você não inicializou não é especificado e pode ser absolutamente qualquer coisa. Não há rima ou razão para o que está lá.

Fazer isso geralmente é uma prática ruim. Você quer programas que se comportem de maneira previsível e ter variables ​​não inicializadas é uma fonte de imprevisibilidade. Note que, enfaticamente, não é uma fonte de aleatoriedade, apenas imprevisibilidade. A maioria dos compiladores reclamará de código assim se você ativar todos os avisos.

Em C ++, quando você declara uma variável, o compilador atribui um endereço de memory a ela. E é isso, nenhuma limpeza é feita. Isso ocorre principalmente porque o C ++ (e C) foi criado com o desempenho em mente. C ++ não gasta tempo inicializando um endereço, a menos que você diga explicitamente para fazer isso.

E o chamado lixo que você vê é o que foi deixado naquele endereço pela última variável que o usou.

Outros idiomas inicializarão os dados para você. Na verdade, o C # não permite que você use a variável até inicializá-la. Essas linguagens são projetadas para serem seguras , no sentido de que elas não permitem que você escreva um código que, por engano, use um endereço não inicializado e cause falha em seu programa ou, pior, corrompa seus dados.

você não inicializou o var nos dois casos para obter uma saída de lixo.

você fez

const int var(5);

seria inicializado com o valor 5

Quando você declara var , é atribuído um local na memory. No entanto, essa memory não está definida para nada por padrão, então você pega o que estava lá antes. Este será um valor de lixo que não tem significado.

Em C ++ isso é verdade para variables ​​de membro e variables ​​locais. No entanto, em linguagens como Java e C #, suas variables ​​de membro são automaticamente inicializadas como 0 para tipos numéricos, false para booleanos e null para referências. Isso não é feito para variables ​​locais e (pelo menos no compilador C #) sua compilation falhará se você tentar obter o valor de uma variável não inicializada.