it-swarm.com.de

C: Vergleich mit NULL

Religiöse Argumente beiseite:

  • Option 1:

    if (pointer[i] == NULL) ...
    
  • Option 2:

    if (!pointer[i]) ...  
    

In C ist Option1 funktional gleichbedeutend mit Option2? 

Löst sich die spätere Lösung aufgrund fehlender Vergleiche schneller auf?

21
Ande TURNER

Ich mag den zweiten, andere mögen den ersten.

Eigentlich bevorzuge ich eine dritte Art der ersten:

if (NULL == ptr) {
   ...
}

Weil ich dann:

  • kann nicht verfehlen und nur ein "=" eingeben
  • verpassen Sie nicht das "== NULL" und verwechseln Sie es mit dem Gegenteil, wenn die Bedingung lang ist (mehrere Zeilen)

Funktionell sind sie gleichwertig.

Selbst wenn ein NULL-Zeiger nicht "0" ist (alle Null-Bits), vergleicht if (!ptr) den NULL-Zeiger.

Das Folgende ist falsch. Es ist immer noch hier, weil es viele Kommentare gibt, die sich darauf beziehen: Vergleichen Sie jedoch keinen Zeiger mit der Literal-Null. Es funktioniert fast überall, ist aber unbestimmtes Verhalten.

15
Thomas

Ich bevorzuge den expliziten Stil (erste Version). Es ist offensichtlich, dass es sich um einen Zeiger handelt und nicht um eine ganze Zahl oder etwas anderes, sondern um eine Frage des Stils. 

Aus Sicht der Leistung sollte es keinen Unterschied machen. 

33
Laserallan

Äquivalent. So steht es im Sprachstandard. Und die Leute haben die am meisten religiösen Vorlieben!

30
Norman Ramsey

Es ist oft sinnvoll anzunehmen, dass Compiler-Schreiber mindestens über ein Minimum an Intelligenz verfügen. Ihr Compiler ist not geschrieben von besoffenen Entenküken. Es wurde von Menschen geschrieben, mit jahrelanger Programmiererfahrung und jahrelangem Studium der Compilertheorie. Das bedeutet nicht, dass Ihr Compiler perfekt ist und immer das Beste weiß, aber bedeutet, dass er perfekt in der Lage ist, triviale automatische Optimierungen durchzuführen.

Wenn die beiden Formulare gleich sind, warum übersetzt der Compiler dann nicht einfach eines in das andere, um sicherzustellen, dass beide gleich effizient sind?

Wenn if (pointer[i] == NULL) langsamer als if (!pointer[i]) wäre, würde der Compiler es nicht einfach in die zweite, effizientere Form ändern?

Also nein, wenn sie gleichwertig sind, sind sie gleich effizient.

Für den ersten Teil der Frage sind sie ja gleichwertig. Der Sprachstandard gibt dies tatsächlich irgendwo explizit an - ein Zeiger wertet true aus, wenn er nicht NULL ist, und false, wenn er NULL ist, also sind die beiden genau identisch.

19
jalf

Fast sicher kein Unterschied in der Leistung. Ich bevorzuge jedoch den impliziten Stil des zweiten.

9
Barry Kelly

NULL sollte in einer der Standard-Header-Dateien als solche deklariert werden:

#define NULL ((void*)0)

So oder so, Sie vergleichen mit Null und der Compiler sollte beide auf dieselbe Weise optimieren. Jeder Prozessor verfügt über einige "Optimierungen" oder Opcodes zum Vergleichen mit Null.

3
Mark Rushakoff

Frühe Optimierung ist schlecht. Die Mikrooptimierung ist auch schlecht, es sei denn, Sie versuchen, jedes letzte Hz-Bit aus Ihrer CPU herauszudrücken. Wie bereits gezeigt wurde, optimiert der Compiler den größten Teil Ihres Codes sowieso.

Am besten machen Sie Ihren Code so kurz und lesbar wie möglich. Wenn dies besser lesbar ist

if (!ptr)

als das

if (NULL==ptr)

dann verwenden Sie es. Solange jeder, der Ihren Code lesen wird, zustimmt. 

Persönlich verwende ich den vollständig definierten Wert (NULL == ptr), damit klar ist, wonach ich prüfe. Könnte länger dauern, aber ich kann es leicht lesen. Ich denke, das! Ptr wäre leicht zu übersehen! wenn schnell zu lesen.

1
shimpossible

Es kommt wirklich auf den Compiler an. Es würde mich überraschen, wenn die meisten modernen C-Compiler für das von Ihnen beschriebene Szenario keinen praktisch identischen Code generieren würden.

Lassen Sie Ihren Compiler eine Assembly-Liste für jedes dieser Szenarien erstellen und Sie können Ihre eigene Frage beantworten (für Ihren speziellen Compiler :).

Und selbst wenn sie sind unterschiedlich sind, ist der Leistungsunterschied in praktischen Anwendungen wahrscheinlich irrelevant.

0
Thomas Lee

Aktivieren Sie die Compiler-Optimierung und sie sind im Grunde gleich

getestet dies auf gcc 4.3.3

int main (int argc, char** argv) {
   char c = getchar();
   int x = (c == 'x');
   if(x == NULL)
      putchar('y');
   return 0;
}

vs

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

produziert keine Ausgabe :)

0
Charles Ma