Est-il sûr de vérifier un pointeur pour ne pas être NULL
en écrivant simplement if(pointer)
ou dois-je utiliser if(pointer != NULL)
?
c++
pointers
if-statement
null
null-pointer
danijar
la source
la source
0
ounullptr
. (NULL
est un C'ism, et nécessite d'inclure un fichier d'en-tête.)NULL
en C ++ à partir de maintenant carNULL
c'est une macro dépendante de l'implémentation qui peut vous donner des comportements ambigus.Réponses:
Vous pouvez; le pointeur nul est implicitement converti en booléen faux tandis que les pointeurs non nuls sont convertis en vrai. De la norme C ++ 11, section sur les conversions booléennes:
la source
Oui vous pourriez.
Cela fait partie de la conversion standard C ++, qui relève de la clause de conversion booléenne :
§ 4.12 Conversions booléennes
la source
Oui, vous pouvez. En fait, je préfère l'utiliser
if(pointer)
car c'est plus simple à lire et à écrire une fois que vous vous y êtes habitué.Notez également que C ++ 11 a introduit
nullptr
ce qui est préféré àNULL
.la source
if(som_integer)
vsif(some_integer != 0)
car les entiers ne sont pas non plus des booléens, non? Je préfère éviter0
ouNULL
dans une déclaration if.if (pointer)
me préférer , mais meif (ptr != nullptr)
semble parfaitement légitime. D'un autre côté, si je voyais quelqu'un de mon équipe qui écrivait,if (some_integer)
je le ferais changer enif (some_integer != 0)
. Cependant, je ne prétendrai pas que ce n'est pas une préférence relativement arbitraire de ma part - je préfère simplement ne pas traiter les pointeurs et les entiers de la même manière.if(isReady)
if(filePtr)
if(serviceNo)
? Faire exprès de mauvais noms de variables ne signifie pas grand-chose dans ce cas. Quoi qu'il en soit, j'ai déjà compris votre point de vue et je l'ai compris, mais je peux insister moi-même en utilisant mon propre style de codage, d'accord?La question a reçu une réponse, mais je voudrais ajouter mes points.
Je préférerai toujours
if(pointer)
au lieuif(pointer != NULL)
etif(!pointer)
au lieu deif(pointer == NULL)
:Moins de chances d'écrire un code bogué, supposons que si j'ai mal orthographié l'opérateur de vérification d'égalité
==
avec=
if(pointer == NULL)
peut être mal orthographiéif(pointer = NULL)
Donc je vais l'éviter, le mieux est justeif(pointer)
.(J'ai également suggéré une condition Yoda en une seule réponse , mais c'est une question différente)
De même pour
while (node != NULL && node->data == key)
, j'écrirai simplement cewhile (node && node->data == key)
qui est plus évident pour moi (montre que l'utilisation de court-circuit).la source
(boolean expression)? true : false
est complètement inutile. L'expression évalue àtrue
ou àfalse
; ce que vous dites, c'est "si c'est vrai, donnez-moi vrai, si c'est faux, donnez-moi faux". En bref: c'est complètement équivalent à l'expression booléenne elle-même. Notez qu'ilnode == NULL
s'agit d'une expression booléenne. BTW, vos deux implémentations renvoient exactement le contraire l'une de l'autre. Soit vous voulez!=
dans le premier, soit un seul!
dans le second.=
au lieu de==
est de rendre vos variablesconst
chaque fois que possible. Par exemple, vous pouvez définir votre fonction commeisEmnpy(node* const head) { ... }
, et le compilateur refuserait de la compiler si vous écriviez accidentellement à lanode = NULL
place denode == NULL
. Bien sûr, cela ne fonctionne que pour les variables que vous n'avez vraiment pas besoin de modifier.T* get() const
au lieu deoperator T*() const
pour éviter les conversions implicites. Ils ont cependant unoperator bool() const
.La vérification explicite de NULL pourrait fournir un indice au compilateur sur ce que vous essayez de faire, ce qui conduit à être moins sujet aux erreurs.
la source
Oui, vous pouvez. La possibilité de comparer des valeurs à des zéros implicitement a été héritée de C et est présente dans toutes les versions de C ++. Vous pouvez également utiliser
if (!pointer)
pour vérifier les pointeurs pour NULL.la source
Les cas d'utilisation pertinents pour les pointeurs nuls sont
Des lancers dynamiques. Le cast d'un pointeur de classe de base vers une classe dérivée particulière (quelque chose que vous devriez à nouveau essayer d'éviter, mais que vous pourriez parfois trouver nécessaire) réussit toujours, mais aboutit à un pointeur nul si la classe dérivée ne correspond pas. Une façon de vérifier cela est
(ou, de préférence,
auto derived_ptr = ...
). Maintenant, c'est mauvais, car cela laisse le pointeur dérivé (peut-être invalide, c'est-à-dire nul) en dehors de laif
portée du bloc de sécurité . Ce n'est pas nécessaire, car C ++ vous permet d'introduire des variables convertibles booléennes dans uneif
-condition :ce qui est non seulement plus court et sûr pour la portée, mais aussi beaucoup plus clair dans son intention: lorsque vous vérifiez null dans une condition if séparée, le lecteur se demande "ok, donc
derived_ptr
ne doit pas être nul ici ... eh bien, pourquoi le ferait il est nul? " Alors que la version d' une ligne dit très clairement « si vous pouvez en toute sécurité jetébase_ptr
àDerived*
, puis l ' utiliser ... ».La même chose fonctionne aussi bien pour toute autre opération d'échec possible qui retourne un pointeur, même si IMO vous devriez généralement éviter ceci: il est préférable d'utiliser quelque chose comme
boost::optional
le "conteneur" pour les résultats d'opérations éventuellement échouées, plutôt que des pointeurs.Donc, si le cas d'utilisation principal des pointeurs nuls doit toujours être écrit dans une variante du style implicite-cast, je dirais qu'il est bon pour des raisons de cohérence de toujours utiliser ce style, c'est-à-dire que je recommanderais
if(ptr)
plusif(ptr!=nullptr)
.J'ai bien peur de devoir terminer par une annonce: la
if(auto bla = ...)
syntaxe n'est en fait qu'une approximation un peu lourde de la vraie solution à de tels problèmes: la correspondance de motifs . Pourquoi voudriez-vous d'abord forcer une action (comme lancer un pointeur) et ensuite considérer qu'il pourrait y avoir un échec ... Je veux dire, c'est ridicule, n'est-ce pas? C'est comme si vous aviez de la nourriture et que vous vouliez faire de la soupe. Vous le donnez à votre assistant avec la tâche d'extraire le jus, s'il s'agit d'un légume mou. Vous ne le regardez pas d'abord. Lorsque vous avez une pomme de terre, vous la donnez toujours à votre assistant, mais il vous la claque au visage avec une note d'échec. Ah, programmation impérative!Bien mieux: considérez tout de suite tous les cas que vous pourriez rencontrer. Alors agissez en conséquence. Haskell:
Haskell a également des outils spéciaux pour les cas où il y a vraiment une sérieuse possibilité d'échec (ainsi que pour tout un tas d'autres choses): les monades. Mais ce n'est pas le lieu pour les expliquer.
⟨/publicité⟩
la source
if(ptr)
plutôt queif(ptr != nullptr)
, sur lesquelles il y a un peu plus à dire.Oui bien sûr! en fait, écrire if (pointer) est un moyen plus pratique d'écrire que if (pointer! = NULL) car: 1. il est facile à déboguer 2. facile à comprendre 3. si accidentellement, la valeur de NULL est définie, alors aussi le code ne plantera pas
la source
Oui. En fait, vous devriez. Si vous vous demandez si cela crée une erreur de segmentation , ce n'est pas le cas.
la source
Comme d'autres ont déjà bien répondu, ils sont tous deux interchangeables.
Néanmoins, il convient de mentionner qu'il pourrait y avoir un cas où vous voudrez peut-être utiliser l'instruction explicite, ie
pointer != NULL
.Voir également https://stackoverflow.com/a/60891279/2463963
la source
Oui, vous pouvez toujours le faire car la condition 'IF' s'évalue uniquement lorsque la condition à l'intérieur devient vraie. C n'a pas de type de retour booléen et renvoie donc une valeur non nulle lorsque la condition est vraie, tandis que renvoie 0 chaque fois que la condition dans 'IF' s'avère être fausse. La valeur non nulle renvoyée par défaut est 1. Ainsi, les deux manières d'écrire le code sont correctes alors que je préférerai toujours la seconde.
la source
Je pense qu'en règle générale, si votre expression if peut être réécrite comme
tel qu'il ne provoque AUCUN AVERTISSEMENT, alors THAT doit être le style préféré pour l' expression if . (Je sais que je reçois des avertissements lorsque j'attribue un ancien C
BOOL
(#define BOOL int
) à un C ++bool
, sans parler des pointeurs.)la source
"Est-ce sûr..?" est une question sur le standard du langage et le code généré.
"Est-ce une bonne pratique?" est une question sur la façon dont la déclaration est comprise par tout lecteur humain arbitraire de la déclaration. Si vous posez cette question, cela suggère que la version "sûre" est moins claire pour les futurs lecteurs et écrivains.
la source