tipos - tag c jsp
Inicializando variables en C (10)
En general, no es necesario inicializar una variable, con 2 excepciones notables:
- Está declarando un puntero (y no lo asigna de inmediato); siempre debe establecerlos en NULL como buen estilo y programación defensiva.
- Si, cuando declara la variable, ya sabe qué valor se le asignará. Las tareas adicionales consumen más ciclos de CPU.
Más allá de eso, se trata de lograr que las variables se encuentren en el estado correcto en el que las desea para la operación que va a realizar. Si no va a leerlos antes de que una operación cambie su valor (y a la operación no le importa en qué estado se encuentra), no es necesario inicializarlos.
En lo personal, siempre me gusta inicializarlos de todos modos; si olvidó asignarle un valor, y se pasa a una función por error (como una longitud de búfer restante), el 0 generalmente se maneja de forma limpia, 32532556 no lo sería.
Sé que a veces, si no inicializa un int
, obtendrá un número aleatorio si imprime el número entero.
Pero inicializar todo a cero parece un poco tonto.
Lo pregunto porque estoy comentando mi proyecto de C, estoy bastante claro con la sangría y se compila completamente (90/90 gracias a Stackoverflow) pero quiero obtener 10/10 en los puntos de estilo.
Entonces, la pregunta: ¿cuándo es apropiado inicializar, y cuándo debería declarar una variable?
int a = 0;
contra
int a;
Existen varias circunstancias en las que no debe inicializar una variable:
- Cuando tiene una duración de almacenamiento estático (palabra clave
static
o var global) y desea que el valor inicial sea cero. La mayoría de los compiladores realmente almacenarán ceros en el binario si lo inicializa explícitamente, lo que generalmente es solo un desperdicio de espacio (posiblemente un desperdicio enorme para arreglos grandes). - Cuando pasará inmediatamente la dirección de la variable a otra función que llena su valor. Aquí, la inicialización es solo una pérdida de tiempo y puede confundir a los lectores del código que se preguntan por qué está almacenando algo en una variable que está a punto de sobrescribirse.
- Cuando no se puede determinar un valor significativo para la variable hasta que el código posterior haya finalizado la ejecución. En este caso, es activamente dañino inicializar la variable con un valor ficticio como cero / NULL, ya que esto evita que el compilador le advierta si tiene algunas rutas de código donde nunca se asigna un valor significativo. Los compiladores son buenos para advertirle sobre el acceso a variables no inicializadas, pero no pueden advertirle acerca de las variables de "todavía contiene valores ficticios".
Aparte de estos problemas, diría que en general es una buena práctica inicializar sus variables no estáticas cuando sea posible.
Inicializar una variable, incluso si no es estrictamente necesaria, SIEMPRE es una buena práctica. Los pocos caracteres adicionales (como " = 0
") escritos durante el desarrollo pueden ahorrar horas de depuración más tarde, especialmente cuando se olvida que algunas variables permanecen sin inicializar.
De pasada, creo que es bueno declarar una variable cerca de su uso .
Lo siguiente es malo:
int a; // line 30
...
a = 0; // line 40
Lo siguiente es bueno:
int a = 0; // line 40
Además, si la variable se va a sobrescribir justo después de la inicialización, como
int a = 0;
a = foo();
es mejor escribirlo como
int a = foo();
Las variables estáticas y globales se inicializarán a cero para usted, por lo que puede omitir la inicialización. Las variables automáticas (por ejemplo, las variables no estáticas definidas en el cuerpo de la función) pueden contener basura y probablemente siempre deberían inicializarse.
Si hay un valor específico distinto de cero que necesita en la inicialización, siempre debe inicializar explícitamente.
Mientras no haya leído de una variable antes de escribirla, no he tenido que molestarme en inicializarla.
Leer antes de escribir puede causar errores graves y difíciles de atrapar. Creo que esta clase de errores es lo suficientemente notoria para ganar una mención en los populares videos de conferencias de SICP.
No hay absolutamente ninguna razón por la que las variables no deban inicializarse, el compilador es lo suficientemente inteligente como para ignorar la primera asignación si una variable se asigna dos veces. Es fácil que el código crezca en tamaño donde las cosas que dabas por sentado (como asignar una variable antes de ser utilizada) ya no son ciertas. Considerar:
int MyVariable;
void Simplistic(int aArg){
MyVariable=aArg;
}
//Months later:
int MyVariable;
void Simplistic(int aArg){
MyVariable+=aArg; // Unsafe, since MyVariable was never initialized.
}
Uno está bien, el otro te mete en un montón de problemas. Ocasionalmente, tendrá problemas en los que su aplicación se ejecutará en modo de depuración, pero el modo de lanzamiento generará una excepción, una de las razones es que está utilizando una variable sin inicializar.
Puedo pensar en un par de razones fuera de mi cabeza:
Cuando lo va a inicializar más tarde en su código.
int x; if(condition) { func(); x = 2; } else { x = 3; } anotherFunc(x); // x will have been set a value no matter what
Cuando necesite algo de memoria para almacenar un valor establecido por una función u otro fragmento de código:
int x; // Would be pointless to give x a value here scanf("%d", &x);
Si la variable está dentro del alcance de una función y no es un miembro de una clase, siempre la inicializo porque de lo contrario obtendrá advertencias. Incluso si esta variable se usará más adelante, prefiero asignarla a la declaración.
En cuanto a las variables miembro, debe inicializarlas en el constructor de su clase.
Para los punteros, siempre inicialícelos con algún valor predeterminado, particularmente NULL, incluso si se usarán más adelante, son peligrosos cuando no están inicializados.
También se recomienda construir su código con el nivel más alto de advertencias que admita su compilador, esto ayuda a identificar malas prácticas y posibles errores.
Siempre es una buena práctica inicializar sus variables, pero a veces no es estrictamente necesario. Considera lo siguiente:
int a;
for (a = 0; a < 10; a++) { } // a is initialized later
o
void myfunc(int& num) {
num = 10;
}
int a;
myfunc(&a); // myfunc sets, but does not read, the value in a
o
char a;
cin >> a; // perhaps the most common example in code of where
// initialization isn''t strictly necessary
Estos son solo algunos ejemplos en los que no es estrictamente necesario inicializar una variable, ya que se establece más tarde (pero no se accede entre la declaración y la inicialización).
En general, sin embargo, no se pierde nada con inicializar siempre sus variables en la declaración (y de hecho, esta es probablemente la mejor práctica).
Una regla que aún no se ha mencionado es esta: cuando la variable se declara dentro de una función, no se inicializa, y cuando se declara en alcance estático o global, se establece en 0:
int a; // is set to 0
void foo() {
int b; // set to whatever happens to be in memory there
}
Sin embargo, para facilitar la lectura, normalmente lo inicializo todo en el momento de la declaración.
Si está interesado en aprender este tipo de cosas en detalle, recomendaría esta presentación y este libro.