it-swarm.com.de

Ist es gut, eine Variable innerhalb einer Schleife zu definieren?

Mein Lehrer hat mir einmal gesagt, dass ich sollte keine Variable innerhalb einer Schleife definieren, aber ich verstehe ehrlich gesagt immer noch nicht warum.

Was sind die Nachteile davon?

Könnte mir jemand das erklären?

16
user3260672

Es ist kein Problem, eine Variable innerhalb einer Schleife zu definieren. In der Tat ist es eine gute Praxis, da Bezeichner auf den kleinstmöglichen Bereich beschränkt werden sollten.

Was schlecht ist, ist zuweisen eine Variable innerhalb einer Schleife, wenn Sie sie genauso gut einmal zuweisen können, bevor die Schleife ausgeführt wird . Je nachdem, wie komplex die rechte Seite der Zuweisung ist, kann dies ziemlich teuer werden und sogar die Laufzeit der Schleife dominieren. Wenn Sie eine Schleife schreiben, die in allen Iterationen denselben berechneten Wert verwendet, sollten Sie sie auf jeden Fall über der Schleife berechnen - das ist wichtiger als die Minimierung ihres Umfangs .

Zur Verdeutlichung: Solange compute() immer den gleichen Wert zurückgibt, ist dies

int value = compute();
while (something) {
    doSomething(value);
}

ist schlauer als das:

while (something) {
    int value = compute();
    doSomething(value);
}
43
Kilian Foth

Komplexe Typen haben nicht triviale Konstruktoren und Destruktoren.

Diese werden am Anfang und am Ende des Schleifenkörpers aufgerufen (da dieser initialisiert ist und den Gültigkeitsbereich verlässt). Wenn die Initialisierung teuer ist und Speicherplatz zuweisen muss, sollte dies vermieden werden.

Für triviale Typen ist dies jedoch kein Problem. Die Zuweisung und Freigabe selbst addiert und subtrahiert lediglich einen Wert vom Stapelzeiger. (was optimiert wird)

16
ratchet freak

Nun, sein Rat ist leicht zu einfach (das ist eine Untertreibung).
Das Folgen reicht von eine gute Idee über wen interessiert das und schlechte Idee bis nmöglich =.

  1. Sie sollten es befolgen, wenn die Wiederverwendung billiger ist als die Zerstörung der alten und die Erstellung einer neuen.

    #include <iostream>
    #include <string>
    
    int main() {
        std::string s; // Don't needlessly free the buffer
        while ((std::cin >> s))
            std::cout << s;
    }
    
  2. Sie sollten es aus Stilgründen meiden, wenn es für die Leistung keine Rolle spielt.

    #include <stdio.h>
    #include <stdlib.h>
    int f(int, int);
    
    int main() {
        for (int i = 0; i < 100; ++i) {
            int x = Rand(); // Declared here so you don't need to hunt it down.
            printf("%d => %d\n", x, f(x-1, x+i));
        }
    }
    
  3. Sie wirklich sollten es meiden, wenn es eine schlechtere Leistung oder die falsche Semantik hat.

    #include <iostream>
    #include <string>
    std::string generate(int);
    
    int main() {
        for(int i = 0; i < 100; ++i) {
            std::string s = generate(i); // Using copy-ellision here
            std::cout << s;
        }
    }
    
  4. Sie können nicht folgen, wenn der verwendete Typ weder das Tauschen noch das Verschieben oder Kopieren zulässt.

    #include <iostream>
    #include <puzzle>
    
    int main() {
        for (int i = 0; i < 100; ++i) {
            Puzzle x(i); // Puzzle is an immutable class. For whatever reasons.
            std::cout << x;
        }
    }
    
6
Deduplicator