Warum ist (Position <Größe) ein so weit verbreitetes Muster in Bedingungen?

9

In einer Bedingungsanweisung (IF) verwendet jeder (position < size), aber warum?
Nur Konvention oder gibt es einen guten Grund dafür?

In freier Wildbahn gefunden:

if (pos < array.length) {
   // do some with array[pos];
}

Selten gefunden:

if (array.length > pos) {
   // do some with array[pos];
}
Felipe
quelle
7
Ein Fall, in dem es mir nichts ausmacht, die "Variable" rechts zu haben, ist if (MIN <= x && x <= MAX). (In einigen Sprachen kann dies wie MIN <= x <= MAXfolgt geschrieben werden: In C ist es vollkommen legal, bedeutet aber nicht, was Sie vielleicht denken, dass es bedeutet).
Keith Thompson
5
Könnte damit zusammenhängen, wie Intervalle geschrieben werden [min, max]und nicht [max, min]. Daher ist es nur natürlich zu überprüfen, ob ein Element xzum Intervall gehört, indem Sie schreiben min <= x <= max.
Andres F.
Was für ein Trottel.
Tulains Córdova
Das zweite Beispiel kann weiter geklärt werden, als ob (! (Array.lengh <= pos)) ...
OldFart

Antworten:

48

Das tiefere Muster ist, dass wir natürlich "[etwas, das variiert] [Vergleich] [etwas, das nicht variiert]" als Standardreihenfolge verwenden. Dieses Prinzip gilt für Ihr Beispiel, da die Position variieren kann, die Größe jedoch nicht.

Die einzige häufige Ausnahme besteht darin, dass sich einige Programmierer beim Testen auf Gleichheit darin üben, die entgegengesetzte Reihenfolge (als Yoda-Bedingungen bezeichnet ) zu verwenden, um das Gemeinsame variable = constantund nicht den variable == constantFehler zu vermeiden. Ich halte an dieser Idee nicht fest, weil ich die beschriebene natürliche Reihenfolge finde oben viel besser lesbar, vor allem, weil wir die Idee so auf Englisch ausdrücken und weil die meisten modernen Compiler dies erkennen und eine Warnung ausgeben.

