Quais são as diferenças entre nulo, '\ 0' e 0 no idioma c?

C é um pouco estranho, pois só possui três tipos padrão diferentes, a saber

int

,

flutuador

e ponteiros. Ah, claro, existem algumas variações nisso, como

Caracteres

(que é realmente um número inteiro de 8 bits), mas, em essência, isso é verdadeiro. Os valores booleanos são números inteiros (0 se false, true), os caracteres são números inteiros e as strings são uma matriz de números inteiros terminada com o valor zero.

Com isso em mente, literais de caracteres como

'uma'

e

'z'

são realmente apenas maneiras sofisticadas de dizer o número 97 e 122, respectivamente. É por isso que algo como

printf ('% c \ n', 'a' + 6);

irá imprimir

g

. Da mesma maneira,

'\ 0'

é simplesmente uma maneira elegante de dizer

0 0

. Se você não acredita em mim, tente

printf ('% d \ n', '\ 0');

Portanto, não há diferença entre

'\ 0'

e

0 0

.

Quanto a

nulo

, como outros já apontaram, ele deve ser usado apenas para ponteiros. Agora,

nulo

é uma constante definida definida com o

#definir

comando. Poderia assim ser definido como

0 0

, Como

1 1

ou como

123141231

. Geralmente, porém, é definido como

0 0

ou como um ponteiro vazio apontando para

0 0

(

(nulo *) 0

)

Então, para responder às suas (duas) perguntas:

  • Sim, '\ 0' é exatamente igual a 0.
  • Não, nulo não é necessariamente igual a 0, mas pode ser, dependendo do seu ambiente de construção.

null é um ponteiro que aponta para nada. Isso pode ser implementado como o valor 00000000H (em um espaço de endereço de 32 bits), mas não precisa ser. Você pode ter uma convenção de que FFFFFFFFH é o ponteiro nulo.

0 é o número inteiro com o valor 0, geralmente 32 bits, mas pode ser 64 ou 16 ou até 8.

'\ 0' é o caractere com o valor 0, ou seja, o terminador de string. É (em todas ou pelo menos quase todas as implementações) o mesmo padrão de bits que um 0 numérico de 8 bits, mas se comporta de maneira diferente em termos de compatibilidade de tipos.

Então você tem 0,0 (que é o número do ponto flutuante com valor zero) e false (que é o bool com valor FALSE que é igual a um zero numérico, geralmente com 32 bits).

Eles têm tipos diferentes.

null uma constante que eu acho que tem o tipo (void *). Ele pode ser usado ou atribuído em qualquer lugar em que um ponteiro possa ser usado, mas você não deve desreferenciá-lo, porque ele não aponta para um objeto válido. null geralmente é representado por um padrão de bit zero de 32 ou 64 bits, mas o padrão diz que deve ser zero.

'\ 0' tem o tipo char. Em muitos sistemas, pode ser um padrão de 8 bits de todos os 0s. É usado como o caractere final nas seqüências C.

0 por si só é uma constante numérica, que pode ser atribuída a qualquer tipo numérico, como int, não assinado, longo int, curto, flutuante, duplo, etc.

Quais são as diferenças entre nulo, '\ 0' e 0 no idioma C?

Eu vou assumir que você quis dizer NULL, não null. Não há nada na linguagem ou biblioteca padrão C com o nome "null".

NULO

é uma macro que se expande para uma constante de ponteiro nulo definida pela implementação. Há várias definições válidas para isso, mas as mais comuns são:

#define NULL 0

e

#define NULL ((vazio *) 0)

Você não precisa saber ou se importar com como é definido, apenas que é uma constante de ponteiro nulo e deve ser usado apenas como um valor de ponteiro. Em alguns contextos (por exemplo, como argumento para

printf

), será necessário convertê-lo em algum tipo de ponteiro específico, mas na maioria dos contextos ele será implicitamente convertido no tipo certo.

'\ 0'

é um

constante de caractere

com o valor 0. Ele normalmente deve ser usado como um valor de caractere - mas, por razões históricas, é realmente do tipo

int

