Ist es sicher, einen Zeiger darauf zu prüfen, dass er nicht NULL
ist, indem er einfach if(pointer)
schreibt oder muss ich if(pointer != NULL)
verwenden?
Sie können; Der Nullzeiger wird implizit in boolesches false konvertiert, während Nicht-Nullzeiger in true konvertiert werden. Aus dem C++ 11-Standard Abschnitt über Boolesche Konvertierungen:
Ein prvalue aus arithmetischer, nicht begrenzter Aufzählung, einem Zeiger oder einem Zeiger auf einen Mitgliedstyp kann in eine .__-Datei umgewandelt werden. prvalue vom Typ
bool
. Ein Nullwert, ein Nullzeigerwert oder ein Nullelementzeigerwert wird in .__ konvertiert.false
; Jeder andere Wert wird in .__ konvertiert.true
. Ein prvalue vom Typstd::nullptr_t
kann in einen prvalue von .__ umgewandelt werden. Artbool
; Der resultierende Wert istfalse
.
Ja du könntest.
Dies ist Teil der C++ - Standardkonvertierung, die in die Klausel Boolean conversion fällt:
§ 4.12 Boolesche Konvertierungen
Ein prvalue aus arithmetischer, nicht begrenzter Enumeration, pointer oder einem Zeiger auf einen Member-Typ kann in einen prvalue vom Typ bool umgewandelt werden. Ein Nullwert, Nullzeigerwert oder Nullelementzeigerwert wird in false konvertiert. Jeder andere Wert wird in true konvertiert. Ein prvalue vom Typ std :: nullptr_t kann in einen prvalue vom Typ bool umgewandelt werden. Der resultierende Wert ist falsch.
Ja, du kannst. Ich bevorzuge die Verwendung von if(pointer)
, weil es einfacher ist, zu lesen und zu schreiben, wenn Sie sich erst einmal daran gewöhnt haben.
Beachten Sie auch, dass C++ 11 nullptr
eingeführt hat, das gegenüber NULL
bevorzugt wird.
Die Frage ist beantwortet, aber ich möchte meine Punkte hinzufügen.
Ich werde immer if(pointer)
anstelle von if(pointer != NULL)
und if(!pointer)
anstelle von if(pointer == NULL)
vorziehen:
Weniger Chancen, einen fehlerhaften Code zu schreiben, angenommen, der Operator ==
mit =
ist falsch geschrieben.if(pointer == NULL)
kann falsch geschrieben werden if(pointer = NULL)
Also werde ich es vermeiden, am besten ist es nur if(pointer)
.
(Ich habe auch eine Yoda-Bedingung in einer Antwort vorgeschlagen , aber das ist eine andere Sache.)
In ähnlicher Weise schreibe ich für while (node != NULL && node->data == key)
einfach while (node && node->data == key)
, die für mich offensichtlicher ist (zeigt die Verwendung eines Kurzschlusses).
Ja, du kannst. Die Möglichkeit, Werte mit Nullen implizit zu vergleichen, wurde von C geerbt und ist in allen Versionen von C++ vorhanden. Sie können auch if (!pointer)
verwenden, um Zeiger auf NULL zu überprüfen.
Die relevanten Anwendungsfälle für Nullzeiger sind
Dynamische Besetzungen Das Umwandeln eines Basisklassenzeigers auf eine bestimmte abgeleitete Klasse (etwas, das Sie erneut vermeiden sollten, aber manchmal als notwendig erachten) ist immer erfolgreich, führt jedoch zu einem Nullzeiger, wenn die abgeleitete Klasse nicht übereinstimmt. Eine Möglichkeit dies zu überprüfen ist
Derived* derived_ptr = dynamic_cast<Derived*>(base_ptr);
if(derived_ptr != nullptr) { ... }
(oder vorzugsweise auto derived_ptr = ...
). Dies ist nun schlecht, da der abgeleitete (möglicherweise ungültige, d. H. Null) Zeiger außerhalb des Bereichs des Sicherheitsüberwachungs-if
-Blocks verbleibt. Dies ist nicht erforderlich, da Sie in C++ boolesche konvertierbare Variablen einfügen können innerhalb einer if
- Bedingung :
if(auto derived_ptr = dynamic_cast<Derived*>(base_ptr)) { ... }
was nicht nur kürzer und sicherer ist, sondern auch viel klarer ist: Wenn Sie in einer separaten if-Bedingung nach null suchen, fragt sich der Leser "ok", daher muss derived_ptr
hier nicht null sein ... nun, warum wäre es null? " Während die einzeilige Version sehr deutlich sagt: "Wenn Sie base_ptr
sicher in Derived*
umwandeln können, verwenden Sie es für ...".
Das Gleiche funktioniert genauso gut für alle anderen möglichen Fehleroperationen, die einen Zeiger zurückgeben, obwohl IMO dies generell vermeiden sollte: Es ist besser, etwas wie boost::optional
als "Container" für die Ergebnisse möglicherweise fehlerhafter Operationen anstelle von Zeigern zu verwenden.
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 Gründen der Konsistenz gut ist, immer diesen Stil zu verwenden, dh ich würde dafür plädieren if(ptr)
über if(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 real - Lösung für solche Probleme: Mustervergleich . Warum sollten Sie zuerst eine Aktion erzwingen (z. B. einen Zeiger werfen) und dann in Betracht ziehen, dass ein Fehler auftreten könnte ... Ich meine, es ist lächerlich, nicht wahr? Es ist so, als hätten Sie etwas zu essen und möchten Suppe machen. Sie geben es Ihrem Assistenten mit der Aufgabe, den Saft zu extrahieren, wenn es sich um ein weiches Gemüse handelt. Du siehst es nicht zuerst an. Wenn Sie eine Kartoffel haben, geben Sie sie immer noch Ihrem Assistenten, aber sie schlagen sie mit einem Fehlerhinweis in Ihr Gesicht. Ah, zwingende Programmierung!
Viel besser: Betrachten Sie sofort alle Fälle, auf die Sie stoßen könnten. Dann handeln Sie entsprechend. Haskell:
makeSoupOf :: Foodstuff -> Liquid
makeSoupOf [email protected](Potato{..}) = mash (boil p) <> water
makeSoupOf vegetable
| isSoft vegetable = squeeze vegetable <> salt
makeSoupOf stuff = boil (throwIn (water<>salt) stuff)
Haskell hat auch spezielle Werkzeuge für den Fall, dass eine ernsthafte Möglichkeit zum Scheitern besteht (sowie für eine ganze Reihe anderer Dinge): Monaden. Dies ist jedoch nicht der Ort, um diese zu erklären.
⟨/Inserat⟩
Ja. Eigentlich sollten Sie. Wenn Sie sich fragen, ob ein Segmentierungsfehler erstellt wird, ist dies nicht der Fall.
ja bitte! In der Tat ist das Schreiben von if (Zeiger) eine bequemere Schreibweise als wenn (Zeiger! = NULL), weil es ist leicht zu debuggen. 2. leicht verständlich 3. Wenn versehentlich der Wert von NULL definiert wird, stürzt auch der Code nicht ab