Nota: Esta resposta se aplica à linguagem C, não a C ++.
Ponteiros nulos
A constante inteira literal 0
tem significados diferentes, dependendo do contexto em que é usada. Em todos os casos, ainda é uma constante inteira com o valor 0
, é apenas descrito de maneiras diferentes.
Se um ponteiro estiver sendo comparado ao literal constante 0
, essa é uma verificação para ver se o ponteiro é um ponteiro nulo. Isso 0
é referido como uma constante de ponteiro nulo. O padrão C define que a 0
conversão para o tipo void *
é um ponteiro nulo e uma constante de ponteiro nulo.
Além disso, para ajudar na legibilidade, a macro NULL
é fornecida no arquivo de cabeçalho stddef.h
. Dependendo do seu compilador, pode ser possível #undef NULL
redefini-lo para algo maluco.
Portanto, aqui estão algumas maneiras válidas de verificar um ponteiro nulo:
if (pointer == NULL)
NULL
é definido para comparar igual a um ponteiro nulo. É definido como implementação qual é a definição real NULL
, desde que seja uma constante válida de ponteiro nulo.
if (pointer == 0)
0
é outra representação da constante de ponteiro nulo.
if (!pointer)
Essa if
declaração verifica implicitamente "não é 0", portanto, revertemos que significa "é 0".
A seguir, são apresentadas formas INVÁLIDAS de procurar um ponteiro nulo:
int mynull = 0;
<some code>
if (pointer == mynull)
Para o compilador, essa não é uma verificação para um ponteiro nulo, mas uma verificação de igualdade em duas variáveis. Isso pode funcionar se mynull nunca mudar no código e as otimizações do compilador dobrarem constantemente o 0 na instrução if, mas isso não é garantido e o compilador precisa produzir pelo menos uma mensagem de diagnóstico (aviso ou erro) de acordo com o Padrão C.
Observe que o que é um ponteiro nulo na linguagem C. Não importa na arquitetura subjacente. Se a arquitetura subjacente tiver um valor de ponteiro nulo definido como o endereço 0xDEADBEEF, será responsabilidade do compilador resolver essa bagunça.
Assim, mesmo nessa arquitetura engraçada, as seguintes maneiras ainda são válidas para verificar se há um ponteiro nulo:
if (!pointer)
if (pointer == NULL)
if (pointer == 0)
A seguir, são apresentadas formas INVÁLIDAS de procurar um ponteiro nulo:
#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)
como estes são vistos por um compilador como comparações normais.
Caracteres nulos
'\0'
é definido como um caractere nulo - ou seja, com todos os bits definidos como zero. Isso não tem nada a ver com ponteiros. No entanto, você pode ver algo semelhante a este código:
if (!*string_pointer)
verifica se o ponteiro da string está apontando para um caractere nulo
if (*string_pointer)
verifica se o ponteiro da string está apontando para um caractere não nulo
Não confunda isso com ponteiros nulos. Só porque a representação de bits é a mesma, e isso permite alguns casos convenientes de cruzamento, eles não são realmente a mesma coisa.
Além disso, '\0'
é (como todos os literais de caracteres) uma constante inteira, nesse caso com o valor zero. Portanto, '\0'
é completamente equivalente a uma 0
constante inteira sem adornos - a única diferença está na intenção que ela transmite a um leitor humano ("estou usando isso como um caractere nulo").
Referências
Consulte a pergunta 5.3 das perguntas frequentes do comp.lang.c para obter mais informações. Veja este pdf para o padrão C. Confira as seções 6.3.2.3 Ponteiros, parágrafo 3.