340 Stimmen

Wozu dienen geschweifte Klammern (d.h. {}) in einer einzeiligen if- oder Schleife?

Ich lese gerade einige Vorlesungsunterlagen meines C++-Dozenten, und er schrieb Folgendes:

  1. Einrückung verwenden // OK
  2. Verlassen Sie sich nie auf den Vorrang von Operatoren - Verwenden Sie immer Klammern // OK
  3. Verwenden Sie immer einen { }-Block - auch für eine einzelne Zeile // nicht OK Warum?
  4. Const-Objekt auf der linken Seite des Vergleichs // OK
  5. Vorzeichenlose Variablen, die >= 0 sind, verwenden // netter Trick
  6. Zeiger nach dem Löschen auf NULL setzen - Doppelter Löschschutz // nicht schlecht

Die 3. Technik ist mir nicht klar: Was würde ich gewinnen, wenn ich eine Zeile in a { ... } ?

Nehmen wir zum Beispiel diesen merkwürdigen Code:

int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
    if (i % 2 == 0)
    {
        j++;
    }
}

und ersetzen sie durch:

int j = 0;
for (int i = 0 ; i < 100 ; ++i)
    if (i % 2 == 0)
        j++;

Was ist der Vorteil der 1. Version?

4voto

AncientSwordRage Punkte 6818

Wenn ich mir die Antworten ansehe, hat niemand explizit die Art von Praxis genannt, die ich mir zur Gewohnheit mache, nämlich die Geschichte des Codes zu erzählen:

int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
    if (i % 2 == 0)
    {
        j++;
    }
}

Wird:

int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
    if (i % 2 == 0) j++;
}

Die Umsetzung der j++ über die gleiche Linie als die si an andere Personen weitergeben sollte, "Ich will nur, dass dieser Block immer größer wird j " . Dies ist natürlich nur dann sinnvoll, wenn die Zeile so einfach wie möglich ist, denn das Setzen eines Haltepunkts an dieser Stelle, wie peri erwähnt, wird nicht sehr nützlich sein.

Tatsächlich bin ich gerade auf einen Teil der Twitter Storm API gestoßen, der diese Art von Code in Java enthält. Hier ist der entsprechende Ausschnitt aus dem ausgeführten Code, auf Seite 43 dieser Diashow :

...
Integer Count = counts.get(word);
if (Count=null) count=0;
count++
...

En für Schleife Block hat zwei Dinge in ihm, so würde ich nicht inline, dass Code. I.e., niemals :

int j = 0;
for (int i = 0 ; i < 100 ; ++i) if (i % 2 == 0) j++;

Es ist furchtbar, und ich weiß nicht einmal, ob es (wie beabsichtigt) funktioniert; Tun Sie das nicht . Neue Zeilen und geschweifte Klammern helfen dabei, getrennte, aber zusammenhängende Teile des Codes zu unterscheiden, so wie es ein Komma oder ein Semikolon in der Prosa tun. Der obige Block ist wie ein sehr langer Satz mit einigen Klauseln und einigen anderen Aussagen, die nie unterbrochen werden, um einzelne Teile zu unterscheiden.

Wenn Sie wirklich jemandem mitteilen wollen, dass es sich um einen einzeiligen Auftrag handelt, verwenden Sie einen ternären Operator oder ?: Form:

for (int i = 0 ; i < 100 ; ++i) (i%2 ? 0 : >0) j++;

Aber das grenzt schon an Code-Golf und ich denke, es ist keine gute Praxis (es ist mir nicht klar, ob ich die j++ auf eine Seite der : oder nicht). NB Ich habe noch nie einen ternären Operator in C++ ausgeführt, und ich weiß nicht, ob das funktioniert, aber es gibt sie doch .

Kurz gesagt:

Stellen Sie sich vor, wie Ihr Leser (d. h. die Person, die den Code pflegt) Ihre Geschichte (den Code) interpretiert. Machen Sie es für ihn so klar wie möglich. Wenn Sie wissen, dass ein unerfahrener Programmierer/Student den Code pflegt, lassen Sie vielleicht sogar so viele {} wie möglich, damit sie nicht verwirrt werden.

4voto

Artemix Punkte 2074

Ein weiteres Beispiel für das Hinzufügen geschweifter Klammern.

Einmal habe ich nach einem Fehler gesucht und einen solchen Code gefunden:

void SomeSimpleEventHandler()
{
    SomeStatementAtTheBeginningNumber1;
    if (conditionX) SomeRegularStatement;
    SomeStatementAtTheBeginningNumber2;
    SomeStatementAtTheBeginningNumber3;
    if (!SomeConditionIsMet()) return;
    OtherwiseSomeAdditionalStatement1;
    OtherwiseSomeAdditionalStatement2;
    OtherwiseSomeAdditionalStatement3;
}

Wenn Sie die Methode Zeile für Zeile lesen, werden Sie feststellen, dass es eine Bedingung in der Methode gibt, die zurückgegeben wird, wenn sie nicht wahr ist. Aber eigentlich sieht es aus wie 100 andere einfache Event-Handler, die einige Variablen basierend auf einigen Bedingungen setzen. Und eines Tages kommt der Fast Coder und fügt zusätzliche Anweisungen zum Setzen von Variablen am Ende der Methode hinzu:

