2010-02-07 22 views
37

Según tengo entendido, una variable int se inicializará automáticamente en 0; sin embargo, no lo es. El siguiente código imprime un valor aleatorio.Inicialización de variable en C++

int main() 
{ 
    int a[10]; 
    int i; 
    cout << i << endl; 
    for(int i = 0; i < 10; i++) 
     cout << a[i] << " "; 
    return 0; 
} 
  • ¿Qué reglas, en su caso, se aplican a la inicialización?
  • Específicamente, ¿en qué condiciones se inicializan las variables automáticamente?

Respuesta

62

Se inicializa automáticamente si

  • es un/instancia estructura de clases en las que el constructor predeterminado inicializa todos los tipos primitivos; como MyClass instance;
  • utiliza la sintaxis del inicializador de matriz, p.int a[10] = {} (todos a cero) o int a[10] = {1,2}; (todos a cero, excepto los dos primeros elementos: a[0] == 1 y a[1] == 2)
  • Lo mismo se aplica a las clases/estructuras no agregadas, p. MyClass instance = {}; (Más información sobre esto se puede encontrar here)
  • es una variable
  • la variable global y/o externa se define static (no importa si dentro de una función o de alcance/espacio de nombres global) - gracias Jerry

¡Nunca confíe en que una variable de tipo simple (int, largo, ...) se inicialice automáticamente! Puede suceder en idiomas como C#, pero no en C & C++.

+7

El primer punto es un poco inexacto. Se inicializará automáticamente si no es un tipo de POD. :) – jalf

+0

Derecha, cambió eso;) thx – AndiDog

+2

Las variables con duración de almacenamiento estático de "tipo simple" también se inicializan a cero (o un puntero nulo, en el caso de los punteros). Esto sería algo declarado como 'estático' dentro de una función, o algo declarado en el ámbito del espacio de nombres (es decir, fuera de cualquier función). –

12

int no se inicializa a cero. Cuando dice int i;, todo lo que hace es reservar espacio para un número entero. El valor en esa ubicación no se inicializa. Eso solo se hace con usted, digamos int i = 0; (o int i = 5; en cuyo caso el valor se inicializa a 5). En cualquier caso, es una buena práctica inicializar una variable a algún valor conocido. De lo contrario, i contiene el valor aleatorio que estaba en esa ubicación de memoria cuando el espacio estaba reservado para ello. Esta es la razón por la cual cout imprime un valor aleatorio.

Los valores predeterminados dependen de la implementación del idioma. Algunos idiomas lo inicializarán a algún valor "sano" (como 0 quizás). Como regla general, siempre inicializo una variable a algún valor razonable (a menos que sepa que voy a inicializarlo en algo más con seguridad antes de usarlo). Como mencioné antes, es imprudente para suponer que el valor va a ser algo sensato. Puede o no ser (dependiendo del idioma, o la implementación del intérprete/compilador de ese idioma).

2

Las variables locales no se inicializan a menos que lo haga usted mismo. Lo que está viendo es cualquier basura que haya en la pila antes de que se llame su método.

4

Este post lo dice mejor: http://www.velocityreviews.com/forums/showpost.php?p=1528247&postcount=10

hay ningún constructor "por defecto" para tipos no de clase, pero no es por defecto inicialización (cero). Por desgracia, para la compatibilidad con C braindead, la inicialización por defecto no se hace para este tipo de POD en las siguientes circunstancias :

desnudo (es decir, sin declarado inicializadores) variables locales a una clase o función .

instancias dinámicamente asignadas.

Sin embargo, en otros lugares (en particular variables estáticas) y en el caso de nada dado el inicializador vacío parametros (cuando es válida), obtiene el valor por defecto inicialización (cero).

+1

No diría que se debe a la "compatibilidad con el cerebro con C", creo que tiene más que ver con la filosofía "no pagues por lo que no usas" de C++. – Manuel

3

En C++, las variables automáticas no están definidas hasta que se les asigna un valor explícitamente. Quizás estés pensando en C# u otros lenguajes .Net o Java.

5

Ver sección 4.9.5 Inicialización del lenguaje de programación C++.

Dependiendo de si su variable es local, estática, definida por el usuario o const la inicialización predeterminada puede suceder.

Como está utilizando POD (tipos de datos antiguos simples), la variable automática no se inicializa a ningún valor predeterminado.

4

Para forzar la inicialización de un POD (que es int), puede utilizar la sintaxis copia inicializador:

#include <iostream> 

int main() { 
    int i = int(); 
    int j; 

    std::cout << "i: " << i << std::endl; 
    // warning: undefined behavior 
    std::cout << "j: " << j << std::endl; 
} 

Ésta es caídas en "sólo paga por lo que usa". Si va a asignar posteriormente un valor a la variable, o posiblemente no la use en absoluto, no hay razón para hacer el trabajo de inicializarla. Para obtener eso, tienes que pedir explícitamente que se haga ese trabajo.

+1

esto no funciona para 'unsigned int's o' long long' o tipos similares que consisten en más de una palabra en GCC, sin embargo sí funciona en MSVC, pregunta relacionada: http://stackoverflow.com/questions/2144012/explicit-type-conversion-and-multiple-simple-type-especificadores – smerlin

0

Aunque su descubrimiento reciente puede no ser bienvenido (porque es posible que deba inicializar algunas variables que otros lenguajes habrían solucionado), puede significar menos ciclos de CPU y, por lo tanto, un código más rápido.

2

Si no se especifica un inicializador para un objeto, el objeto se inicializa por defecto; si no se realiza la inicialización, un objeto con una duración de almacenamiento automática o dinámica tiene un valor indeterminado.

Par. 8.5, la sección 11 de un reciente proyecto N3092.pdf C++ 0x,

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/

3

Los diferentes sistemas operativos (es decir, OS X vs Ubuntu Linux) va a reaccionar de manera diferente a inicializar frente variables inicializadas en C++. En mi experiencia, la versión OS X de gcc compilará e imprimirá 2 para ambas versiones del código a continuación. Donde como si estuviera trabajando en una máquina Ubuntu Linux, el primer bloque de código imprimirá lo que sucedió en la ubicación de la memoria a la que hace referencia la variable (+2 después del ciclo).

int c; 

    for(int i = 0; i < 3; i++) 
    { 
     c++; 
    } 

    cout << c << endl; 

Donde como, todos le dará los mismos resultados para:

int c = 0; 

    for(int i = 0; i < 3; i++) 
    { 
     c++; 
    } 

    cout << c << endl; 
-1

Aquí int i; es una variable automática que se debe inicializar manualmente. auto variable no se inicializa automáticamente en c y C++.

Si desea compilador para inicializar, entonces es necesario utilizar siguientes cosas,

declaran i variable como estática.

static int i; // zero assign to the i by compiler.

declarar i como variable global [fuera de la principal()].

Cuestiones relacionadas