Ist i, j = 1 wirklich irreführend? [geschlossen]


11

Es gibt ein allgemeines Argument für die Initialisierung mehrerer Variablen in einem Einzeiler, nämlich:

Betrachten Sie zum Beispiel int i, j = 1; Dies könnte dazu führen, dass einige Leute fälschlicherweise glauben, dass beide Variablen initialisiert werden

Wir könnten argumentieren, dass jemand die Syntax seiner Sprache genug kennen sollte, um sich nicht zu irren. Ein weiteres Argument könnte sein, dass wir als Entwickler so viele Sprachen lernen, dass wir Fehler zwischen den Besonderheiten zwischen den Sprachen machen können.

Für diesen speziellen Fall frage ich mich jedoch, ob es überhaupt eine Sprache gibt, in der die Syntax i, j = 1 beide Variablen initialisiert.

Wenn nicht, trifft dieses Argument nicht zu.


2
Wenn Ihre Sprache vernünftig ist, ist die potenzielle Verwirrung harmlos, da der Zugriff auf eine nicht initialisierte Variable einen Compilerfehler auslöst.
CodesInChaos

4
@CodesInChaos sagst du, C ist nicht gesund?
Baldrickk

2
Nur weil eine Sprache etwas erlaubt, heißt das nicht, dass Sie den Menschen keine unnötigen Schmerzen bereiten. Der einzige Ort, an dem dieser Code benötigt wird, sind Quizfragen, mit denen diejenigen bestraft werden sollen, die sich die Sprachspezifikation nicht gemerkt haben. Ich habe diese Art von Fragen immer nicht beantwortet. Bleh.
candied_orange

2
In Visual Basic 6 Dim Apple, Orange, Pear as Fruitist eine rechtliche Erklärung. Angenommen, Sie kennen VB nicht. Ist Ihr erster Eindruck Applevom Typ Fruit? Es ist nicht. Denken Sie daran, dass Sprachen häufig von Personen gelesen werden, die keine Experten für diese Sprache sind. Wenn Sie ein Experte sind, verwenden Sie die Sprache mit Bedacht, um Ihre Absichten auch Nicht-Experten klar mitzuteilen. Ich verwende niemals mehrere Initialisierungen in einer Sprache.
Eric Lippert

13
Ähnlich: Überlegen Sie: var x = 1, y = 1.5; Ist dies dasselbe wie int x = 1; double y = 1.5;oder ist es dasselbe wie double x = 1, y = 1.5;? Als wir varC # 3.0 hinzufügten , führte ich eine Umfrage durch und stellte fest, dass ungefähr die Hälfte der Leute glaubte, dass die erste "offensichtlich" korrekt war und die andere Hälfte glaubte, dass die andere "offensichtlich" korrekt war, und so machten wir es illegal. Ein Merkmal, das die Hälfte der Bevölkerung völlig irreführt, ist ein schlechtes Merkmal.
Eric Lippert

Antworten:


37

Ich denke nicht, aber das ist nicht der Punkt. Der Punkt ist , dass i, j = 0ist sehr leicht verwechselt i = j = 0, was tut beide initialize. Klarheit ist neben Korrektheit die wichtigste Anforderung an den Quellcode, und die Tatsache, dass diese Frage sogar auftaucht, zeigt, dass die Klarheit nicht optimal ist.


3
Ich würde auch argumentieren, dass wenn eine solche Aussage nicht beide Aussagen initialisiert, warum sie überhaupt existiert?
Berin Loritsch

2
@BerinLoritsch hängt von der Sprache ab. Dies geschieht häufig in JavaScript aufgrund des Anhebens von Deklarationen: Viele halten es für eine bewährte Methode, Variablen am oberen Rand des Bereichs zu deklarieren, in dem sie verfügbar sind, auch wenn Sie sie erst an der Stelle initialisieren, an der sie im Code verwendet werden . Fast alle Code-Transformationstools werden auf diese Weise ausgegeben.
Jared Smith

1
Ich nehme an, es ist eine Sache, wenn ein Code-Ausgabe-Tool dies tut, da dem vertraut werden soll. Für Menschen würde ich jedoch empfehlen, Deklaration und Initialisierung des letzten Elements nur in einer Zeile zu kombinieren. Es sieht aus wie ein Fehler, der darauf wartet, passiert zu werden.
Berin Loritsch

2
@JaredSmith Neben Maple kann ich mir keine Sprache vorstellen, in der dies derzeit erwünscht ist. Selbst C bevorzugt jetzt einen näheren Bereich (wie C ++ und die meisten anderen Sprachen mit halbwegs anständigen statischen Compilern), da dies den Vorteil bietet, potenzielle Fehler zu stoppen und zuzulassen Der Compiler entscheidet, was mit der Variablen geschehen soll, solange sich die Funktionalität nicht ändert. Dies ermöglicht möglicherweise bessere Optimierungen, da Sie mit weniger Registern davonkommen könnten.
Am

