384 votes

Quelle est la différence entre la valeur NULL, ' \0 ' et 0

En C, il semble y avoir des différences entre les valeurs différentes de zéro -- NULL, NUL et 0.

Je sais que le caractère ASCII '0' évalue 48 ou 0x30.

L' NULL pointeur est généralement définie comme:

#define NULL 0l

En outre, il est l' NUL caractère '\0' qui semble à évaluer à l' 0 .

Existe-il des moments où ces trois valeurs ne peuvent pas être égaux?

Est-ce aussi vrai sur les systèmes 64 bits?

431voto

Andrew Keeton Points 6268

Pointeurs Null

La constante entière littérale 0 a des significations différentes selon le contexte dans lequel il est utilisé. Dans tous les cas, il est toujours une constante entière avec la valeur 0, c'est juste décrit de différentes façons.

Si un pointeur est par rapport à la constante littérale 0, alors c'est une vérification pour voir si le pointeur est un pointeur null. Cette 0 est alors désigné comme un pointeur null constante. La norme définit 0 cast vers le type void * est à la fois un pointeur null et un pointeur null constante.

Par ailleurs, pour des raisons de lisibilité, la macro NULL est fourni dans le fichier d'en-tête stddef.h. En fonction de votre compilateur, il pourrait être possible d' #undef NULL et de redéfinir quelque chose de loufoque. Quiconque fait cela mérite d'être fusillés.

Donc, ici, sont quelques-uns des moyens valables pour vérifier un pointeur null:

if (pointer == NULL)

NULL est défini à comparer égale à un pointeur null. Elle est définie par l'implémentation de ce que la définition même de l' NULL est, tant qu'il est valide d'un pointeur null constante.

if (pointer == 0)

0 est une autre représentation de pointeur null constante.

if (!pointer)

Cette if déclaration implicitement contrôles "0", donc on inverse qui signifie "0".

Les éléments suivants ne sont pas valides façons de vérifier pour un pointeur null:

int mynull = 0;
<some code>
if (pointer == mynull)

Pour le compilateur, ce n'est pas un chèque pour un pointeur null, mais un contrôle d'égalité sur les deux variables. Cela peut fonctionner si mynull ne change jamais dans le code et les optimisations du compilateur constante plier le 0 dans l'instruction if, mais ce n'est pas garanti et que le compilateur doit produire au moins un message de diagnostic (avertissement ou erreur) selon la Norme.

Notez que ce qui est un pointeur null dans le langage C. Il n'a pas d'importance sur l'architecture sous-jacente. Si l'architecture sous-jacente a une valeur de pointeur null définie comme adresse 0xDEADBEEF, puis c'est au compilateur de trier ce gâchis.

En tant que tel, même sur cette drôle de l'architecture, de l'une des manières suivantes sont toujours valables façons de vérifier pour un pointeur null:

if (!pointer)
if (pointer == NULL)
if (pointer == 0)

Les éléments suivants ne sont pas valides façons de vérifier pour un pointeur null:

#define MYNULL (void *) 0xDEADBEEF
if (pointer == MYNULL)
if (pointer == 0xDEADBEEF)

comme ceux-ci sont vus par un compilateur comme normal comparaisons.

Les Caractères Null

'\0' correspond à un caractère null - qui est un personnage avec tous les bits à zéro. Cela n'a rien à voir avec les pointeurs. Cependant, vous pouvez voir quelque chose de semblable à ce code:

if (!*string_pointer)

vérifie si le pointeur de la chaîne est de pointer un caractère nul

if (*string_pointer)

vérifie si le pointeur de la chaîne est de pointage à un non-caractère null

N'obtenez pas ces confondu avec des pointeurs null. Tout simplement parce que la représentation binaire est le même, ce qui permet une certaine pratique de la croix-plus de cas, ils ne sont pas vraiment la même chose.

En outre, '\0' , à l'instar de toutes les chaînes de caractères) à une constante entière, dans ce cas, la valeur zéro. Donc, '\0' est complètement équivalent à un sans fioritures 0 constante entière - la seule différence est dans l' intention qu'il transmet à un lecteur humain ("je suis en utilisant cela comme un caractère nul.").

Références

Voir la Question 5.3 de la comp.lang.c FAQ pour plus d'. Voir ce document pdf pour le C standard. Découvrez les articles 6.3.2.3 Pointeurs, paragraphe 3.

43voto

amaterasu Points 380

Il semble qu'un certain nombre de gens ne comprennent pas quelles sont les différences entre la valeur NULL, '\0' et 0 sont. Donc, pour expliquer, et dans une tentative pour éviter de répéter ce qui est dit plus haut:

