2010-09-12 15 views
5

programación NULL en C ¿alguien puede decirme cómo se maneja NULL en C? Y la salida de este programa es 3, ¿cómo con el concepto NULL?Dificultad en concepto NULL en C?

#include <stdio.h> 

int main(void) { 
    int i; 
    static int count; 
    for(i = NULL; i <= 5;) { 
     count++; 
     i += 2; 
    } 

    printf("%d\n",count); 
    return 0; 
} 

Respuesta

3

NULL es simplemente una macro definida en stdio.h o un archivo que stdio incluye. Se puede definir de diversas maneras como una variación de cero.

Si ejecuta su código a través de la pre-procesador de C (por lo general cc -E) se puede ver lo que se traduce en en su implemnentation:

void main(){ 
    int i; 
    static int count; 
    for(i=((void *)0); i<=5 ;){ 
     count++; 
     i+=2; 
    } 
    printf("%d",count); 
} 

que es no sólo un uso innecesario de NULL pero es tremendamente ONU código C -idiomatic, más común sería:

int main(){ 
    int i; 
    int count = 0; 
    for(i = 0; i <= 5; i += 2){ 
     count++; 
    } 
    printf("%d\n",count); 
    return 0; 
} 
+0

bt de salida es 3 .. ¿cómo? –

+3

@me_eclair: es '3' porque estás contando a' 5' por '2' en la última parte del ciclo' for'. Está agregando '2' a cada iteración, por lo que' i' es así: '0' ->' 2' -> '4' ->' 6'. El bucle no se ingresa cuando 'i == 6', por lo que el cuerpo del bucle solo se ejecuta 3 veces. –

+0

NULL se define en . No necesita incluir . En particular, puede usar NULL en un entorno independiente sin incluir (que no debe estar disponible). – alecov

1

NULL SI debe ser sinónimo de 0. Se usa más correctamente para indicar un puntero nulo.

En este caso, el código será en realidad:

for (i = 0; i <= 5) 
{ 
    count++; 
    i += 2; 
} 
+1

corrección, depende de la biblioteca estándar, no del compilador. Las especificaciones de lenguaje para C y C++ son muy claras acerca de lo que 'NULL' puede ser. –

+0

@Evan - gracias, hace tiempo que hice C enojado. Respuesta actualizada – ChrisF

21

Para C, "NULO" se define tradicionalmente como (void *) 0 - en otras palabras, es un alias de puntero a la dirección 0. Por C++, "NULL" se define típicamente como "0". El problema con NULL en C++ y C es que no es seguro para tipos: puedes construir construcciones extrañas como la que incluiste en tu muestra de código.

Para C++, los diseñadores de idiomas arreglaron esto en C++ 0x agregando un nuevo tipo "nullptr" que se puede convertir implícitamente a cualquier tipo de puntero pero que no se puede convertir a un tipo entero.

+2

NULL no es un alias de la dirección 0 (que podría ser una dirección válida). Es un entero * constante * cero en un contexto de puntero. – mpez0

+0

No existe el concepto de "puntero cero" porque la adición del puntero no tiene un elemento de identidad. 'NULL' es una macro que se expande a un puntero canónico no válido, que no está fuertemente tipado. – Potatoswatter

2

NULL tiene la mayor parte de su significado cuando se trata de punteros. Cuando se trata de enteros, sería mejor usar simplemente cero.

Estrictamente hablando, NULL es simplemente el valor cero con un nombre elegante, pero la parte más importante es su nombre elegante. Existe porque es menos ambiguo escribir int* p = NULL; que int* p = 0;. Como sabemos que NULL es un puntero, estamos seguros de que realmente quería decir p como un puntero.

Por lo tanto, cuando se trabaja con punteros y quiere representar la dirección de0, utilice NULL. Y cuando trabaje con números y desee representar el número 0, use 0. (En el ejemplo, se debe utilizar en lugar de 0NULL.)

0

NULL se define como 0 por C. En su programa, que cuenta de 0 a 5 (contando cada segundo número). Es por eso que contar es 3 (i = 0, 2, 4).

NULL no se debe utilizar de esta manera. NULL se debe usar con punteros.

0

el tipo de NULL y el tipo de i son diferentes, pero C perdona ti :)

C es (sobre todo) un lenguaje "no seguro". Quiero decir: te permite mezclar tipos de los que se quejarían otros idiomas.

Con C puede agregar a charsdoubles, se puede multiplicar chars y ints, ...

