Ist es sicher, einen Zeiger darauf zu überprüfen, dass man nicht NULL
einfach schreibt, if(pointer)
oder muss ich ihn verwenden if(pointer != NULL)
?
c++
pointers
if-statement
null
null-pointer
Danijar
quelle
quelle
0
oder zu testennullptr
. (NULL
ist ein C'ism und erfordert das Einfügen einer Header-Datei.)NULL
ab diesem Zeitpunkt nicht mehr in C ++ verwenden, daNULL
es sich um ein implementierungsabhängiges Makro handelt, das möglicherweise zu mehrdeutigen Verhaltensweisen führt.Antworten:
Sie können; Der Nullzeiger wird implizit in einen booleschen Wert false umgewandelt, während Nicht-Nullzeiger in true konvertiert werden. Aus dem C ++ 11-Standard, Abschnitt über Boolesche Konvertierungen:
quelle
Ja du könntest.
Dies ist Teil der C ++ - Standardkonvertierung, die in die Boolesche Konvertierungsklausel fällt :
§ 4.12 Boolesche Konvertierungen
quelle
Ja, du kannst. Tatsächlich bevorzuge ich die Verwendung,
if(pointer)
weil das Lesen und Schreiben einfacher ist, wenn man sich erst einmal daran gewöhnt hat.Beachten Sie auch, dass C ++ 11 eingeführt wurde,
nullptr
das gegenüber bevorzugt wirdNULL
.quelle
if(som_integer)
vsif(some_integer != 0)
anwenden, weil Ganzzahlen auch keine Booleschen Werte sind, oder? Ich bevorzuge es zu vermeiden0
oderNULL
in einer if-Anweisung.if (pointer)
mich selbst zu bevorzugen , aberif (ptr != nullptr)
scheint mir vollkommen legitim zu sein. Wenn ich andererseits jemanden in meinem Team sehenif (some_integer)
würde, der geschrieben hat, würde ich ihn dazu bringen, es zu ändernif (some_integer != 0)
. Ich werde jedoch nicht so tun, als wäre dies keine relativ willkürliche Präferenz meinerseits - ich ziehe es einfach vor, Zeiger und ganze Zahlen nicht gleich zu behandeln.if(isReady)
if(filePtr)
if(serviceNo)
? Absichtlich schlechte Variablennamen zu erstellen, bedeutet in diesem Fall nicht viel. Wie auch immer, ich habe Ihren Standpunkt bereits verstanden und verstanden, aber ich kann darauf bestehen, meinen eigenen Codierungsstil selbst zu verwenden, OK?Die Frage wird beantwortet, aber ich möchte meine Punkte hinzufügen.
Ich werde immer lieber
if(pointer)
anstelle vonif(pointer != NULL)
undif(!pointer)
anstelle vonif(pointer == NULL)
:Weniger Chancen auf einen fehlerhaften Code zu schreiben, nehme an, wenn ich Gleichheitsprüfung Operator falsch geschrieben
==
mit=
if(pointer == NULL)
kann falsch geschrieben ,if(pointer = NULL)
damit ich es vermeiden, am besten ist einfachif(pointer)
.(Ich schlug auch eine Yoda-Bedingung in einer Antwort vor , aber das ist eine andere Sache)
In ähnlicher Weise
while (node != NULL && node->data == key)
werde ich einfach schreibenwhile (node && node->data == key)
, was für mich offensichtlicher ist (zeigt, dass Kurzschluss verwendet wird).quelle
(boolean expression)? true : false
ist völlig sinnlos. Der Ausdruck wertet entweder zutrue
oder zu ausfalse
; Was Sie sagen, ist "wenn es wahr ist, geben Sie mir wahr, wenn es falsch ist, geben Sie mir falsch". Kurz gesagt: Es entspricht vollständig dem booleschen Ausdruck selbst. Beachten Sie, dass diesnode == NULL
ein boolescher Ausdruck ist. Übrigens geben Ihre beiden Implementierungen genau das Gegenteil voneinander zurück. Entweder Sie wollen!=
in der ersten oder nur eine!
in der zweiten.=
statt==
darin, Ihre Variablen zuconst
erstellen , wann immer dies möglich ist. Sie könnten beispielsweise Ihre Funktion als definierenisEmnpy(node* const head) { ... }
, und dann würde der Compiler die Kompilierung ablehnen, wenn Sie versehentlichnode = NULL
statt schreiben würdennode == NULL
. Das funktioniert natürlich nur für Variablen, die Sie wirklich nicht ändern müssen.T* get() const
stattdessenoperator T*() const
implizite Konvertierungen vermeiden. Sie haben jedoch eineoperator bool() const
.Das explizite Überprüfen auf NULL kann dem Compiler einen Hinweis darauf geben, was Sie versuchen, was dazu führen kann, dass er weniger fehleranfällig ist.
quelle
Ja, du kannst. Die Möglichkeit, Werte implizit mit Nullen zu vergleichen, wurde von C geerbt und ist in allen Versionen von C ++ vorhanden. Sie können auch
if (!pointer)
Zeiger auf NULL prüfen.quelle
Die relevanten Anwendungsfälle für Nullzeiger sind
Dynamische Besetzungen. Das Umwandeln eines Basisklassenzeigers in eine bestimmte abgeleitete Klasse (etwas, das Sie erneut vermeiden sollten, das Sie jedoch manchmal für erforderlich halten) ist immer erfolgreich, führt jedoch zu einem Nullzeiger, wenn die abgeleitete Klasse nicht übereinstimmt. Eine Möglichkeit, dies zu überprüfen, ist
(oder vorzugsweise
auto derived_ptr = ...
). Dies ist schlecht, da der (möglicherweise ungültige, dh null) abgeleitete Zeiger außerhalb desif
Bereichs des Sicherheitsschutzblocks bleibt . Dies ist nicht erforderlich, da Sie in C ++ boolesche konvertierbare Variablen in eineif
Bedingung einführen können :Das ist nicht nur kürzer und bereichssicher, sondern auch viel klarer in seiner Absicht: Wenn Sie in einer separaten if-Bedingung nach null suchen, fragt sich der Leser: "OK,
derived_ptr
darf hier also nicht null sein ... nun, warum sollte es ist null? " Während die einzeilige Version sehr deutlich sagt : „Wenn Sie sicher werfen könnenbase_ptr
zuDerived*
, dann verwenden Sie es für ...“.Das Gleiche funktioniert genauso gut für alle anderen Operationen mit möglichen Fehlern, die einen Zeiger zurückgeben. IMO sollten Sie dies jedoch generell vermeiden: Es ist besser, so etwas wie
boost::optional
den "Container" für Ergebnisse möglicherweise fehlgeschlagener Operationen zu verwenden, als Zeiger.Wenn also der Hauptanwendungsfall für Nullzeiger immer in einer Variation des impliziten Cast-Stils geschrieben werden sollte, würde ich sagen, dass es aus Konsistenzgründen gut ist , diesen Stil immer zu verwenden, dh ich würde mich für
if(ptr)
mehr einsetzenif(ptr!=nullptr)
.Ich fürchte, ich muss mit einer Anzeige enden: Die
if(auto bla = ...)
Syntax ist eigentlich nur eine etwas umständliche Annäherung an die eigentliche Lösung solcher Probleme: Pattern Matching . Warum sollten Sie zuerst eine Aktion erzwingen (z. B. einen Zeiger werfen) und dann bedenken, dass möglicherweise ein Fehler vorliegt? Ich meine, es ist lächerlich, nicht wahr? Es ist wie, Sie haben etwas zu essen und möchten Suppe machen. Sie geben es Ihrem Assistenten mit der Aufgabe, den Saft zu extrahieren, falls es sich um ein weiches Gemüse handelt. Du siehst es dir nicht zuerst an. Wenn Sie eine Kartoffel haben, geben Sie sie immer noch Ihrem Assistenten, aber er schlägt sie Ihnen mit einem Fehlerbericht ins Gesicht. Ah, zwingende Programmierung!Viel besser: Betrachten Sie sofort alle Fälle, auf die Sie stoßen könnten. Dann handeln Sie entsprechend. Haskell:
Haskell hat auch spezielle Werkzeuge für den Fall, dass wirklich ernsthafte Fehler möglich sind (sowie für eine ganze Reihe anderer Dinge): Monaden. Aber das ist nicht der Ort, um diese zu erklären.
⟨/Inserat⟩
quelle
if(ptr)
stattif(ptr != nullptr)
, zu der es ein bisschen mehr zu sagen.ja natürlich! In der Tat ist das Schreiben von if (Zeiger) eine bequemere Schreibweise als if (Zeiger! = NULL), weil: 1. es leicht zu debuggen ist 2. leicht zu verstehen ist 3. wenn versehentlich der Wert von NULL definiert wird, dann stürzt auch der Code nicht ab
quelle
Ja. In der Tat sollten Sie. Wenn Sie sich fragen, ob ein Segmentierungsfehler auftritt , ist dies nicht der Fall.
quelle
Wie andere bereits gut geantwortet haben, sind beide austauschbar.
Es ist jedoch erwähnenswert, dass es einen Fall geben kann, in dem Sie die explizite Aussage verwenden möchten, z
pointer != NULL
.Siehe auch https://stackoverflow.com/a/60891279/2463963
quelle
Ja, Sie können dies immer tun, da die 'IF'-Bedingung nur dann ausgewertet wird, wenn die darin enthaltene Bedingung erfüllt ist. C hat keinen booleschen Rückgabetyp und gibt daher einen Wert ungleich Null zurück, wenn die Bedingung wahr ist, während 0 zurückgegeben wird, wenn sich die Bedingung in 'IF' als falsch herausstellt. Der standardmäßig zurückgegebene Wert ungleich Null ist 1. Somit sind beide Arten des Schreibens des Codes korrekt, während ich immer den zweiten vorziehen werde.
quelle
Ich denke als Faustregel, ob Ihr if-Ausdruck als neu geschrieben werden kann
so dass es KEINE WARNUNGEN verursacht, sollte DAS der bevorzugte Stil für den if-Ausdruck sein . (Ich weiß, dass ich Warnungen bekomme, wenn ich einem C ++ ein altes C
BOOL
(#define BOOL int
) zuweisebool
, geschweige denn Zeiger.)quelle
"Ist es sicher..?" ist eine Frage zum Sprachstandard und zum generierten Code.
"Ist das eine gute Praxis?" ist eine Frage, wie gut die Aussage von einem beliebigen menschlichen Leser der Aussage verstanden wird. Wenn Sie diese Frage stellen, deutet dies darauf hin, dass die "sichere" Version für zukünftige Leser und Autoren weniger klar ist.
quelle