2009-08-04 23 views
26

¿Cómo puedo determinar si un número entero no está asignado?C - Compruebe si se ha asignado un número entero

int i; /* no assignment */ 

if (/* conditional statement here to check if int i is unassigned or not */) { 
    printf("Integer is unassigned!\n"); 
} else { 
    printf("Integer is assigned!\n"); 
} 
+2

Este hilo tiene alguna discusión sobre esto: http://stackoverflow.com/questions/473236/check-for-value-definedness-in-c – Laserallan

Respuesta

20

No puede. Tendrá contenido "indefinido", lo que significa que contendrá lo que ocurra en esa ubicación de la memoria en ese momento.

. . . a menos que se declare en el alcance global, entonces se inicializará a cero.

+0

@Kenny: "a menos que sea declarado" es en realidad lo que quería decir, como "yo" es la variable de la que estamos hablando, gracias. –

+0

En realidad, creo que se podría argumentar que incluso una variable estática no está asignada (por supuesto, no se inicializa) si no se inicializa explícitamente. –

+0

@Neil: Ahora estás deambulando en un mundo de semántica. TODO EL MUNDO (incluyéndome a mí) sabe lo que significa asignar un valor. TODO EL MUNDO también sabe lo que significa inicializar una variable. Ahora, pregúntele a TODOS "¿Cuál es la diferencia entre la asignación y la inicialización?" y los veo forcejear (mi propia cabeza también empieza a doler). –

8

C no es intrínsecamente compatible con esto, al igual que no admite intrínsecamente la comprobación de límites en las matrices. Es una compensación entre velocidad/eficiencia y seguridad.

En general ... inicialice sus variables.

4

Si i es global o estático, su valor será 0, de lo contrario, su valor puede ser cualquier cosa y no hay forma de saber si es basura o no.

1

Por lo general, las variables se establecen en 0 por la biblioteca C, pero no necesariamente.

Pero, básicamente, no se puede. asignarles un valor por defecto en la definición, por ejemplo:

int i = 0; /* Or what ever value you know won't be used elsewhere */ 

Entonces si ejecuta algún código y quiere comprobar si el valor se estableció allí, se puede comparar a su valor inicial.

+0

Vea este mensaje por ejemplo: http://gcc.gnu.org/ml/gcc-help/2007-07/msg00097.html – Makis

+0

Y al decirlo, no quise decir que nadie debería confiar en que esto suceda. Si necesita una variable para ser 0, ¡inicialícela específicamente a ese valor! – Makis

7

Es muy simple. Usted sabe que no está asignado porque no lo inicializó.

+8

Obviamente, porque nunca tendría una variable configurada durante el tiempo de ejecución. –

0

En C, un entero toma un valor indefinido cuando se crea. Esto significa que si su primer uso de ese entero proviene de un registro/ubicación de memoria/dispositivo con un 5893872, ese es el valor de ese entero. (Kilometraje varía para la compilación de depuración/liberación.)

El método habitual de hacer frente a esto es utilizar un defecto sin sentido:

int number_of_widgets = -1; 

... o una bandera para indicar su estado:

int number_of_widgets; 
int number_of_widgets_assigned = 0; 

if (number_of_widgets_assigned) 
    do something 
else 
    do something else 
number_of_widgets_assigned = 1; 

No hay otra manera de detectar si se ha asignado algo, a menos que desee acceder a las funciones de depuración de su hardware y sospecho que de eso no se trata esta conversación.

1

Como todas las respuestas anteriores, no hay forma de detectar eso en tiempo de ejecución. Sin embargo, casi cualquier static code analysis tool con advertencia para las variables no asignadas.

4

Puede solicitar advertencias al compilador si utiliza valores no inicializados. Sin embargo, no son del todo fiables; se obtienen ocasionalmente falsos positivos en los que el DFA no es tan inteligente como cabría esperar y, tal vez, falsos negativos ocasionales (espero que no, pero no prometo nada).

Para GCC:

-Wuninitialized -O1 

