Angenommen, ich habe eine boolesche Bedingung a AND b OR c AND d
und verwende eine Sprache, bei AND
der eine höhere Operationsreihenfolge vorliegt als OR
. Ich könnte diese Codezeile schreiben:
If (a AND b) OR (c AND d) Then ...
Aber wirklich, das ist gleichbedeutend mit:
If a AND b OR c AND d Then ...
Gibt es irgendwelche Argumente für oder gegen das Einschließen der äußeren Klammern? Schlägt die praktische Erfahrung vor, dass es sich lohnt, sie zur besseren Lesbarkeit einzuschließen? Oder ist es ein Zeichen dafür, dass sich ein Entwickler wirklich hinsetzen und sich auf die Grundlagen seiner Sprache verlassen muss?
coding-style
operator-precedence
Jeff Bridgman
quelle
quelle
2 * 3 + 2
ist vielleicht dasselbe wie,(2 * 3) + 2
aber die zweite ist leichter zu lesen.Antworten:
Gute Entwickler bemühen sich, Code zu schreiben, der klar und korrekt ist . Klammern in Bedingungen helfen bei beiden, auch wenn sie nicht unbedingt erforderlich sind.
Wie für Klarheit , denken Sie an den Klammern wie Kommentare in dem Code ein : sie nicht unbedingt erforderlich sind, und in der Theorie sollte ein kompetenter Entwickler in der Lage sein , Code , ohne sie zu verstehen . Und doch sind diese Hinweise äußerst hilfreich, weil:
Darüber hinaus helfen zusätzliche Klammern, genau wie Einrückungen, Leerzeichen und andere Stilstandards, den Code auf logische Weise visuell zu organisieren.
Bezüglich der Richtigkeit sind Bedingungen ohne Klammern ein Rezept für dumme Fehler. Wenn sie auftreten, kann es sich um schwer zu findende Fehler handeln, da sich ein falscher Zustand die meiste Zeit korrekt verhält und nur gelegentlich fehlschlägt.
Und selbst wenn Sie es richtig machen, kann es sein, dass die nächste Person, die an Ihrem Code arbeitet, dem Ausdruck Fehler hinzufügt oder Ihre Logik missversteht und somit Fehler an anderer Stelle hinzufügt (wie LarsH zu Recht hervorhebt).
Ich benutze immer Klammern für Ausdrücke, die
and
und kombinierenor
(und auch für arithmetische Operationen mit ähnlichen Prioritätsproblemen).quelle
Es ist weniger wichtig, ob Sie mit der Sprache vertraut sind. Was mehr zählt, ist das Verständnis der Sprache des n00b, das Ihnen folgt.
Schreiben Sie Ihren Code so klar und eindeutig wie möglich. Zusätzliche Klammern helfen oft (aber nicht immer). Oft hilft es, nur eine Anweisung in eine Zeile zu setzen. Konsistenz in der Codierung hilft oft.
Es gibt so etwas wie zu viele Klammern, aber es ist eine der Situationen, in denen Sie keinen Rat brauchen - Sie werden es wissen, wenn Sie es sehen. An diesem Punkt überarbeiten Sie Ihren Code, um die Komplexität der Anweisung zu verringern, anstatt Klammern zu entfernen.
quelle
There is such a thing as too many parenthesis
- Sie sind offensichtlich kein lisper;)Ja
Sie sollten immer Klammern verwenden ... Sie haben keinen Einfluss auf die Rangfolge ... der Entwickler des Compilers. Hier ist eine Geschichte, die mir über die Nichtverwendung von Klammern passiert ist. Dies betraf über einen Zeitraum von zwei Wochen Hunderte von Menschen.
Grund der realen Welt
Ich habe eine Mainframe-Anwendung übernommen. Eines Tages hörte es aus heiterem Himmel auf zu funktionieren. Das war's ... puh, es hat einfach aufgehört.
Meine Aufgabe war es, es so schnell wie möglich zum Laufen zu bringen. Der Quellcode war seit zwei Jahren nicht mehr verändert worden, aber plötzlich hörte er einfach auf. Ich habe versucht, den Code zu kompilieren und er ist in Zeile XX kaputt gegangen. Ich habe mir Zeile XX angesehen und konnte nicht sagen, was dazu führen würde, dass Zeile XX abbricht. Ich fragte nach den detaillierten Spezifikationen für diese Anwendung und es gab keine. Zeile XX war nicht der Täter.
Ich druckte den Code aus und begann ihn von oben nach unten zu überprüfen. Ich fing an, ein Flussdiagramm zu erstellen, was vor sich ging. Der Code war so verworren, dass ich kaum einen Sinn daraus ziehen konnte. Ich habe es aufgegeben, ein Flussdiagramm zu erstellen. Ich hatte Angst, Änderungen vorzunehmen, ohne zu wissen, wie sich diese Änderungen auf den Rest des Prozesses auswirken würden, zumal ich keine Einzelheiten darüber hatte, was die Anwendung tat oder wo sie sich in der Abhängigkeitskette befand.
Also habe ich beschlossen, am Anfang des Quellcodes zu beginnen und Leerzeichen und Zeilenbremsen hinzuzufügen, um den Code besser lesbar zu machen. In einigen Fällen stellte ich fest, dass sich die Bedingungen zusammentaten
AND
undOR
es nicht klar erkennbar war, welche DatenAND
bearbeitet wurden und welche DatenOR
bearbeitet wurden. Also fing ich an, Klammern um die BedingungenAND
undOR
zu setzen, um sie lesbarer zu machen.Da ich langsam nach unten ging und es aufräumte, speicherte ich meine Arbeit regelmäßig. Irgendwann habe ich versucht, den Code zu kompilieren und es passierte etwas Merkwürdiges. Der Fehler hatte die ursprüngliche Codezeile übersprungen und war nun weiter unten. So fuhr ich fort, die speparating
AND
undOR
Bedingungen mit Pars. Als ich fertig war, klappte es. Stelle dir das vor.Ich beschloss dann, den Operations Shop zu besuchen und sie zu fragen, ob sie kürzlich neue Komponenten auf dem Hauptrahmen installiert hatten. Sie sagten ja, wir haben kürzlich den Compiler aktualisiert. Hmmmm.
Es stellt sich heraus, dass der alte Compiler den Ausdruck unabhängig davon von links nach rechts ausgewertet hat. Die neue Version des Compilers bewertete auch Ausdrücke von links nach rechts, aber mehrdeutigen Code, was bedeutet, dass eine unklare Kombination von
AND
undOR
nicht aufgelöst werden konnte.Daraus habe ich gelernt ... IMMER, IMMER, IMMER benutze ich Parens, um
AND
Bedingungen undOR
Zustände voneinander zu trennen , wenn sie in Verbindung miteinander verwendet werden.Vereinfachtes Beispiel
IF Product = 191 OR Product = 193 AND Model = "ABC" OR Product = 201 OR Product = 202 AND Model = "DEF" ...
(Code mit mehreren davon übersät)Dies ist eine vereinfachte Version von dem, was ich angetroffen habe. Es gab auch andere Bedingungen mit zusammengesetzten booleschen Logikanweisungen.
Ich erinnere mich, dass ich es getippt habe, um:
IF ((Product = 191 OR Product = 193) AND Model = "ABC") OR ((Product = 201 OR Product = 202) AND Model = "DEF") ...
Ich konnte es nicht umschreiben, weil es keine Spezifikationen gab. Der ursprüngliche Autor war lange weg. Ich erinnere mich an starken Druck. Ein ganzes Frachtschiff war im Hafen gestrandet und konnte nicht entladen werden, da dieses kleine Programm nicht funktionierte. Keine Warnung. Keine Änderungen am Quellcode. Es dämmerte mir nur, die Netzwerkoperationen zu fragen, ob sie etwas geändert haben, nachdem mir aufgefallen war, dass das Hinzufügen von Parens die Fehler verschob.
quelle
Ja, wenn 'und' und 'oder' gemischt sind.
Auch eine gute Idee, () was logischerweise eine Prüfung ist.
Am besten ist es jedoch, gut benannte Prädikatfunktionen zu verwenden und die meisten Überprüfungen und Bedingungen dort zu beseitigen, sofern dies einfach und lesbar ist.
quelle
a AND b
dass diese durch eine Funktion oder einen vorberechneten Boolen-Wert ersetzt werden sollte, der einen aussagekräftigeren Namen hat.Die Klammern sind semantisch redundant, daher ist es dem Compiler egal, aber das ist ein roter Faden - das Hauptanliegen ist die Lesbarkeit und das Verständnis der Programmierer.
Ich werde hier die radikale Position einnehmen und den Klammern in ein herzliches "Nein" geben
a AND b OR c AND d
. Jeder Programmierer sollte auswendig wissen, dass der Vorrang in Booleschen Ausdrücken NICHT> UND> ODER ist , genauso wie wenn er sich an Please Excuse My Dear Tante Sally für algebraische Ausdrücke erinnert. Redundante Interpunktion fügt dem Code nur die meiste Zeit visuelle Unordnung hinzu, ohne die Lesbarkeit des Programmierers zu beeinträchtigen.Wenn Sie in logischen und algebraischen Ausdrücken immer Klammern verwenden, geben Sie die Möglichkeit auf, sie als Marker für "Hier passiert etwas Schwieriges - achten Sie darauf!" Zu verwenden. Das heißt, in den Fällen, in denen Sie die Standardpriorität überschreiben und die Addition vor der Multiplikation oder ODER vor UND auswerten möchten , sind Klammern eine nette rote Fahne für den nächsten Programmierer. Zu viel Gebrauch von ihnen, wenn sie nicht gebraucht werden, und Sie werden der Junge, der Wolf weinte.
Ich würde eine Ausnahme für irgendetwas außerhalb des Bereichs der Algebra machen (Boolesche oder nicht), wie Zeigerausdrücke in C, wo alles, was komplizierter ist als Standard-Idiome wie
*p++
oderp = p->next
wahrscheinlich, in Klammern gesetzt werden sollte, um die Dereferenzierung und die Arithmetik aufrechtzuerhalten. Und natürlich gilt nichts davon für Sprachen wie Lisp, Forth oder Smalltalk, die eine Form der polnischen Notation für Ausdrücke verwenden. Für die meisten gängigen Sprachen sind die logischen und arithmetischen Prioritäten jedoch vollständig standardisiert.quelle
AND
vsOR
ist ein ziemlich grundlegender Fall, den ich den anderen Entwicklern in meinem Team mitteilen möchte. Ich mache mir Sorgen, dass manchmal "Verwenden von Klammern zur Verdeutlichung" wirklich "Verwenden von Klammern" ist, sodass ich mich nie die Mühe machen muss, den Vorrang zu erlernen "..member
vor unäre Operatoren, einstellige vor Binäroperatoren,*
und/
vor+
und-
vor<
und>
und==
vor&&
vor||
vor der Zuweisung. Diese Regeln sind leicht zu merken, da sie mit meinem "gesunden Menschenverstand" in Bezug auf die Verwendung der Operatoren übereinstimmen (z. B. wenn Sie keinen==
höheren Vorrang haben als+
oder nicht mehr1 + 1 == 2
funktionieren) und 95% der Vorrangfragen abdecken, die ich hätte .Wie ich es sehe:
JA Vorteile:
JA Nachteile:
KEINE Profis:
KEINE Nachteile:
quelle
3 * a^2 + 2 * b^2
leichter zu lesen als(3 * (a^2)) + (2 * (b^2))
, weil das Format und die Rangfolge bekannt und Standard sind. Ebenso könnten Sie (um extrem zu sein) die Verwendung von Funktionen und Makros (oder Compilern!) Verbieten, um die Semantik Ihres Codes deutlicher zu machen. Offensichtlich befürworte ich das nicht, aber ich hoffe, Ihre Frage zu beantworten, warum es Einschränkungen (ein Gleichgewicht) geben muss, um Dinge explizit zu machen.Wenn sich sonst niemand meinen Code noch einmal ansehen müsste, würde es mich nicht interessieren.
Aber aus meiner Erfahrung:
Ich mache das fast immer, weil ich meiner Fähigkeit vertraue, schnell zu lesen und mit Eltern nicht viel mehr kleine Fehler zu machen als mit nichts anderem.
In Ihrem Fall würde ich mit ziemlicher Sicherheit Folgendes tun:
Ja, es ist mehr Code. Ja, ich kann stattdessen ausgefallene Bool-Operatoren ausführen. Nein, ich mag die Chance nicht, wenn ich Code über 1 Jahr in der Zukunft überfliege. Ich habe ausgefallene Bool-Operatoren falsch verstanden. Was ist, wenn ich Code in einer Sprache schreibe, die eine andere AND / OR-Priorität hat, und zurückspringen muss, um dies zu beheben? Werde ich gehen, "aha! Ich erinnere mich an diese kluge Kleinigkeit, die ich getan habe! Ich musste keine Eltern mit einbeziehen, als ich letztes Jahr schrieb, gute Sache, an die ich mich jetzt erinnere!" wenn das passiert (oder schlimmer, jemand anderes, der sich dieser Klugheit nicht bewusst war oder in eine Situation vom Typ "Fix asap" gestürzt wurde)?
Das Trennen mit () macht es so viel einfacher, später schnell zu überfliegen und zu verstehen ...
quelle
ab = a AND b
?ab
ja nichts bleiben wenn nichta AND b
.Allgemeiner Fall
In C # haben Multiplikation und Division Vorrang vor Addition und Subtraktion.
StyleCop, ein Tool, das einen gemeinsamen Stil in der gesamten Codebasis erzwingt, mit dem zusätzlichen Ziel, das Risiko von Fehlern zu verringern, die durch Code verursacht werden, der möglicherweise nicht klar genug ist, hat die Regel SA1407 . Diese Regel erzeugt eine Warnung mit einem Code wie diesem:
Es ist klar, dass das Ergebnis ist
7
und nicht9
, aber StyleCop schlägt vor, Klammern zu setzen:Ihr besonderer Fall
In Ihrem speziellen Fall hat AND in der von Ihnen verwendeten Sprache Vorrang vor OR.
So verhält sich nicht jede Sprache. Viele andere behandeln UND und ODER gleich.
Als Entwickler, der hauptsächlich mit C # arbeitet, war meine erste Versuchung, zu bemerken, dass die beiden Ausdrücke nicht gleich sind, als ich Ihre Frage zum ersten Mal sah und den Code las, ohne das zu lesen, was Sie zuvor geschrieben haben. Hoffentlich habe ich die ganze Frage vor dem Kommentieren vollständig gelesen.
Diese Besonderheit und das Risiko, dass einige Entwickler glauben, AND und OR hätten die gleiche Priorität, machen das Hinzufügen von Klammern noch wichtiger.
Schreiben Sie keinen Code mit dem Ziel, zu zeigen, dass Sie schlau sind. Schreiben Sie Code mit dem Ziel der Lesbarkeit, auch von Personen, die möglicherweise nicht mit allen Aspekten der Sprache vertraut sind.
quelle
Wie bereits erwähnt, verwenden Sie Klammern immer dann, wenn der Ausdruck besser lesbar ist. Wenn der Ausdruck jedoch kompliziert ist, empfehle ich, neue Funktionen für die Unterausdrücke einzuführen .
quelle
Wenn Sie Sprache ausschließlich in Singular verwenden, vielleicht. Nehmen Sie jetzt alle Sprachen, die Sie kennen, von alt bis modern, vom Kompilieren über das Erstellen von Skripten über SQL bis hin zu Ihrem eigenen DSL, das Sie im letzten Monat erfunden haben.
Erinnern Sie sich an die genauen Vorrangregeln für jede dieser Sprachen, ohne nachzusehen?
quelle
"Soll ich in logischen Anweisungen Klammern verwenden, auch wenn dies nicht erforderlich ist?"
Ja, denn zwei Personen werden sie hilfreich finden:
Der nächste Programmierer, dessen Wissen, Kompetenz oder Stil unterschiedlich sein kann
Die Zukunft, die Sie zu einem späteren Zeitpunkt zu diesem Code zurückkehren!
quelle
Komplexe Bedingungen sind "Boolesche Algebra", die Sie in gewisser Weise so schreiben, dass sie ziemlich genau wie Algebra aussehen, und Sie würden definitiv Parens für Algebra verwenden , nicht wahr?
Die wirklich nützlichen Regeln sind die Negationsregeln:
Oder in einem etwas klareren Format:
Das ist wirklich klar, nur Algebra, wenn geschrieben wird als:
Wir können aber auch das Denken für die algebraische Vereinfachung und Erweiterung anwenden:
obwohl im Code muss man schreiben:
oder in einem etwas klareren Format:
Grundsätzlich ist eine Bedingung immer noch nur ein algebraischer Ausdruck, und durch die eindeutige Verwendung von Klammern können Sie die verschiedenen bereits bekannten algebraischen Regeln, einschließlich des alten Konzepts "Diese Formel vereinfachen oder erweitern", einfacher auf den Ausdruck anwenden.
quelle
!(A + B) <=> !A + !B
und-1*(A + B) = -A + -B
hätte der Operator nicht im zweiten Ausdruck von+
nach umgedreht werden sollen*
?Ich werde Klammern verwenden, auch wenn dies optional ist, warum, weil dies zum besseren Verständnis für alle beiträgt, sowohl für diejenigen, die den Code schreiben, als auch für diejenigen, die bereit sind, diesen Code zu sehen. In Ihrem Fall haben sogar die booleschen Operatoren Vorrang, es könnte zunächst gut funktionieren, aber wir können nicht sagen, dass es Ihnen in jedem Fall helfen wird. Daher bevorzuge ich es, Klammern zu verwenden, wenn dies erforderlich oder optional ist.
quelle
Ja. Sie sollten auf jeden Fall verwenden, wenn Sie der Meinung sind, dass Ihr Code klarer wird. Denken Sie daran, dass Ihr Code klar genug sein sollte, damit andere ihn verstehen können, ohne Ihre Kommentare im Code zu lesen. Es ist daher eine gute Praxis, Klammern und Klammern zu verwenden. Denken Sie auch daran, dass dies möglicherweise von der jeweiligen Praxis Ihres Unternehmens / Teams abhängt. Behalten Sie einfach einen Ansatz bei und mischen Sie nicht.
quelle