Em C, parece haver diferenças entre os vários valores de zero - NULL
, NUL
e 0
.
Eu sei que o caractere ASCII é '0'
avaliado como 48
ou 0x30
.
O NULL
ponteiro é geralmente definido como:
#define NULL 0
Ou
#define NULL (void *)0
Além disso, há o NUL
personagem '\0'
que parece avaliar 0
também.
Há momentos em que esses três valores não podem ser iguais?
Isso também é verdade em sistemas de 64 bits?
NUL
não existe na linguagem ou biblioteca padrão C (ou em C ++, tanto quanto eu sei). O caractere nulo às vezes é chamado de NUL, mas em C ou C ++ geralmente é chamado apenas de'\0'
.Respostas:
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 valor0
, é 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. Isso0
é referido como uma constante de ponteiro nulo. O padrão C define que a0
conversão para o tipovoid *
é um ponteiro nulo e uma constante de ponteiro nulo.Além disso, para ajudar na legibilidade, a macro
NULL
é fornecida no arquivo de cabeçalhostddef.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:
NULL
é definido para comparar igual a um ponteiro nulo. É definido como implementação qual é a definição realNULL
, desde que seja uma constante válida de ponteiro nulo.0
é outra representação da constante de ponteiro nulo.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:
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:
A seguir, são apresentadas formas INVÁLIDAS de procurar um ponteiro nulo:
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:verifica se o ponteiro da string está apontando para um caractere nulo
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 uma0
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.
fonte
ptr
com todos os bits zero . Não é ummemcmp
, mas é uma comparação usando um operador interno. Um lado é uma constante de ponteiro nulo'\0'
e o outro lado é um ponteiro. Além das outras duas versões comNULL
e0
. Esses três fazem as mesmas coisas.0xDEADBEEF
ainda é um ponteiro nulo, não importa o que sua aparência bitstring gosta, e ele ainda irá comparar igual aNULL
,0
,\0
e todas as outras formas constantes ponteiro nulo.ptr == '\0'
.Parece que várias pessoas não entendem quais são as diferenças entre NULL, '\ 0' e 0. Então, para explicar, e na tentativa de evitar repetir as coisas ditas anteriormente:
Uma expressão constante do tipo
int
com o valor 0 ou uma expressão desse tipo, convertida em tipo,void *
é uma constante de ponteiro nulo que, se convertida em um ponteiro, se torna um ponteiro nulo . É garantido pelo padrão comparar desigual com qualquer ponteiro com qualquer objeto ou função .NULL
é uma macro, definida como uma constante de ponteiro nulo .\0
é uma construção usada para representar o caractere nulo , usado para finalizar uma sequência.Um caractere nulo é um byte que possui todos os seus bits definidos como 0.
fonte
Todos os três definem o significado de zero em diferentes contextos.
Estes três são sempre diferentes quando você olha para a memória:
Espero que isso esclareça.
fonte
sizeof('\0')
e surpreenda-se.Se NULL e 0 são equivalentes como constantes de ponteiro nulo, qual devo usar? na lista de perguntas frequentes C também resolve esse problema:
fonte
"caractere nulo (NUL)" é mais fácil de excluir.
'\0'
é um caractere literal. Em C, é implementado comoint
, portanto, é o mesmo que 0, que é deINT_TYPE_SIZE
. No C ++, o literal de caractere é implementado comochar
1 byte. Normalmente é diferente deNULL
ou0
.A seguir,
NULL
é um valor de ponteiro que especifica que uma variável não aponta para nenhum espaço de endereço. Deixando de lado o fato de que geralmente é implementado como zeros, ele deve poder expressar o espaço de endereço completo da arquitetura. Assim, em uma arquitetura de 32 bits, NULL (provável) tem 4 bytes e na arquitetura de 64 bits, 8 bytes. Isso depende da implementação de C.Finalmente, o literal
0
é do tipoint
, que é do tamanhoINT_TYPE_SIZE
. O valor padrão deINT_TYPE_SIZE
pode ser diferente dependendo da arquitetura.A Apple escreveu:
Wikipedia de 64 bits :
Editar : Adicionado mais no literal do caractere.
O código acima retorna 4 no gcc e 1 no g ++.
fonte
'\0'
é um valor de 1 byte. É um literal de caractere, que é uma expressão constante inteira - portanto, se pode-se dizer que ele tem um tamanho, é o tamanho de um (que deve ter pelo menos 2 bytes). Se você não acredita em mim, avalie e veja por si mesmo. , e são todos completamente equivalentes.int
sizeof('\0')
'\0'
0
0x0
sizeof('\0')
um compilador C ++.Um one-L NUL, termina uma string.
Um N-L de dois pontos não indica nada.
E eu vou apostar um touro de ouro
Que não há três L NULLL.
Como você lida com o NUL?
fonte
Uma boa peça que me ajuda ao começar com C (extraído da Expert C Programming by Linden)
O Um 'l' nul e o Dois 'l' nulo
Memorize esta pequena rima para recuperar a terminologia correta para ponteiros e zero ASCII:
O caractere ASCII com o padrão de bit zero é denominado "NUL". O valor do ponteiro especial que significa que o ponteiro não aponta para lugar nenhum é "NULL". Os dois termos não têm significado intercambiável.
fonte
NUL
é um código de controle, tais comoBEL
,VT
,HT
,SOT
etc. e, portanto, tem max. 3 caracteres."NUL" não é 0, mas refere-se ao caractere ASCII NUL. Pelo menos, é assim que eu vi isso ser usado. O ponteiro nulo geralmente é definido como 0, mas isso depende do ambiente em que você está executando e da especificação de qualquer sistema operacional ou idioma que esteja usando.
No ANSI C, o ponteiro nulo é especificado como o valor inteiro 0. Portanto, qualquer mundo em que isso não seja verdade não é compatível com ANSI C.
fonte
Um byte com um valor de
0x00
é, na tabela ASCII, o caractere especial chamadoNUL
orNULL
. Em C, como você não deve incorporar caracteres de controle no seu código-fonte, isso é representado nas seqüências de caracteres C com um 0 escapado, ou seja\0
,.Mas um NULL verdadeiro não é um valor. É a ausência de um valor. Para um ponteiro, significa que o ponteiro não tem nada para apontar. Em um banco de dados, significa que não há valor em um campo (o que não é o mesmo que dizer que o campo está em branco, 0 ou preenchido com espaços).
O valor real que um determinado formato de arquivo de sistema ou banco de dados usa para representar a
NULL
não é necessariamente0x00
.fonte
NULL
não é garantido que seja 0 - seu valor exato depende da arquitetura. A maioria das principais arquiteturas o define(void*)0
.'\0'
sempre será igual a 0, porque é assim que o byte 0 é codificado em um caractere literal.Não me lembro se é necessário que os compiladores C usem ASCII - se não,
'0'
pode nem sempre ser igual a 48. Independentemente, é improvável que você encontre um sistema que use um conjunto de caracteres alternativo como EBCDIC, a menos que esteja trabalhando muito. sistemas obscuros.Os tamanhos dos vários tipos serão diferentes nos sistemas de 64 bits, mas os valores inteiros serão os mesmos.
Alguns comentaristas expressaram dúvidas de que NULL seja igual a 0, mas não seja zero. Aqui está um exemplo de programa, junto com a saída esperada em um sistema assim:
Esse programa pode imprimir:
fonte
(void *) 0 é NULL e '\ 0' representa o final de uma string.
fonte