Sollte ich in logischen Anweisungen Klammern verwenden, auch wenn dies nicht erforderlich ist?

100

Angenommen, ich habe eine boolesche Bedingung a AND b OR c AND dund verwende eine Sprache, bei ANDder 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?

Jeff Bridgman
quelle
90
Ich mag faul sein, aber ich bevorzuge es, Klammern in den meisten solchen Situationen zu haben, um die Lesbarkeit zu verbessern.
thorsten müller
6
Ich auch. Ich hoffe nur, dass ich es mehr aus Gründen der Lesbarkeit und weniger mache, weil ich zu faul bin, um mich mit den Grundlagen meiner Sprache vertraut zu machen.
Jeff Bridgman
16
Eine gute Verwendung von Klammern ist wie eine gute Verwendung von Grammatik. 2 * 3 + 2ist vielleicht dasselbe wie, (2 * 3) + 2aber die zweite ist leichter zu lesen.
Reactgular
16
@ Mathew Vielleicht, wenn Sie in Mathe schwach sind. Verwenden Sie für komplexere Fälle Klammern. Aber für blindlings offensichtliche (BODMAS…) verringern sie die Lesbarkeit mehr, als sie aufgrund von Unordnung zu unterstützen.
Konrad Rudolph
3
Das heißt, die gleiche Priorität von AND / OR gilt für Basic, Python, SQL ... Mein Eindruck ist, dass dies in der überwiegenden Mehrheit der modernen Sprachen der Fall ist (wenn auch nicht in allen).
Tim Goodman

Antworten:

117

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:

  • Sie reduzieren den Arbeitsaufwand zum Verstehen des Codes.
  • Sie bestätigen die Absicht des Entwicklers.

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 andund kombinieren or(und auch für arithmetische Operationen mit ähnlichen Prioritätsproblemen).

user82096
quelle
3
Obwohl ich gehört habe, dass es sich bei Kommentaren um Entschuldigungen handelt (für schlechten / schwer lesbaren Code) ... besteht die gute Chance, dass Sie es besser hätten schreiben können. Ich denke, man könnte ähnliche Dinge über Klammern sagen.
Jeff Bridgman
6
Ein weiterer Aspekt der Korrektheit besteht darin, sie durch Änderungen beizubehalten: Während der ursprüngliche Entwickler möglicherweise ohne Klammern Vorrang hat, wenn er den Code zum ersten Mal mit dem Ziel und Kontext neu schreibt, kommt er (oder ein anderer) später dazu und merkt sich nicht alles Die Details können es vermasseln, wenn sie dem Ausdruck weitere Ausdrücke hinzufügen. (Das war größtenteils schon impliziert, aber ich hatte das Gefühl, dass es sich lohnt, es hervorzuheben.)
LarsH
1
@ LarsH, danke, ich habe dies explizit zur Antwort hinzugefügt.
8
+1 "Sie bestätigen die Absicht des Entwicklers." - Jeder Programmierer (OK, vielleicht nicht alle, aber alle, die sich hier befinden ...) kann herausfinden, was der Compiler mit der komplexesten Logik machen wird. Absolut niemand kann herausfinden, was der ursprüngliche Entwickler bestimmt sind (einschließlich sich selbst) ein paar Wochen auf der Spur für etwas jenseits der einfachsten .....
mattnz
2
Ich denke, @ JeffBridgman bezog sich auf einen ziemlich bekannten Standpunkt von "Kommentare können manchmal ein Code-Geruch sein". Siehe z. B. Jeff Atwoods Zusammenfassung mit der Frage "Können Sie den Code umgestalten, damit die Kommentare nicht erforderlich sind?". Ich würde behaupten, wenn Ihr Kommentar erklärt, warum Ihr Code so verdammt unintuitiv ist, kann dies definitiv ein Hinweis darauf sein, dass etwas nicht stimmt. In solchen Situationen ist es eine gute Idee, den Code zu vereinfachen. Ich stimme Ihrer tatsächlichen Antwort jedoch voll und ganz zu und übernehme jedoch Klammern.
Daniel B
94

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.