Si desea escribir código condicional:

int a = 3; 
int b; 
int *p = (rand() > RAND_MAX/2) ? &a : &b; 
if (is_uninitialized(*p)) // blah 

entonces estás de suerte.A diferencia de algunos lenguajes dinámicos, C no tiene ningún concepto de "valor indefinido". Si una variable no se inicializa, no se le da algún valor especial que pueda probarse más adelante. No se le da un valor en absoluto, por lo que no está definido lo que sucede cuando usas la variable.

1

El uso de una variable antes de la inicialización (o asignación) es una causa grave de errores. No puede verificarlo confiablemente en tiempo de ejecución, pero puede detectarlo durante o antes de la compilación.

Sugiero no para marcarlo dentro del código. Debido a que es probable que cause advertencias del compilador (la 'i' variable se usa antes de que se le haya asignado un valor), introduzca nuevos errores y tenga muy pocas posibilidades de éxito en programas de medianos a grandes.

El mejor método es utilizar herramientas de análisis de código estático (como QA/C o PCLint). Usar el compilador con un alto nivel de sensibilidad de advertencia es una opción gratuita, con mucha menos cobertura que las herramientas especializadas.

Si realiza revisiones de código, también puede incluir una verificación de variables no inicializadas en la lista de verificación. Esto no es garantía, pero generará verificaciones manuales por parte de los revisores.

Si se trata de la verificación del tiempo de ejecución que desea, entonces puede comenzar al inicializar las variables a un valor fuera de rango. Por ejemplo -1 para un valor por lo demás positivo. A continuación, puede comprobar si hay

#define UNASSIGNED_VALUE -1 
    static int number_of_apples = UNASSIGNED_VALUE; 
    if (UNASSIGNED_VALUE == number_of_apples) 
    { 
     // error handling 
    } 

esto no es un verdadero 'unintialized' variable, pero al menos se puede detectar si se llevaron a cabo las tareas de ejecución en rango legal.

0

Comprobar si una variable que está utilizando se inicializa (asigna) en el tiempo de ejecución es notoriamente difícil para C. No hay soporte de idioma para ella, y la información disponible en tiempo de ejecución simplemente es insuficiente para la detección perfecta de valores no inicializados. Las herramientas de análisis dinámico como Valgrind/Memcheck tienen una gran duración (como hacer un seguimiento de cada byte de memoria en el espacio de direcciones de su proceso y luego examinar cada tienda para marcar un byte como incializado) para determinar si el valor de uso está inicializado y todavía son susceptibles a falsos positivos.

Si solo intenta minimizar tales errores en sus programas, las herramientas de análisis estático como lint pueden hacer un trabajo razonablemente bueno para informarle si está utilizando o no variables no inicializadas. De hecho, creo que la mayoría de los compiladores harán todo lo posible para decirte cuándo estás haciendo esto (aunque ciertamente no son perfectos)

4

Como han notado otros, no puedes escribir un programa en C que detecte si una de sus propias variables no está inicializada, y debe esforzarse para asegurarse de que las variables siempre se inicialicen.

  • Si su objetivo es asegurarse de que todas las variables se inicializan, una herramienta como valgrind puede detectar usos de las variables sin inicializar dinámicamente , a través del análisis de tiempo de ejecución caro.

  • Si su objetivo es asegurarse de que los datos privados se inicia exactamente una vez, el método usual es protegerlo con

    int i; 
    static bool initialized = 0; 
    
    ... 
    if (!initialized) { 
        initialized = 1; 
        i = ... i's initial value ...; 
    } 
    
0

En C# que haría uso:

Nullable<int> i = null; /* null assignment */ 

if (i == null) { 
    printf("Integer is unassigned!\n"); 
} else { 
    printf("Integer is assigned!\n"); 
} 

No estoy seguro si esto se traduciría en C, sin embargo.

+0

¡Está utilizando la sintaxis C# yc !, este código es híbrido porque C# no tiene un método llamado printf, en cambio es Console.Write –

Cuestiones relacionadas