7
votes

Manière idiomatique de vérifier le non-zéro

Lorsque je souhaite vérifier si une valeur est 0 en C, comment est-ce fait idiomatiquement?

  • si (! num)
  • si (num == 0)

3 commentaires

Préférez si (0 == num) Si vous devez choisir une seconde sur le premier.First est la meilleure option.


@Als si (0 == num) , l'état classique Yoda


@DavidHeffernan: Q du choix personnel vraiment.Je préfère cela.


8 Réponses :


6
votes

Je préfère toujours la deuxième façon: xxx

comme num == 0 ou ptr == null est évalué à un booléen qui est l'intention. Le compilateur Java applique ce formulaire, mais les compilateurs C / C ++ ne le font pas.

Le pire exemple de ce serait: xxx

qui déguise vraiment sa Intention comme le STRCMP La famille de fonctions ne retourne pas booléen, ils retournent positive, zéro ou négatif (comme indiqué par @jooMimpileborg).

Toutefois si le INT est utilisé pour représenter un type booléen, lequel c n'a pas de type intégré pour, alors ce formulaire est correct: xxx

mais cela peut être fait Documentation automatique en créant un type personnalisé: xxx


7 commentaires

STRCMP est un bon exemple. J'aime ça dans Objective-C, Apple a fourni une énumération avec nsordédascending , nsordedsame et nsordeddescendants qui rend l'intention plus claire que -1, 0 et 1.


En ce qui concerne le cas STRCMP , la valeur de retour peut en réalité être une valeur positive ou négative, outre zéro. Ne comparez jamais contre 1 ou -1 .


@ Joachimpileborg: convenu; Vous utiliseriez <0 , == 0 ou > 0 .


Oh yuck! Non! "Comme NUM == 0 ou PTR == NULL, évalue à un booléen qui est l'intention. Le compilateur Java applique ce formulaire, mais les compilateurs C / C ++ ne le font pas." Cette question est étiquetée C. en C Ces opérations n'évaluent pas à un booléen. Ils évaluent à 0 ou 1, explicitement dans la spécification AN INT 0 ou 1.


@Jamesgreenhalgh: Préférez-vous quelque chose comme: Char * p = et quelque chose; Si (p) {...} ?


@trojanfoe Je n'exprime aucune préférence pour les idiomes. J'exprime une préférence pour des déclarations précises sur le résultat des expressions. Les opérateurs d'égalité et de comparaison renvoient un int de valeur 0 ou 1. Cette distinction est importante dans C99, où l'évaluation de Boolean impliquerait un résultat de type _bool.


@Jamesgreenhalgh: intéressant; Je n'aurais même jamais entendu parler de _bool que seuls seuls l'utiliser. Vous vivez et apprenez :)



15
votes

S'il s'agit d'une question de goût, je trouve que cela dépend à peu près de l'intention. Si la valeur doit être utilisée en tant que booléen, ! Code> va bien. Si la valeur compte quelque chose, l'égalité a plus de sens.

if (!isVisible) {...}
if (isVisible == 0) {...} // Intention not as clear as line above.

if (numberOfItems == 0) {...}
if (!numberOfItems) {...} // Intention not as clear as line above.


0 commentaires

2
votes

Je pense que cela dépend du contexte. Si la variable se réfère à une valeur booléenne est meilleure première fois. Sinon, la seconde est meilleure.


2 commentaires

J'étais sur le point d'écrire exactement la même chose.


Je pense que nous avons tous écrit sur la même chose;)



0
votes

C'est fait, mais vous voulez que ce soit fait, en termes de style. Je ne le vois pas aussi longtemps que votre cohérence et il est clair sur ce que vous essayez de faire, ou si vous le faites dans des cas où cela pourrait mieux couler dans une phrase anglaise et mettre l'accent sur ce que vous faites.

Pour des raisons de clarté, j'ai généralement si (num == 0) , car il faut moins de penser à comprendre ce que je fais quand je vais sur mon code.


0 commentaires

3
votes

Peu importe les autres que les autres vous ont dit avec une exception!

Ne le faites pas avec float et double . IEEE 754 float s / double S / LONG Double S (le plus couramment utilisé) souvent ne contient pas de valeurs exactes, donc les comparant directement avec 0 est stupide (ou faisant si (! floatvalue) )

Exemple: http://ideone.com/piuffla xxx

avec une compilation non optimisée peut retour (sur Ideone Est-ce que) xxx

(Si vous activez des optimisations, le compilateur pourrait pré-calculer certaines valeurs dans une précision supérieure et les arrondir à 0 )


3 commentaires

Mais cela n'a-t-il pas plus à voir avec 0,1 ne pas être représentable dans la base 2?


@Paul oui (et même 0.2 et 0.3 ). Mais le "pourquoi" n'est pas vraiment pertinent. La chose importante était "ne le fais pas avec flotteur un double"


La raison donnée est fausse. "Souvent ne contient pas de valeurs exactes" n'est pas vrai: les types de points flottants contiennent des valeurs exactes - mais le résultat d'un calcul peut ne pas être ce qu'une personne suppose naïvement. Si vous attribuez un "0" littéral à un flotteur, il se comparera toujours à celui de "0". et c'est la même chose pour -0 aussi que cela se compare comme égal à +0.



0
votes

!! user fonctionnera également si vous souhaitez vérifier si la valeur n'est pas nulle.

! Valeur Évalue à 1 lorsque la valeur = 0 et 0 lorsque la valeur 0.
Le second ! flipse, rendant !


2 commentaires

Et est même une astuce en C ++ Stackoverflow.com/questions/ 248693 / Double-négation-In-C-Code


@xanatos: Bien sûr, la question était à propos de C.



0
votes

Nous pouvons discuter de quelle manière c'est mieux, mais idiomatique, bien que pour ce que je puisse dire par d'autres réponses archaic, serait si (! num) . .


0 commentaires

1
votes

Pour le compilateur, cela n'a pas d'importance, bien sûr. Pour le lecteur humain, il fait. Étant donné que les deux formes sont utilisées par d'autres êtres humains, vous devriez vous y habituer et les reconnaître. Personnellement, je préfère la forme la plus courte, qui prend moins de temps (moins de jetons, en particulier par la parenthèse) de lire et de comprendre. Surtout:

if (ptr != NULL) {}
if (strcmp(a,b) == 0) {}
of (0 == strcmp()) {}


0 commentaires