Lo que está haciendo es la asignación de un null pointer constant (de tipo void *) a una int. C permite eso, pero debe tener mucho cuidado al mezclar los tipos de esta manera.

El resultado de asignar la constante del puntero nulo a un int es lo mismo que asignarle 0. Entonces comienza su ciclo con i siendo 0.

Una variable automática estática, en ausencia de un inicializador, se inicializa en 0. Esto le sucede a la variable count en su programa.

Así, el bucle sale primero (count se convierte en 1) con i ser 0, a continuación, se convierte en i 2.
Ahora el bucle va (count se convierte en 2) con i ser 2, a continuación, se convierte en i 4.
Ahora el el lazo va (count se convierte en 3) con i siendo 4, luego i se convierte en 6.
Y el ciclo finaliza ... e imprime el valor de count.


Notas

  • ser estándar compatible main debe declararse int main(void)
  • que debe ser la salida de una nueva línea después de cada línea completa (printf("%d\n", count);)
  • y usted debe return 0; para indicar éxito finalización de su programa para el sistema operativo
+0

Gracias U ... problema pmg resuelto. –

0

No confunda la idea de un puntero NULL en c con la de un tipo o cantidades que aceptan nulos en algunos lenguajes dinámicos. Hay similares, pero tienen usos y significados distintos.

En C el concepto de NULL sólo se utiliza de forma nativa en el contexto de puntero donde es un puntero a una ubicación conocida memoria no válida (a menudo, pero no siempre, representado por cero).

Esto no es (bastante) lo mismo que un tipo o variable que puede representar falta de ajuste. Tenga en cuenta que tipos como este pueden ser definidos y administrados por el usuario en c, pero no son proporcionados por el idioma.

3

Hay un capítulo completo dedicado al puntero nulo en el C FAQ que debe responder a todas sus preguntas.

  • 5.1 ¿Qué es este infame puntero nulo, de todos modos?
  • 5.2 ¿Cómo obtengo un puntero nulo en mis programas?
  • 5.3 ¿Es válida la comparación del puntero abreviado if(p) para probar los punteros no nulos?¿Qué pasa si la representación interna para punteros nulos es distinta de cero?
  • 5.4 ¿Qué es NULL y cómo se define?
  • 5.5 ¿Cómo se debe definir NULL en una máquina que utiliza un patrón de bits distinto de cero como la representación interna de un puntero nulo?
  • 5.6 Si NULL se definieron de la siguiente manera: #define NULL ((char *)0). ¿No sería eso lo que haría funcionar las llamadas que pasan un trabajo NULL uncast?
  • 5.7 Mi proveedor proporciona archivos de encabezado #define NULL como 0L. ¿Por qué?
  • 5.8 ¿Es NULL válido para los punteros a las funciones?
  • 5.9 Si NULL y 0 son equivalentes a las constantes de puntero nulo, ¿qué debería usar?
  • 5.10 ¿Pero no sería mejor usar NULL (en lugar de 0), en caso de que cambie el valor de NULL, quizás en una máquina con punteros nulos internos distintos de cero?
  • 5.11 Una vez usé un compilador que no funcionaría a menos que se usara NULL.
  • 5.12 Utilizo el macro del preprocesador #define Nullptr(type) (type *)0 para ayudarme a construir punteros nulos del tipo correcto.
  • 5.13 Esto es extraño. NULL se garantiza que es 0, pero el puntero nulo no?
  • 5.14 ¿Por qué hay tanta confusión en torno a los punteros nulos? ¿Por qué surgen estas preguntas tan a menudo?
  • 5.15 Estoy confundido. Simplemente no puedo entender todo este asunto del puntero nulo.
  • 5.16 Dada toda la confusión que rodea a los punteros nulos, ¿no sería más fácil simplemente exigir que estén representados internamente por ceros?
  • 5.17 En serio, ¿alguna máquina real realmente utiliza punteros nulos distintos de cero, o representaciones diferentes para punteros a diferentes tipos?
  • 5.18 ¿Se garantiza que un valor integral en tiempo de ejecución de 0, puntero, sea un puntero nulo?
  • 5.19 ¿Cómo puedo acceder a un vector de interrupción ubicado en la ubicación de la máquina 0? Si configuro un puntero a 0, el compilador podría traducirlo a algún valor de puntero nulo interno distinto de cero.
  • 5.20 ¿Qué significa un error de "asignación de puntero nulo" en tiempo de ejecución? ¿Cómo puedo rastrearlo?