. (É do tipo

Caracteres

em C ++, mas você perguntou sobre C.)

0 0

é uma constante inteira. (As regras de sintaxe são tais que, na verdade, são octais, mas isso não importa.) É do tipo

int

. O que significa que

'\ 0'

e

0 0

ambos têm o mesmo valor e tipo e, em princípio, podem ser usados ​​de forma intercambiável - mas como uma questão de estilo e sanidade, você deve usar

'\ 0'

somente em um contexto em que será convertido em um tipo de caractere.

Por exemplo:

  1. int * null_int_pointer = NULL; void * null_void_pointer = NULL; char null_character = '\ 0'; int zero = 0;

Se você escrever:

int what_the_heck = NULL; / * Não faça isso! * /

o compilador

posso ou não posso

reclamar. Se a implementação definir

NULO

Como

0 0

, até onde o compilador pode dizer o que foi dito acima é perfeitamente válido. Em outra implementação que define

NULO

Como

((nulo *) 0)

, o compilador relatará um erro. Este é um dos muitos casos em C em que é sua responsabilidade fazer as coisas direito; o compilador não diz necessariamente se você cometer um erro.

NULO

:

Um ponteiro vazio

NULO

devemos

ser usado somente em

ponteiro

contextos.

Vamos ver como NULL é definido pelo padrão C:

NULL pode ser definido de duas maneiras:

  1. #define NULL 0

ou

  1. #define NULL ((vazio *) 0)

A diferença entre os dois é a primeira definição de NULL é do tipo

inteiro

; enquanto que o segundo é do tipo

ponteiro

anular (um ponteiro nulo).

Ambas são definições válidas de C porque é permitido atribuir um valor de 0 a um tipo de ponteiro em C para indicar um ponteiro que não aponta para nada (um ponteiro nulo). A segunda definição permitida (melhor) informa ao compilador que o valor 0 é um contexto de ponteiro (devido ao lançamento de void *).

Dê uma olhada neste código:

  1. int main () {int num = NULL; int * numPtr = NULL;}

Se NULL for definido como no primeiro caso (um 0 sem adornos), o compilador ficaria feliz em permitir a inicialização de

num

porque NULL foi definido como número inteiro 0. No entanto, se NULL foi definido com o void * cast, o compilador provavelmente reclamaria porque você está tentando inicializar um número inteiro com um tipo de ponteiro.

numPtr

sempre seria permitido porque C permite que um tipo de dados de ponteiro seja inicializado com número inteiro 0 ou (vazio *) 0.

Então, como o C ++ lida com as coisas ...?

Em C ++, o uso de NULL é diferente porque

C ++ faz

não

permite a conversão implícita de um void * para outro tipo de ponteiro

(enquanto C sim).

Como NULL pode ser definido como um 0 não adornado (inteiro), considere os dois protótipos de função sobrecarregados a seguir para

f

:

  1. int f (int x); int f (int * p);

Se você invocar

f (NULL)

, você entrará no

f (int)

função em vez do

f (int *)

funcionar como você pretendia.

Então, como o C ++ contorna esse problema? A resposta é

certifique-se de sempre usar contextos de ponteiro ao lidar com tipos de ponteiro; ou seja, não use inteiro em contextos de ponteiro…

Digite a definição C ++ de

nullptr

. nullptr é definido como um tipo de ponteiro com valor 0, semelhante à definição nula * de NULL. Como o nullptr é sempre um contexto de ponteiro, que nunca é confundido com o número inteiro 0, o problema de função sobrecarregada mostrado acima desaparecerá ao usar o nullptr, em vez de NULL:

  1. f (nullptr); // bom: sempre chama f (int *)

ao invés de:

  1. f (NULL); // ruim: pode chamar f (int)

'\ 0'

: O caractere nul

Isto é um

Caracteres

tipo de dados (não inteiro nem ponteiro) e é usado principalmente para finalizar seqüências de caracteres no estilo C. Não deve ser usado em contextos inteiros ou de ponteiro!

  1. char * str = "Olá, mundo!"; Anexa o caractere nul '\ 0' no final da sequência

Eu espero que isso ajude :)