Dan Pichelman
quelle
72
Vergiss das nicht, auch wenn du ein Solo-Entwickler bist, wenn du krank, müde oder mit Code umgehst, den du letztes Jahr geschrieben hast. Ihr Verständnisniveau ist auf das eines n00b reduziert.
Dan Neely
30
There is such a thing as too many parenthesis- Sie sind offensichtlich kein lisper;)
Paul
18
Das ist ein schlechter Rat: Schreiben Sie nicht für Noobs. Dies verringert Ihre Codequalität (erheblich), da Sie keine gängigen Redewendungen verwenden können, die über die ersten beiden Kapitel eines Anfängerbuchs hinausgehen.
Konrad Rudolph
10
@KonradRudolph: Vielleicht ist es so, aber schreibe nicht für die Einzigen, die die Kunst der Computerprogrammierung von Anfang bis Ende kennen, oder sei bereit, ihren Code nachträglich zu debuggen und keine Ahnung zu haben, warum du die Dinge so gemacht hast . Code wird viel mehr gelesen als geschrieben.
Haylem
15
@dodgethesteamroller: Ich habe viel zu viele kompetente / angesehene Entwickler gesehen, die Vorrang-Bugs eingeführt haben (jeder hat ab und zu einen schlechten Tag), die ewig unbemerkt bleiben. Für gute Entwickler, die die Vorrangregeln kennen, ist das Risiko von unentdeckten Fehlern / Tippfehlern zu hoch. Für alle anderen ist das Risiko höher. Die besten Entwickler sind die Entwickler, die sich die Vorrangregeln der Sprache merken, diese aber vergessen haben, weil sie gewöhnlich Klammern für nicht offensichtliche Dinge verwenden.
Brendan
31

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 ANDund ORes nicht klar erkennbar war, welche Daten ANDbearbeitet wurden und welche Daten ORbearbeitet wurden. Also fing ich an, Klammern um die Bedingungen ANDund ORzu 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 ANDund ORBedingungen 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 ANDund ORnicht aufgelöst werden konnte.

Daraus habe ich gelernt ... IMMER, IMMER, IMMER benutze ich Parens, um ANDBedingungen und ORZustä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.

Michael Riley - AKA Gunny
quelle
22
Das scheint ein besseres Beispiel dafür zu sein, warum es wichtig ist, einen guten Compiler zu haben.
Ruakh
6
@CapeCodGunny: Ich bin sicher, du hast es nicht getan. Das Problem hierbei ist jedoch, dass Sie einen schlechten Compiler-Anbieter hatten, der eine wichtige Änderung vorgenommen hat. Ich verstehe nicht, wie Sie gelernt haben, "IMMER IMMER IMMER" dieses Problem zu umgehen, selbst wenn Sie bessere Compiler verwenden.
Ruakh
5
@ruakh - Nein, der Anbieter hat einfach seinen Code-Parser geändert. Ich bin altmodisch und verlasse mich nicht auf meine Fähigkeit, mich an jedes System zu erinnern, an dem ich programmiert habe oder an dem ich beteiligt war. Ohne Dokumentation ist alles, was Sie haben, der Quellcode. Wenn der Quellcode schwer zu lesen und zu befolgen ist, entsteht eine äußerst stressige Situation. Programmierer, die kein Leerzeichen verwenden, mussten sich wahrscheinlich noch nie mit einer Situation wie der, mit der ich konfrontiert war, auseinandersetzen. Ich habe auch gelernt, dass es sinnvoller ist, Code zu schreiben wie: Siehe Dick; Siehe Jane; Siehe Dick und Jane; Einfache Aussagen, die einfach zu lesen sind ... auskommentieren ... und folgen.
Michael Riley - AKA Gunny
2
Tolle Geschichte, aber ich stimme zu, dass es kein Grund ist, Klammern zu verwenden. und / oder der Vorrang ist nahezu universell und es ist unwahrscheinlich, dass sich etwas ändert, was man sich vorstellen kann. Wenn Sie sich bei einer solchen Standardoperation nicht auf ein konsistentes Verhalten verlassen können, ist Ihr Compiler Müll und Sie werden abgespritzt, egal was Sie tun. Ihre Story ist zu 100% ein Compiler-Problem und zu 0% ein Code-Problem. Insbesondere angesichts der Tatsache, dass das Standardverhalten eine einfache Bewertung von links nach rechts war - die Reihenfolge war immer klar. Warum sollte also jemand Klammern verwenden?
7
Ich denke, hier werden auf beiden Seiten Lehren gezogen ... Sie sollten Klammern besser verwenden, insbesondere wenn sich die Alternative auf das undokumentierte Verhalten eines Compilers in Bezug auf mehrdeutigen Code stützt . Und wenn der Programmierer nicht weiß, welche Ausdrücke mehrdeutig sind, sollten Sie lieber parens verwenden. Andererseits ist es gefährlich, das Verhalten eines Compilers zu ändern, aber es hat zumindest einen Fehler ausgelöst, wenn sich das Verhalten geändert hat. Es wäre schlimmer gewesen, wenn der Compiler keinen Fehler ausgegeben hätte, sondern anders zu kompilieren begonnen hätte. Der Fehler hat Sie vor unbemerkten Fehlern geschützt.
LarsH
18

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.

Balog Pal
quelle
6
Es stimmt, es besteht eine sehr gute Chance, a AND bdass diese durch eine Funktion oder einen vorberechneten Boolen-Wert ersetzt werden sollte, der einen aussagekräftigeren Namen hat.
Jeff Bridgman,
14

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++oder p = p->nextwahrscheinlich, 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.