{
    ...
    OtherwiseSomeAdditionalStatement3;
    SetAnotherVariableUnconditionally;
}

Infolgedessen wird SetAnotherVariableUnconditionnally ausgeführt, wenn SomeConditionIsMet() ausgeführt wird, aber der schnelle Typ hat es nicht bemerkt, weil alle Zeilen fast gleich groß sind und selbst wenn die Rückgabebedingung vertikal eingerückt ist, fällt es nicht so sehr auf.

Wenn die bedingte Rückgabe wie folgt formatiert ist:

if (!SomeConditionIsMet())
{
    return;
}

Es ist sehr auffällig und der Fast Coder findet es auf einen Blick.

3voto

P.P Punkte 111806

Wenn Sie ein Compiler sind, macht das keinen Unterschied. Beide sind gleich.

Aber für Programmierer ist die erste Variante klarer, leichter zu lesen und weniger fehleranfällig.

2voto

RollRoll Punkte 7657

Meiner Meinung nach ist der erste klarer als der zweite. Er vermittelt das Gefühl einer abschließenden Anweisung. Bei kurzem Code ist das in Ordnung, aber wenn der Code komplexer wird, {...} hilft sehr, auch wenn es sich endif ou begin...end .

// First
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
{
    if (i % 2 == 0)
    {
        j++;
    }
}

// Second
int j = 0;
for (int i = 0 ; i < 100 ; ++i)
    if (i % 2 == 0)
        j++;
i++;

2voto

Öö Tiib Punkte 10171

Die Verwendung geschweifter Klammern ist eine sehr einfache und solide Regel. Allerdings kann der Code unelegant aussehen, wenn es viele geschweifte Klammern gibt.

Wenn die Regeln es erlauben, geschweifte Klammern wegzulassen, sollte es detailliertere Stilregeln und ausgefeiltere Werkzeuge geben. Andernfalls kann dies leicht zu chaotischem und verwirrendem (nicht elegantem) Code führen.

Daher ist es wahrscheinlich sinnlos, eine einzelne Stilregel getrennt von den übrigen Stilrichtlinien und den verwendeten Tools zu betrachten. Ich werde nur einige wichtige Details zu dieser Regel #3 nennen, die in anderen Antworten nicht einmal erwähnt wurden.

Das erste interessante Detail ist, dass die meisten Befürworter dieser Regel darin übereinstimmen, gegen sie zu verstoßen, wenn es um else . Mit anderen Worten, sie wollen nicht, dass es zu einem solchen Code kommt:

// Pedantic rule #3
if ( command == Eat )
{
    eat();
}
else
{
    if ( command == Sleep )
    {
        sleep();
    }
    else
    {
        if ( command == Drink )
        {
            drink();
        }
        else
        {
            complain_about_unknown_command();
        }
    }
}

Wenn sie es sehen, können sie sogar vorschlagen, es so zu schreiben:

// Not fully conforming to rule #3
if ( command == Eat )
{
    eat();
}
else if ( command == Sleep )
{
    sleep();
}
else if ( command == Drink )
{
    drink();
}
else
{
   complain_about_unknown_command();
}

Dies ist technisch gesehen ein Verstoß gegen Regel Nr. 3, da keine geschweiften Klammern zwischen else y if aber die Mehrheit hält sie für offensichtlicher und leichter zu lesen. Diese Zwiespältigkeit der Regel zeigt sich, wenn man versucht, sie automatisch mit einem geistlosen Werkzeug auf eine Codebasis anzuwenden. Warum also streiten? Lassen Sie einfach ein Werkzeug den Stil automatisch anwenden.

Das zweite Detail (das auch von den Befürwortern dieser Regel oft vergessen wird) ist, dass die Illusionsfehler, die auftreten können, nie nur auf Verstöße gegen diese Regel #3 zurückzuführen sind. Tatsächlich handelt es sich dabei fast immer auch um Verstöße gegen die Regel Nr. 1 (die niemand bestreitet). Wiederum vom Standpunkt automatischer Werkzeuge aus betrachtet, ist es nicht schwer, ein Werkzeug zu entwickeln, das sich sofort beschwert (oder sogar korrigiert), wenn Regel Nr. 1 verletzt wird, und so können die meisten Fehler rechtzeitig erkannt werden.

Das dritte Detail (das von den Gegnern dieser Regel oft vergessen wird) ist die verwirrende Natur einer leeren Aussage, die durch ein einzelnes Semikolon dargestellt wird. Die meisten Entwickler mit etwas Erfahrung wurden früher oder später von einem einzigen falsch gesetzten Semikolon oder von einer leeren Anweisung, die mit einem einzigen Semikolon geschrieben wurde, verwirrt. Zwei geschweifte Klammern anstelle eines einzelnen Semikolons sind visuell viel leichter zu erkennen.

Also TL;DR mein Vorschlag ist, anstatt sich auf solche Regeln zu einigen, sich auf die Konfiguration von Auto-Formatierungs-Tools zu einigen und diese zu einem Teil des Build-Prozesses zu machen. Die Werkzeuge sind oft schlauer als die Teilnehmer eines solchen Streits.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X