Arguments religieux mis à part:
Option 1:
if (pointer[i] == NULL) ...
Option 2:
if (!pointer[i]) ...
En C, l’option 1 est-elle fonctionnellement équivalente à l’option 2?
La résolution ultérieure est-elle plus rapide en raison de l'absence de comparaison?
J'aime le second, les autres aiment le premier.
En fait, je préfère un troisième type au premier:
if (NULL == ptr) {
...
}
Parce qu'alors je:
Fonctionnellement, ils sont équivalents.
Même si un pointeur NULL
n'est pas "0" (tous les bits nuls), if (!ptr)
est comparé au pointeur NULL
.
Ce qui suit est incorrect. Il est toujours là car de nombreux commentaires y font référence: Ne comparez pas un pointeur avec un zéro littéral, cependant. Cela fonctionnera presque partout mais c'est un comportement non défini IIRC.
Je préfère le style explicite (première version). Il est évident qu’il s’agit d’un pointeur et non d’un nombre entier ou autre, mais d’une question de style.
Du point de vue de la performance, cela ne devrait faire aucune différence.
Équivalent. C'est ce que dit la norme de langue. Et les gens ont les damndest préférences religieuses!
Il est souvent utile de supposer que les auteurs de compilateur ont au moins un minimum d'intelligence. Votre compilateur est not écrit par des canetons commotionnés. Il est écrit par des êtres humains, avec des années d'expérience en programmation et des années consacrées à l'étude de la théorie des compilateurs. Cela ne veut pas dire que votre compilateur est parfait et sait toujours mieux, mais cela signifie que [] est parfaitement capable de gérer des optimisations automatiques triviales.
Si les deux formes sont équivalentes, alors pourquoi le compilateur ne traduirait-il pas l'une dans l'autre pour s'assurer que les deux sont d'une efficacité équivalente?
Si if (pointer[i] == NULL)
était plus lent que if (!pointer[i])
, le compilateur ne le changerait-il pas simplement dans le deuxième formulaire, plus efficace?
Donc non, à supposer qu'ils soient équivalents, ils sont tout aussi efficaces.
Quant à la première partie de la question, oui, elles sont équivalentes. En fait, le standard de langage l'indique explicitement quelque part - un pointeur vaut true s'il n'est pas NULL et false s'il est NULL, les deux sont donc exactement identiques.
Presque certainement aucune différence de performance. Je préfère le style implicite de la seconde, cependant.
NULL
doit être déclaré dans l'un des fichiers d'en-tête standard en tant que tel:
#define NULL ((void*)0)
Donc, dans les deux cas, vous comparez à zéro et le compilateur doit optimiser les deux de la même manière. Chaque processeur a une "optimisation" ou un opcode permettant de comparer avec zéro.
L'optimisation précoce est mauvaise. La micro-optimisation est également mauvaise, sauf si vous essayez d'extraire le dernier bit en Hz de votre processeur, il est inutile de le faire. Comme les gens l'ont déjà montré, le compilateur optimisera de toute façon l'essentiel de votre code.
Il est préférable de rendre votre code aussi concis et lisible que possible. Si cela est plus lisible
if (!ptr)
que cela
if (NULL==ptr)
puis l'utiliser. Tant que tous ceux qui liront votre code seront d’accord.
Personnellement, j'utilise la valeur entièrement définie (NULL == ptr), de sorte qu'il est clair ce que je recherche. Peut-être plus long à taper, mais je peux facilement le lire. Je pense que le! Ptr serait facile à manquer! si vous lisez trop vite.
Cela dépend vraiment du compilateur. Je serais surpris que la plupart des compilateurs C modernes ne génèrent pas du code pratiquement identique pour le scénario spécifique que vous décrivez.
Demandez à votre compilateur de générer une liste Assembly pour chacun de ces scénarios et répondez à votre propre question (pour votre compilateur particulier :)).
Et même s'ils sont différents, la différence de performance ne sera probablement pas pertinente dans les applications pratiques.
Activer l'optimisation du compilateur et ils sont fondamentalement les mêmes
testé sur gcc 4.3.3
int main (int argc, char** argv) {
char c = getchar();
int x = (c == 'x');
if(x == NULL)
putchar('y');
return 0;
}
contre
int main (int argc, char** argv) {
char c = getchar();
int x = (c == 'x');
if(!x)
putchar('y');
return 0;
}
gcc -O -o test1 test1.c
gcc -O -o test2 test2.c
diff test1 test2
produit pas de sortie :)