dodgethesteamroller
quelle
1
+1, Klammern für Klarheit sind in Ordnung, aber ANDvs ORist 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 ".
Tim Goodman
1
In allen Sprachen , die mich mit regelmäßig arbeiten ist es .membervor 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 mehr 1 + 1 == 2funktionieren) und 95% der Vorrangfragen abdecken, die ich hätte .
Tim Goodman
4
@ TimGoodman Ja, genau richtig, zu beiden deinen Kommentaren. Andere Antwortende hier scheinen zu denken, dass es sich um eine Schwarz- oder Weißfrage handelt - verwenden Sie entweder die ganze Zeit Klammern, ohne Ausnahmen, oder fliegen Sie sorglos durch den Sitz Ihrer Hose durch ein Meer von willkürlichen und nicht zu merkenden Regeln, wobei Ihr Code überfließt mit potenziell schwer zu entdeckenden Fehlern. (Gemischte Metaphern sehr absichtlich.) Offensichtlich ist der richtige Weg Mäßigung; Die Klarheit des Codes ist wichtig, aber auch die Kenntnis Ihrer Tools. Sie sollten in der Lage sein, von Ihren Teamkollegen ein gewisses Mindestverständnis für Programmier- und CS-Prinzipien zu erwarten.
dodgethesteamroller
8

Wie ich es sehe:

JA Vorteile:

  • Die Reihenfolge der Operationen ist explizit.
  • Schützt Sie vor zukünftigen Entwicklern, die die Reihenfolge der Vorgänge nicht verstehen.

JA Nachteile:

  • Kann zu überladenem, schwer lesbarem Code führen

KEINE Profis:

  • ?

KEINE Nachteile:

  • Die Reihenfolge der Operationen ist implizit
  • Code ist für Entwickler ohne ein gutes Verständnis der Betriebsreihenfolge weniger wartbar.
MetaFight
quelle
Gut gesagt, obwohl ich denke, "Kann zu überladenem, schwer lesbarem Code führen" ist eher subjektiv.
FrustratedWithFormsDesigner
2
Wie erschwert die explizite Semantik Ihres Codes das Lesen?
Mason Wheeler
1
Ich bin mit den anderen einverstanden, wenn ich Ihre "Ja-Nachteile" in Frage stelle. Ich denke, es ist fast immer das Gegenteil.
@Frustriert So subjektiv wie der gegenteilige Anspruch. Das heißt, überhaupt nicht wirklich. Einfach schwer zu messen.
Konrad Rudolph
1
@MasonWheeler: Obwohl ich der Meinung bin, dass explizite Parens in vielen Fällen sehr wichtig sind, kann ich sehen, wie man die Semantik explizit über Bord werfen kann. Ich finde es 3 * a^2 + 2 * b^2leichter 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.
LarsH
3

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?

Wenn sich sonst niemand meinen Code noch einmal ansehen müsste, würde es mich nicht interessieren.

Aber aus meiner Erfahrung:

  • Ich schaue gelegentlich wieder auf meinen Code (manchmal Jahre nachdem ich ihn geschrieben habe)
  • Andere schauen sich manchmal meinen Code an
    • Oder müssen es sogar erweitern / reparieren!
  • Weder ich noch der andere können sich genau daran erinnern, was ich beim Schreiben gedacht habe
  • Das Schreiben eines kryptischen Codes zur Minimierung der Zeichenanzahl beeinträchtigt die Lesbarkeit

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:

if (a AND b) then ab = true
if (c AND d) then cd = true
If (ab OR cd) Then ...

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 ...

Enderland
quelle
7
Wenn du das machst, warum nicht ab = a AND b?
Eric
1
Vielleicht soll da abja nichts bleiben wenn nicht a AND b.
Armali,
3

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:

var a = 1 + 2 * 3;

Es ist klar, dass das Ergebnis ist 7und nicht 9, aber StyleCop schlägt vor, Klammern zu setzen:

var a = 1 + (2 * 3);

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.

