Was sind Ihre Tipps für die Spur zu halten und Fehler in Schleifen zu vermeiden?
-
06-07-2019 - |
Frage
ich gerade gefunden ... AGAIN ... eine echte Zeitverschwendung Fehler wie folgt
for (int i = 0; i < length; i++)
{ //...Lots of code
for (int j = 0; i < length; j++)
{
//...Lots of code
}
}
Haben Sie geradeaus die innere i die j sein sollte? Weder tat I. Von nun an die ich verwenden werde:
for (int i = 0; i < length; i++)
{
for (int i1 = 0; i1 < length; i1++)
{
}
}
Was sind Ihre Tipps für die innere und äußere, während und für Schleifen?
Edit: Danke für die wertvollen Antworten. Hiermit kurze Zusammenfassung der vorgeschlagenen Tipps:
- verwenden, sinnvolle Variablennamen für Indexvariablen (statt i verwenden SomeObjCollectionLength)
- setzt den Inhalt der inneren Schleife in ein separates Verfahren und ruft diese Methode von der äußeren Schleife
- nicht überschaubare Menge an Codezeilen zwischen der äußeren und inneren Schleife ist ein starkes Signal für die Code-Geruch
- Kopieren Einfügen vermeiden und rauschen, schreiben Sie den Index Vars mit Sorgfalt
Vielleicht möchten Sie die Zusammenfassung von LBushkin für die folgende
- verwenden foreach und Iteratoren, wenn möglich
- die Variablen initialisieren, kurz bevor die Schleifen Eingabe
- Erstellen Sie jede Schleife nur eine Funktion erfüllen. Vermeiden Sie Aufgaben in einer einzigen Schleife Misch
- Wenn möglich, machen Sie Ihre Schleifen kurz genug, um alle auf einmal anzuzeigen
Lösung
Verwenden Sie keine i & j (oder jeder anderen einzelnen Buchstaben Variable) als Indexnamen. Verwenden Sie Eigennamen und Sie werden nicht in diese Art von Problemen bekommen.
Andere Tipps
Eine der einfachsten und saubersten Lösungen ist der Inhalt der inneren Schleife in ein Verfahren zu platzieren, so wird es:
for (int i = 0; i < length; i++)
{
DoSomething();
}
private void DoSomething(int outerValue)
{
for (int i = 0; i < length; i++)
{
// Do something else
}
}
Für mich ist der 'Codegeruch' hier ist 'eine Menge Code'.
Wenn die Menge der Codes in den Schleifen besonders groß ist, wird der Abstand zwischen den inneren und äußeren Schleifen, bedeutet, dass sie nicht so häufig gegeneinander auf Richtigkeit andere verglichen werden.
Zugegeben, am Anfang der inneren Schleife in Isolation sucht, sollte die Frage, um Ihre Aufmerksamkeit zu bringen, aber in einem so kleinen Abschnitt des Codes wie möglich, die Hauptstruktur, gibt Ihr Gehirn weniger zu verdauen.
Es kann möglich sein, die ‚eine Menge Code‘ Abschnitte in separate Funktionen / Methoden, zu extrahieren, um die Größe der Hauptstruktur zu reduzieren - aber nicht alle Tage praktisch sein kann
.Auch würde ich sagen, dass ‚i1‘ ist keine besonders gute Auswahl an Variablennamen, wie das fördern ‚i2‘ neigt, ‚i3‘ usw., die nicht wirklich zu verständlichem Code führen. Vielleicht die Klarheit des Codes alle der Schleifenvariablen mit etwas Sinnvolles zu ersetzen, würde dazu beitragen, und die Chancen auf dem ursprünglichen Fehler zu reduzieren.
Meine Top-Beratung (in keiner bestimmten Reihenfolge) für eine besseren Schleifencode (ein großen Teil davon ist das Schreiben vom ausgezeichneten Buch Code Complete ):
- Vermeiden Sie mehrere Austrittspunkte für Schleifen.
- Verwenden Sie weiterhin / brechen sparsam.
- Umgestalten verschachtelten Schleifen in separate Routinen, wenn möglich.
- Verwenden Sie aussagekräftige Variablennamen verschachtelte Schleifen lesbar zu machen.
- Verwenden Sie foreach () in einer Schleife möglich, wenn nicht für (i = ...) Schleifen.
- Geben Sie die Schleife von einem Ort nur. Nicht mit GOTOs in eine Schleife springen. Eh und je.
- Setzen Sie Initialisierungscode unmittelbar vor der Schleife.
- Halten Schleife Initialisierungsanweisungen mit der Schleife sie verwandt sind.
- Vermeiden Sie Variablen zwischen nicht-verschachtelten Schleifen Wiederverwendung. 10.Limit der Umfang der Schleife-Index Variablen in die Schleife selbst.
- Verwenden Sie while (true) für Endlosschleifen, anstatt für (;;)
- In Sprachen, die Block-Konstrukte (z.B. ‚{‘ und ‚}‘) verwenden sie statt Einrücken der Aussagen einer Schleife zu umschließen. Ja, auch für einzelne Leiterschleifen.
- Vermeiden Sie leere Schleifen.
- Vermeiden Sie Aufräumarbeiten in der Mitte einer Schleife platzieren, legen Sie sie am Anfang und / oder stattdessen beenden.
- Erstellen Sie jede Schleife nur eine Funktion erfüllen. Vermeiden Sie Aufgaben in einer einzigen Schleife zu mischen.
- Schleifenabbruchbedingungen klar machen.
- Sie nicht Affe mit dem Schleifenindex Variable eines for () Schleife, um es zu beenden.
- Vermeiden Sie Code, der auf der Schleife Indexer der Endwert abhängt.
- Betrachten in komplexen Schleifen mit Sicherheitsindikatoren -. Sie überprüft werden können, um sicherzustellen, ist die Schleife nicht zu viele auszuführen, oder zu wenige Male
- Verwenden break-Anweisungen, wenn möglich, zu beenden, während Schleifen.
- Wenn möglich, machen Sie Ihre Schleifen kurz genug, um alle auf einmal zu sehen.
Das ist eine Copy-Paste-Fehler, kopieren und einfügen vermeiden.
Wie für Ihre Lösung, es ist nicht viel besser. Der Fehler kann zwischen Tonnen von Code verrutschen noch. Ich neige dazu, aussagekräftige Namen zu verwenden, auch für Schleife temporäre Variablen.
Nutzen Sie Ihre IDE, auf VS, versuchen, diese zu nutzen:
Ich bin hergekommen, klug zu sein und sagen: „Ich schreibe es nur beim ersten Mal richtig“. Aber dann sah ich dein Beispiel und, na ja, ich habe, dass zu viele Male getan selbst. Wenn Sie wie die verschachtelten Schleifen benötigen, meine einzige Lösung ist wach und denken, wenn Sie den Code schreiben. Wenn möglich, unter Verwendung von Iteratoren und für jede Schleife ist schön. Auch ich kann nicht sehen, wie Ihre vorgeschlagene Lösung besser sein wird. Und es ist nicht so schön aussehen entweder.
Zu allererst reduzieren die Schleife Körpergröße, das heißt bewegen Zeug separate Funktionen. Es ist generell eine schlechte Idee Funktionen haben mehr als das, was in den Bildschirm passen, so Schleifen sein sollten sogar noch kleiner.
Zweitens verwenden sinnvolle Variablennamen in Fällen wie diesem. Ich würde nur i und j in einfachen Schleifen mit wenigen Zeilen Code verwenden. Zum Beispiel, wenn Sie durch ein zweidimensionales Feld gehen, „col“ und „Zeile“ würde viel mehr Sinn machen, machen den Code leichter zu lesen ( „das war was?“) Und leichten Fehler wie diese zu erkennen.
Sie nur zusätzliche Pflege solcher Probleme zu nehmen, gibt es kein Allheilmittel dagegen. Auch mit „besserer Namensgebung“ Sie schlagen Sie werden hin und wieder den Überblick verlieren, ob dies Nth oder (N + M) ten Ebene der verschachtelten Schleife und einen Fehler machen.
Wenn verschachtelte Schleife ist notwendig, schreiben Sie ihn sorgfältig. Wenn es durch Extraktion der äußeren Schleifenkörper in eine Funktion vermieden werden kann, dass ein guter Schutz gegen Indizes Missbrauch wäre.
Ich verwende ‚ii‘ und ‚jj‘ für transiente Schleifenzähler, wenn ich sie wirklich brauchen - sie sind leichter zu suchen als ‚i‘ und ‚j‘ und auch leichter in Beispielen wie dem oben zu erkennen. Geht ein besser kann man tatsächlich einen echten Variablennamen verwenden. Wenn Sie über einen String sind Looping, dann können Sie nennen es characterIndex oder so etwas. Es ist mehr schreiben, aber es dokumentiert sich und spart Zeit später obskuren Probleme debuggen.
Besser wäre noch numerische Zähler und Verwendung namens Iteratoren über eine Sammlung zu vermeiden sein. Sie machen die Absicht klarer, meiner Meinung nach.
Schließlich, wenn möglich, es ist schön, mit der Schleife zu tun, weg ganz: boost :: Foreach ist ein Weg, dies in C ++ zu tun, obwohl ich es vorziehen, in der Regel Sprachen wie Python verwendet werden, die zum Erhöhen eines Indexwertes oder nativ ohne Notwendigkeit direkte Iteration über den Inhalt eines Behälters ermöglichen Iterator.
Versuchen Sie, mehr deklarative Schleifenkonstrukte zu verwenden. Wenn Sie zum Beispiel nicht wirklich Indizes müssen (die i
s und j
s) und Ihre Programmierumgebung ermöglicht es, können Sie ein foreach
Konstrukt verwenden, um über die Sammlung iterieren.
Wie in diesem wie in vielen Dingen, gibt es einige gute Ratschläge in Steve McConnell Code Complete . Es wäre gut wert Ihre Zeit zu lesen, was er über den Aufbau guten Looping Code zu sagen habe ist. Ich weiß nicht die Kopie des Buches hier praktisch, aber das ganze Buch ist Ihre Zeit wert ist.