Nota: Esta respuesta se aplica al lenguaje C, no a C ++.
Punteros nulos
El entero constante literal 0
tiene diferentes significados según el contexto en el que se utiliza. En todos los casos, sigue siendo una constante entera con el valor 0
, solo se describe de diferentes maneras.
Si se compara un puntero con el literal constante 0
, entonces esta es una verificación para ver si el puntero es un puntero nulo. Esto 0
se conoce como una constante de puntero nulo. El estándar C define que la 0
conversión al tipo void *
es tanto un puntero nulo como una constante de puntero nulo.
Además, para ayudar a la legibilidad, la macro NULL
se proporciona en el archivo de encabezado stddef.h
. Dependiendo de su compilador, podría ser posible #undef NULL
y redefinirlo en algo loco.
Por lo tanto, aquí hay algunas formas válidas de verificar un puntero nulo:
if (pointer == NULL)
NULL
se define para comparar igual a un puntero nulo. Es la implementación definida cuál es la definición real de NULL
, siempre que sea una constante de puntero nulo válida.
if (pointer == 0)
0
es otra representación de la constante de puntero nulo.
if (!pointer)
Esta if
afirmación verifica implícitamente "no es 0", por lo que revertimos que significa "es 0".
Las siguientes son formas NO VÁLIDAS de verificar un puntero nulo:
int mynull = 0;
<some code>
if (pointer == mynull)
Para el compilador, esto no es una comprobación de un puntero nulo, sino una comprobación de igualdad en dos variables. Esto podría funcionar si mynull nunca cambia en el código y las optimizaciones del compilador constantemente doblan el 0 en la instrucción if, pero esto no está garantizado y el compilador tiene que producir al menos un mensaje de diagnóstico (advertencia o error) de acuerdo con el Estándar C.
Tenga en cuenta que lo que es un puntero nulo en el lenguaje C. No importa en la arquitectura subyacente. Si la arquitectura subyacente tiene un valor de puntero nulo definido como dirección 0xDEADBEEF, entonces depende del compilador resolver este desorden.
Como tal, incluso en esta arquitectura divertida, las siguientes formas siguen siendo formas válidas de verificar un puntero nulo:
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
Las siguientes son formas NO VÁLIDAS de verificar un puntero nulo:
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
ya que estos son vistos por un compilador como comparaciones normales.
Personajes nulos
'\0'
se define como un carácter nulo, es decir, un carácter con todos los bits puestos a cero. Esto no tiene nada que ver con los punteros. Sin embargo, puede ver algo similar a este código:
if (!*string_pointer)
comprueba si el puntero de cadena apunta a un carácter nulo
if (*string_pointer)
comprueba si el puntero de cadena apunta a un carácter no nulo
No los confundas con punteros nulos. Solo porque la representación de bits es la misma, y esto permite algunos casos cruzados convenientes, en realidad no son lo mismo.
Además, '\0'
es (como todos los literales de caracteres) una constante entera, en este caso con el valor cero. Por '\0'
lo tanto, es completamente equivalente a una 0
constante entera sin adornos : la única diferencia está en la intención que transmite a un lector humano ("Estoy usando esto como un carácter nulo").
Referencias
Consulte la pregunta 5.3 de las preguntas frecuentes de comp.lang.c para obtener más información. Vea este pdf para el estándar C. Consulte las secciones 6.3.2.3 Punteros, párrafo 3.