Arseni Mourzenko
quelle
1
"Das ist sehr ungewöhnlich": Laut Stroustrup2013 scheint C ++ 11 eine unterschiedliche Priorität von UND und ODER zu haben (S. 257). Gleiches gilt für Python: docs.python.org/2/reference/expressions.html
Dirk
10
Betreff: "Jede Sprache, die ich kenne, behandelt UND und ODER gleich": Ich bezweifle, dass das wahr ist. Wenn es ist wahr, dann wissen Sie nicht , jeder von den zehn beliebtestenen Sprachen (C, Java, C ++, PHP, JavaScript, Python, C #, Perl, SQL, und Ruby) und sind nicht in der Lage sein zu kommentieren Was ist "ungewöhnlich", geschweige denn "sehr ungewöhnlich".
Ruakh
1
Ich stimme Ruakh zu und habe nach C ++ 11, Python, Matlab und Java gesucht.
Dirk
3
Sprachen, in denen AND und OR binäre Operatoren sind und in denen AND keine höhere Priorität hat als OR, sind hirngeschädigte Scheiße, deren Autoren Informatikfreaks sind. Dies kommt von der logischen Notation. Hallo, bedeutet "Summe der Produkte" nichts? Es gibt sogar eine Boolesche Notation, die Multiplikation (Nebeneinanderstellung von Faktoren) für AND und das + Symbol für OR verwendet.
Kaz
3
@ruakh Du hast gerade mein Argument für mich gemacht. Weil es eine Handvoll pathologischer Randfälle gibt, heißt das nicht, dass Sie nicht die boolesche Vorrangstellung erlernen sollten und davon ausgehen, dass sie gilt, bis das Gegenteil bewiesen ist. Wir sprechen hier nicht über willkürliche Entwurfsentscheidungen. Die Boolesche Algebra wurde lange vor dem Computer erfunden. Zeigen Sie mir auch die Pascal-Spezifikation, über die Sie sprechen. Hier und hier zeigen UND vor ODER.
dodgethesteamroller
1

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 .

Honza Brabec
quelle
0

Oder ist es ein Zeichen dafür, dass sich ein Entwickler wirklich hinsetzen und sich auf die Grundlagen seiner Sprache verlassen muss?

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?

Sichern
quelle
1
Und wie @Cape Cod Gunny oben erwähnt hat, kann sich die Compiler- / Laufzeitzeit unter Ihnen ändern, selbst wenn Sie glauben, die Sprache zu kennen.
Jordanien
0

"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!

Michael Durrant
quelle
-1

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:

!(A || B) <=> !A && !B
!(A && B) <=> !A || !B

Oder in einem etwas klareren Format:

!(A + B) <=> !A * !B
!(A * B) <=> !A + !B

Das ist wirklich klar, nur Algebra, wenn geschrieben wird als:

-1*(A + B) = -A + -B
-1*(A * B) = -A * -B

Wir können aber auch das Denken für die algebraische Vereinfachung und Erweiterung anwenden:

(A && B) || (C && D) => 
((A && B) || C) && ((A && B) || D) => 
(AC && BC) && (AD && BD) =>
AC && BC && AD && BD

obwohl im Code muss man schreiben:

(A||C) && (B||C) && (A||D) && (B||D)

oder in einem etwas klareren Format:

(A + B) * (C + D) => 
((A + B) * C) + ((A + B) * D) => 
(AC + BC) + (AD + BD) =>
AC + BC + AD + BD

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.

Narfanator
quelle
2
Ich bin mir nicht sicher, ob Sie die Frage tatsächlich beantworten, da Sie Ihre Antwort mit einer Annahme führen, die nicht unbedingt wahr ist. Würde ich für die Algebra Klammern verwenden? Nicht die ganze Zeit. Wenn es mit der Lesbarkeit hilft, dann sicherlich, aber andere haben das hier bereits zum Ausdruck gebracht. Und das Erweitern der mathematischen Algebra in andere Formen hat nicht unbedingt eine Eins-zu-Eins-Entsprechung zur Programmierung - was ist, wenn Sie den Status einiger Zeichenfolgenwerte überprüfen?
Derek
Wenn die zugehörige Boolesche Algebra kompliziert genug ist, um die Verwendung von Parens zu rechtfertigen, sollten Sie als Bedingung wahrscheinlich Parens verwenden. Wenn es einfach genug ist, keine Parens zu rechtfertigen, müssen Sie das entweder nicht oder sollten es nicht. In beiden Fällen ist das Problem wahrscheinlich klarer, wenn Sie es wie einen mathematischen Ausdruck betrachten.
Narfanator
Meine obigen Beispiele verwenden zwei und vier Boolesche Werte. Wenn Sie den Status von zwei oder mehr Zeichenfolgenwerten überprüfen, wird dies zugeordnet. Jede Prüfung entspricht einer booleschen Variablen. unabhängig davon, ob diese Prüfung eine Ganzzahl oder eine Zeichenkettengleichheit ist; String-, Array- oder Hash-Aufnahme; ein komplexer Ausdruck selbst ... Egal; Alles, was zählt, ist, dass Sie mehr als eine Messung von wahr / falsch in Ihrem Ausdruck haben.
Narfanator
2
Nur ein bisschen picken, aber rein !(A + B) <=> !A + !Bund -1*(A + B) = -A + -Bhätte der Operator nicht im zweiten Ausdruck von +nach umgedreht werden sollen *?
Jeff Bridgman
-1

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.

singa selva sankar
quelle
-1

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.

DeveloperArnab
quelle