6
Unabhängig von der Sprache sollte man fragen: "Was ist der Vorteil des Schreibens int i, j=1gegenüber int i; int j = 1(oder noch besser, getrennten Zeilen)?"
Chepner

2

Ich denke, Sie können für beide Seiten argumentieren:

  • Kontra i, j = 0:
    Mathematiker verwenden dies, um zu bedeuten, dass beide iund jNull sein sollen.

  • Pro i, j = 0:
    Es ist ganz einfach, den Vorrang Ihrer Bediener zu kennen. Und wenn Sie Zweifel an ihrem Vorrang haben, ist es jetzt an der Zeit, nachzuschlagen.

    Es ist der gleiche Grund, warum wir Dinge wie a.b += c[i]*d[i];ohne Klammern schreiben . Dies ist natürlich gleichbedeutend mit (a.b) += ((c[i])*(d[i]));, aber von Programmierern kann erwartet werden, dass sie die Priorität der am häufigsten verwendeten Operatoren auswendig können und die Priorität von Operatoren nachschlagen können, wenn sie sich nicht sicher sind. Daher werden Klammern im Allgemeinen als nutzlose Unordnung angesehen, es sei denn, sie erzwingen eine andere Bewertungsreihenfolge, als es die Priorität des Bedieners vorschreiben würde.

    Natürlich gibt es Ausnahmen. Der Vorrang von <<und +wird in beiden Fällen im Allgemeinen als mehrdeutig genug angesehen, um Klammern zu warnen. Aber das ist die Ausnahme, die die Regel bestätigt.

Zum einen würde ich eher auf die Pro-Seite fallen, aber ich bin bereit, mich an jeden Styleguide zu halten, der solche Erklärungen verbietet. Es lohnt sich einfach nicht, darüber zu streiten.


7
Ich stelle fest, dass int i, j = 0;keine Operatoren darin sind. Der einzige Ausdruck in dieser Anweisung ist, 0und daher kommt die Operatorpriorität nicht dazu. Der Parser behandelt nicht ,als Kommaoperator oder =als Zuweisungsoperator. Vielmehr sind dies grammatikalische Teile der Deklarationserklärung.
Eric Lippert

@EricLippert In Bezug auf Prioritätsregeln ist dieser Unterschied irrelevant: Jede mir bekannte Sprache im C-Stil verwendet in einer Deklaration dieselben Prioritäten wie in anderen Ausdrücken. Alles andere würde zu einer Katastrophe führen.
cmaster - wieder Monica

but programmers can be expected to know the precedence of the most used operators by heart, du sagst. In dem Beispiel, das Sie geben, bin ich mir nicht sicher, ob die meisten (durchschnittlichen) Programmierer den Elementzugriffsoperator oder den Arrayindexoperator überhaupt als Operatoren im mathematischen Sinne verstehen, sondern sie eher als Substantive in natürlicher Sprache und als Multiplikation betrachten Operator als Verb. Deshalb int i, j, k = 0;ist es so ein teuflisches Konstrukt, weil es als natürliches Sprachanalog von "int Variablen i, j und k werden deklariert und sollen auf 0 gesetzt werden" darstellt!
Steve

@Steve Wie Sie sich als Programmierer an die Vorrangregeln erinnern, liegt ganz bei Ihnen. Wenn es Ihnen hilft, sie als Substantive der Sprache zu betrachten, tun Sie es. In diesem Fall werden Sie jedoch auf Probleme stoßen *a[i], wenn Sie Dinge wie sehen . Ich glaube nicht, dass Sie dies mit der Analogie "Substantive" ausreichend analysieren können. Was int i, j, k = 0;, das könnte alles bedeuten , wenn Sie die Regeln nicht sehen: Eine dritte Interpretation zu erklären wäre int i, dann auswerten jund schließlich assign k = 0. Wenn Sie die Syntax Ihrer Sprache nicht kennen, können Sie solche Konstrukte nicht analysieren. Es ist dein Problem, wenn du es trotzdem tust.
cmaster - wieder herstellen Monica

@cmaster, ich habe meine spezifische Strategie zum Auswendiglernen nicht zum Ausdruck gebracht, haha. Ich bin kein C-Programmierer, daher ist meine Vertrautheit mit der Priorität von Operatoren in C zweitklassig. Als ich mir Ihr Beispiel ansah, stellte ich jedoch fest, dass ich den Multiplikationsoperator nicht einmal als relativ vorrangig gegenüber dem Array-Indexoperator angesehen habe. Das heißt, ich habe nicht a[i]als Indexoperator gelesen , auf den angewendet wurde a, sondern beide zusammen als irreduzibles syntaktisches Element gelesen, das den Operanden des Multiplikationsoperators angibt, und daher wurde ich nicht einmal aufgefordert, die Priorität zu bewerten. (1/2)
Steve
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.