Une expression constante de type int avec la valeur 0, ou une expression de ce type, distribution de type void * est un pointeur null constante, qui, si converti en pointeur se transforme en pointeur null. Il est garanti par la norme pour comparer l'inégalité à un pointeur vers un objet ou une fonction.

NULL est une macro définie comme un pointeur null constante.

'\0' est une construction utilisée pour représenter le caractère null, utilisé pour mettre fin à une chaîne.

Un caractère nul est un octet, qui a tous ses bits à 0.

18voto

Nasko Points 616

Tous les trois de définir le sens de zéro dans un contexte différent.

  • pointeur de contexte - NULL est utilisé et s'entend de la valeur du pointeur est 0, indépendamment de savoir si il est en 32 bits ou 64 bits (un cas sur 4 octets 8 octets de zéros).
  • contexte de chaîne - le personnage qui représente le chiffre zéro a une valeur hexadécimale de 0x20, alors que le NUL personnage a une valeur hexadécimale de 0x00 (utilisé pour la terminaison de chaînes de caractères).

Ces trois sont toujours différentes, quand vous regardez la mémoire:

NULL - 0x00000000 ou 0 x 00000000`00000000 (32 vs 64 bits)
NUL - 0x00 ou 0x0000 (ascii vs 2byte unicode)
'0' - 0x20

J'espère que cela clarifie.

13voto

Sinan Ünür Points 76179

Si la valeur est NULL et 0 sont équivalentes comme pointeur null constantes, qui dois-je utiliser? dans le C FAQ de la liste des adresses de ce problème ainsi:

C programmeurs doivent comprendre que NULL et 0 sont interchangeables dans pointeur de contextes, et que l'un uncast 0 est parfaitement acceptable. Toute utilisation de la NULL (par opposition à l' 0) devrait être considéré comme un doux rappel qu'un pointeur; les programmeurs ne doit pas dépendre de ça (que ce soit pour leur propre compréhension ou l' du compilateur) pour distinguer pointeur 0'partir integer 0'.

C'est seulement dans le pointeur de contextes qui NULL et 0 sont équivalentes. NULLdoit pas être utilisé lorsqu'un autre type d' 0est nécessaire, même si cela pourrait fonctionner, car cela envoie le mauvais stylistique message. (En outre, la norme ANSI permet la définition d' NULL à ((void *)0), qui ne sera pas de travail à la tous les non-pointeur de contextes.) Dans en particulier, ne pas utiliser NULL lorsque le ASCII caractère null (NUL) est souhaitée. Fournir votre propre définition

#define NUL '\0'

si vous devez.

7voto

Eugene Yokota Points 43213

Quelle est la différence entre la valeur NULL, ‘\0' et 0

"le caractère nul (NUL)" est la plus simple à la règle. '\0' est un caractère littéral. En C, il est mis en œuvre en tant que int, donc, c'est la même chose que 0, ce qui est d' INT_TYPE_SIZE. En C++, le caractère littéral est mis en œuvre en tant que char, qui est de 1 octet. Normalement, c'est différent de NULL ou 0.

Ensuite, NULL est une valeur de type pointeur qui indique qu'une variable n'est pas un espace d'adressage. Mis à part le fait qu'il est généralement mis en œuvre comme des zéros, il doit être capable d'exprimer l'adresse complète de l'espace de l'architecture. Ainsi, sur une architecture 32 bits, la valeur NULL (probable) est de 4 octets, et sur une architecture 64 bits de 8 octets. C'est jusqu'à la mise en œuvre de C.

Enfin, la traduction littérale 0 est de type int, ce qui est de la taille de l' INT_TYPE_SIZE. La valeur par défaut de INT_TYPE_SIZE peut être différent en fonction de l'architecture.

Apple a écrit:

La version 64 bits du modèle de données utilisé par Mac OS X est connu comme "LP64". C'est le modèle de données commun utilisé par d'autres 64 bits des systèmes UNIX de Sun et SGI ainsi que Linux 64-bit. Le LP64 modèle de données définit les types primitifs comme suit:

  • entiers de 32 bits
  • longs sont 64 bits
  • long-longs sont aussi 64-bit
  • les pointeurs sont des 64 bits

Wikipedia 64 bits:

Microsoft VC++ compilateur utilise la LLP64 modèle.

64-bit data models
Data model short int long  long long pointers Sample operating systems
LLP64      16    32  32    64        64       Microsoft Win64 (X64/IA64)
LP64       16    32  64    64        64       Most Unix and Unix-like systems (Solaris, Linux, etc.)
ILP64      16    64  64    64        64       HAL
SILP64     64    64  64    64        64       ?

Edit: Ajout de plus sur le caractère littéral.

#include <stdio.h>

int main(void) {
	printf("%d", sizeof('\0'));
	return 0;
}

Le code ci-dessus renvoie 4 sur gcc et 1 sur g++.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X