Jules
quelle
3
Abhängig von Ihren Entwicklungstools werden viele auch vor dem variable = constantKonstrukt warnen (oder Fehler machen) .
GalacticCowboy
5
+1. Suchen Sie in "Yoda Conditions" nach weiteren Details zu diesem constant == variablePhänomen.
John M Gant
Ich habe dasselbe kürzlich in meiner eigenen Codebasis gesehen (z. B. if(DBNull == row["fieldName"]) methodCall()und mich gefragt, ob ich verrückt geworden bin, weil ich es die meiste Zeit umgekehrt gesehen habe.
Andrew Gray
1
Ich würde auch hinzufügen, dass dies (position < size)oft eine Obergrenze ausdrückt, so dass es tatsächlich einen Teil von neu formuliert lowerbound <= position < upperbound, wobei die Größe die Obergrenze ist. Wenn die beiden Einschränkungen explizit sind, positionkann die nur in die Mitte gehen.
Steve314
4
Es hängt wahrscheinlich mit der Sprache zusammen; Wir analysieren " X-Operator Y " als " X ist ( Operator Y )", so wie die Beziehung ein Merkmal von X ist . Wenn wir nach dem Vergleich fragen, fragen wir, ob X einen guten oder einen schlechten Wert hat (und Y lokal als Konstante behandelt wird). Wenn Sie nach "pos <array.length" fragen, möchten Sie fragen: "Ist die Position in Ordnung (kleiner als die Array-Länge)?" Wenn nein, stimmt etwas mit der Position nicht. Geben Sie mir eine andere Position, und ich würde gerne tun, was Sie wollten. An der Array-Länge ist jedoch nichts auszusetzen. Wenn Sie nach "array.length> pos" fragen, sollten Sie das Array vergrößern, wenn es zu kurz ist.
14

Die einzige Rechtfertigung, die ich jemals dafür gesehen habe, ist, dass es wie Zahlenlinien oder andere Ordnungssachen ist, die wir in der Schule gelernt haben. Zum Beispiel schreiben wir Zahlenzeilen wie folgt:

<--|--|--|--|--|--|-->
   1  2  3  4  5  6

Die kleineren Dinge erscheinen links von größeren Dingen. Gleiches gilt für andere Dinge wie Daten (denken Sie daran, wie ein Kalender aufgebaut ist).

Es läuft im Grunde darauf hinaus, wie wir natürlich über die Reihenfolge der Dinge denken. Es ist einfacher, das erste Formular zu lesen, da Sie nicht viel mentale Bearbeitung daran vornehmen müssen.

Becuzz
quelle
1
Sie meinen, der Ausdruck, der den kleineren Wert ergibt, steht in der Bedingung an erster Stelle? Wie können Sie sicher sein, dass dies zutrifft, wenn Werte eine Laufzeit ändern?
Tulains Córdova
@ user61852 Sie müssen nicht wissen, welche Werte zur Laufzeit vorliegen. Beispiel: Ich habe 2 Werte, die ich zur Laufzeit mit Wert A und Wert B berechne, und ich möchte testen, ob Wert A kleiner als Wert B ist. Ich würde "if (valueA <valueB)" schreiben. Ob Wert A kleiner als Wert B ist, ist unerheblich. Es ist (zumindest für mich) einfacher, sich das anzusehen und zu wissen, dass ich suche, wenn valueA kleiner als valueB ist. Wenn ich "if (valueB> valueA)" sehen möchte, muss ich innehalten und darüber nachdenken, welches Ding das kleinere ist, wenn ich diesem Codezweig folgen will.
Becuzz
1
Ich missverstand. Ich habe die Antwort abgelehnt. Jetzt möchte ich darüber abstimmen, aber die Site verlangt, dass die Antwort bearbeitet wird, damit ich meine Stimme ändern kann. Bitte nehmen Sie einige Änderungen vor, damit ich darüber abstimmen kann.
Tulains Córdova
@ user61852 Sie sollten jetzt in der Lage sein, Ihre Stimme zu ändern.
Becuzz
11

Obwohl es hauptsächlich eine Frage der Konvention ist, ist dies meiner Meinung nach am besten so, wie wir denken - es zeigt den Punkt, auf den wir Wert legen.

Wenn wir diese ins Englische übersetzen, wäre dies der Ausdruck "Wenn die Position kleiner als die Array-Länge ist", wobei das Thema des Satzes das vorübergehende Element ist.

Um es anders auszudrücken: "Wenn die Array-Länge größer als die Position ist", wird die Array-Länge (als fester Wert angenommen) in das Subjekt eingefügt und die Position (vorübergehend) wird zum direkten Objekt.

GalacticCowboy
quelle
3
Tatsächlich (in Ihrem letzten Satz) wird die Position zum Objekt einer Präposition. Aber ich stimme dem zu, was Sie sagen wollen. In der Linguistik würden wir sagen, dass Position das Thema ist und "weniger als Array-Länge" der Kommentar ist . "Die Tendenz, topikalisierte Bestandteile zunächst zu setzen (Themenfront), ist weit verbreitet." en.wikipedia.org/wiki/…
LarsH
4

Meine Meinung, und dies ist nur meine Meinung, ist, dass es eine Konvention für Lesbarkeit ist. Obwohl die beiden identisch sind, fühlen sie sich in meinem Gehirn unterschiedlich an. Ich möchte nicht wissen, ob das Array größer als pos ist. Ich möchte wissen, ob pos kleiner als die Arraygröße ist.

Es ist wie eine halb leere oder halb volle Diskussion. Mathematisch identisch, aber mein Gehirn wird sie je nach Kontext unterschiedlich sehen.

Persönlich, wenn ich sehe

if (array.lengh > pos) {
    // do some with array[pos];
}

Ich werde darüber nachdenken, ob das ein Fehler ist oder nicht und was der Programmierer gemeint hat. Versucht er etwas anderes als die Überprüfung der Grenzen?

Vielleicht bin ich einfach nicht klug, aber wenn ich diese Art von Analyse für jede Codezeile durchführen muss, tut mein Gehirn weh.

Brandon
quelle
3

Um auszudrücken, was einige versucht haben, auf eine andere Art und Weise zu erreichen ...

Wenn die Reihenfolge keinen Einfluss auf das Verhalten des Programms hat, hängt der Unterschied eindeutig davon ab, was für den Menschen am besten lesbar ist. Hier ist ein sprachlicher Grund, warum es sinnvoll ist, das "Thema" links zu setzen:

In der Linguistik ist das Thema eines Satzes das, worüber gesprochen wird, und der Kommentar ist das, was über das Thema gesagt wird. In diesem Beispiel können wir davon ausgehen, dass dies positiondas Thema ist und "weniger als die Array-Länge" der Kommentar ist . In Englisch und in vielen anderen Sprachen wird das Thema normalerweise vor dem Kommentar ausgedrückt.
" Die Tendenz, topikalisierte Bestandteile zunächst zu setzen (Themenfront), ist weit verbreitet. "

Also eine gute Faustregel Ihrer Codezeile als Satz (oder Klausel, in diesem Fall) zu denken, entscheiden , was der Satz über , und dass die erste Stelle setzen , wenn Sie können. Oft ist das, worum es in dem Satz geht, eher eine Variable als eine Konstante. Manchmal enthält der Kommentar jedoch auch eine Variable, sodass Sie nicht einfach so vorgehen können.

LarsH
quelle
1

Es ist eine Kombination aus zwei Dingen, die beide von dem zugrunde liegenden Assembler stammen, zu dem frühe Sprachen kompiliert wurden (und viele aktuelle auch).

  1. Arrays sind nullbasierte Offsets im Speicher (dh der erste Datenblock befindet sich am Anfang des zugewiesenen Speicherblocks ... der 0-Index). Daher die Verwendung von 0..n-1 für das variierende Stück.

  2. Das Verzweigen, wenn ein Wert kleiner als ein anderer Wert (oder ein Register usw.) ist, ist normalerweise eine einzelne Anweisung. Daher die Verwendung des einfachen Operators kleiner als (<).

Das Muster wurde also vom alten Assembler in ANSI-C (das in gewisser Weise eher einem Makro-Assembler ähnelt) und von dort nach Java und in die anderen C-ähnlichen Sprachen verschoben.

andyb
quelle
0

Wie viele andere Antworten gesagt haben, ist es sehr oft einfacher zu lesen:

[thing that varies] [comparison] [thing that does not vary]

Fast jeder, den ich kenne, verwendet ausschließlich diesen Stil.

Es gibt eine Ausnahme für Sprachen im C-Stil, die =zur Zuweisung und ==zum Vergleich verwendet werden. Wenn Sie versehentlich Folgendes eingeben:

if (variable = 5) ...

Anstatt von:

if (variable == 5) ...

Dann erhalten Sie keine Fehlermeldung, da dies eine gültige Codezeile ist. (Einige Compiler und IDEs werden Sie davor warnen, aber es ist immer noch sehr einfach, einen so einfachen Tippfehler zu haben.)

Wenn Sie jedoch schreiben:

if (5 == variable) ...

Der Compiler / Interpreter wird einen Fehler machen, da dies kein gültiges Konstrukt ist (in den meisten Sprachen jedenfalls).

Diese Umschaltung wird oft als Yoda-Bedingung bezeichnet .

UPDATE : Hier ist eine Liste von Orten, an denen Yoda-Bedingungen nützlich sind .

Moshe Katz
quelle
-1

Persönlich bevorzuge ich Folgendes:

bool positionIsWithinBounds = pos < array.length;
if (positionIsWithinBounds) {
   // do some with array[pos];
}

... es ist mehr Code, aber auch sehr einfach zu lesen.

John MacIntyre
quelle
4
+1, um dem Vergleich einen Namen zu geben. Wirklich, ich mag diesen Ansatz besser für komplexere Bedingungen und nicht so sehr für einfache Fälle wie diesen. Es lässt mich tatsächlich aufhören, über "Array", "Grenzen", "innerhalb" und was diese alle bedeuten, nachzudenken, wenn ich instinktiv weiß, was es bedeutet, poszu sein > array.length. Mit anderen Worten, obwohl dies die Bedeutung der Bedingung sehr deutlich macht, ist es tatsächlich etwas schwieriger, IMO zu lesen.
John M Gant
Noch ein anderer Name im Auge zu behalten ...
Deduplicator
-1

Es ist eine Frage der Präferenz oder Konvention. Wenn Sie konsistent sein möchten, gibt es zwei gleichermaßen vernünftige Möglichkeiten:

  1. Stellen Sie immer das "Thema" an die erste Stelle (stellen Sie es sich als Satz vor) - den Wert, um den es beim Test geht. So würden Sie zum Beispiel schreibenif (age>5)

  2. Oder stellen Sie immer das kleinere Element an die erste Stelle (denken Sie daran, dass die Werte in natürlicher Reihenfolge auf Ihrem Bildschirm angeordnet sind). Sie würden also beispielsweise if (a<b)unabhängig davon schreiben, ob es sich bei diesem Code hauptsächlich um a oder hauptsächlich um b handelt.

Beide Konventionen würden das erste Snippet empfehlen, das Sie anstelle des zweiten gezeigt haben. Ich denke, in diesem speziellen Fall haben Sie Ihre Antwort. Ich würde sagen, es ist ratsam, das Schreiben von Code zu vermeiden, der sowohl gegen (1) als auch gegen (2) verstößt, da dies das Lesen für die meisten Menschen erschwert.

Redtuna
quelle