2010-11-26 4 views
2

tout le monde, j'ai une question sur C++, qu'est-ce que vous préférez réellement utiliserpointeur NULL dans C++

int* var = 0; 

if(!var)...//1) 
or 
if(var == 0)..//2) 

quels sont les avantages et les inconvénients? merci à l'avance

+0

Je suis d'accord avec les autres sur l'option 1. Bien que vous devriez probablement vous habituer à écrire 'int * var = std :: nullptr;'. http://en.wikipedia.org/wiki/C%2B%2B0x#Null_pointer_constant – manneorama

+2

Juste comme une remarque, lorsque vous comparez une variable à une valeur constante, placez la constante sur le côté gauche, par exemple. 'if (0 == var);' de cette façon, vous évitez les bogues comme si vous en oubliez accidentellement un '=' le compilateur vous le dira. – Trinidad

+0

@Trinidad: belle recommandation – rookie

Répondre

5

On m'a toujours appris à utiliser if (!var), et il semble que tout le idiomatique C (++) que j'ai jamais lu suit cela. Cela a quelques sémantique agréable:

  • Il n'y a pas cession accidentelle
  • Vous testez l'existence de quelque chose (à savoir si elle est NULL.). Par conséquent, vous pouvez lire l'instruction comme "Si var n'existe pas" ou "Si var n'est pas défini"
  • Mappe étroitement à ce que vous écrivez idiomatically si var était un booléen (les booléens ne sont pas disponibles dans C, mais les gens imitent encore leur utilisation)
  • Similaire au point précédent, il se rapproche des appels de fonction de prédicat, c'est-à-dire. if (!isEmpty(nodeptr)) { .. }
9

Je préfère if (!var), parce que vous pouvez pas céder accidentellement à var, et vous ne devez pas choisir entre 0 et NULL.

1

L'un ou l'autre est bon, bien que personnellement je préfère 2 - ou quelque chose comme ça.

plus de sens pour moi de lire:

if (ptr != NULL) 

que

if (ptr) 

Le second je confondre pour être juste un booléen à regarder, mais le premier que je serais capable de dites immédiatement que c'est un pointeur.

De toute façon, je pense qu'il est important d'en choisir un et de s'en tenir à cela par souci de cohérence, plutôt que de le faire de différentes façons tout au long de votre produit.

2

Préférence personnelle. Certains diront que le premier est préféré car il devient impossible d'attribuer accidentellement au lieu de comparer. Mais par ce même ordre d'idées, si vous prenez l'habitude de mettre la rvalue à gauche de la comparaison, le compilateur vous attraper lorsque vous soufflez:

if(0 == var) 

... ce qui est certainement vrai. Je trouve simplement que if(!var) est un peu plus expressif et moins typé.

Ils évalueront tous deux la même chose, donc il n'y a pas de différence d'exécution. La chose la plus importante est que vous choisissez un et coller avec elle. Ne mélangez pas l'un avec l'autre.

0

Je préférerais l'option 3:

if(not var) 
{ 
} 

Les nouveaux (et depuis 1998) mots-clés de l'opérateur C++ peut rendre le code plus facile à lire parfois.

Curieusement, ils semblent être très inconnus. Il semble y avoir plus de gens qui savent ce que sont les trigraphes (merci IOCCC!), que les personnes qui savent ce que sont les mots-clés de l'opérateur. Les mots-clés de l'opérateur ont une raison similaire d'exister: ils permettent de programmer en C++ même si le clavier ne fournit pas tous les caractères ANSII. Mais en contradiction avec les trigraphes, les mots-clés d'opérateur rendent le code plus lisible au lieu de l'obscurcir.

+0

Que voulez-vous dire par "nouveaux" opérateurs de mots-clés? 'not 'a été dans la norme C++ dès le premier jour. – fredoverflow

+0

Voir ici: http://flylib.com/books/fr/2.253.1.463/1/ – codymanix

+0

Ou ici: http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B – codymanix

0

Selon le High Integrity C++ de codage manuel standard: pour la comparaison entre les constantes et les variables que vous devez mettre la constante sur le côté gauche pour éviter une affectation au lieu d'une comparaison d'égalité, par exemple:

Avoid: 
if(var == 10) {...} 

Prefer 
if(10 == var) {...} 

Particulièrement dans votre cas je préfère if (0 == var) car il est clair que vous comparez le pointeur à null (0). Parce que le ! l'opérateur peut être surchargé alors il pourrait avoir d'autres significations selon ce que votre pointeur indique: if (! (* var)) {...}.

+0

Wrong are you. – ybungalobill

+0

@ybungalobill: Que voulez-vous dire? – ArBR

+0

Selon la référence C++ MSDN: Opérateur de négation logique!: Pour une expression e, l'expression unaire! E est équivalente à l'expression (e == 0), sauf si des opérateurs surchargés sont impliqués. http://msdn.microsoft.com/en-us/library/1k6w8551(VS.80).aspx – ArBR

0
  1. NE PAS utiliser NULL, utilisez 0.
  2. à proprement parler, le pointeur ne bool, donc utilisez '==' et '! =' Opérateurs.
  3. N'utilisez JAMAIS 'if (ptr == 0)', utilisez plutôt 'if (0 == ptr)'.
  4. N'utilisez PAS de pointeurs C, utilisez plutôt smart_ptr. :-)
+0

par curiosité: pourquoi ne pas utiliser NULL? Encore une fois, il est plus clair que vous traitez avec un pointeur dans le contrôle que de dire, en vérifiant une valeur int n'est pas zéro (ce qui est assez commun lorsque vous vous en tenez à la division par zéro). – TZHX

+0

Matthew Wilson et Bjarne Stroustrup recommandent d'utiliser 0 à la place NULL, car NULL - c'est une macros définies de différentes façons sur différentes plates-formes, mais 0 - toujours zéro. Et à proprement parler, NULL fait partie du langage C, pas C++. –

1

Quelques années a passé ...

La norme C++ 11 introduit nullptr pour vérifier les pointeurs nuls et il doit être utilisé comme veiller à ce que la comparaison est effectivement faite sur un pointeur. Ainsi, le plus robuste chèque serait de faire:

if(myPtr != nullptr) 

Le problème avec !var est qu'il est valide si var est un booléen ou une valeur numérique (int, byte, etc ...), il testera si elles sont égales à 0 ou non. Alors que si vous utilisez nullptr, vous êtes sûr que vous vérifiez un pointeur aucun autre type:

Par exemple:

int valA = 0; 
int *ptrA = &valA; 

if(!valA) // No compile error 
if(!*ptrA) // No compile error 
if(!ptrA) // No compile error 

if(valA != nullptr) // Compile error, valA is not a pointer 
if(*ptrA != nullptr) // Compile error, *ptrA is not a pointer 
if(ptrA != nullptr) // No compile error 

Ainsi, il est assez facile de faire une erreur lorsque le pointeur de la manipulation d'un int comme dans votre exemple, c'est pourquoi nullptr devrait être utilisé.