Deklaration in Schleife oder nicht?



  • Hallo,

    ich frage mich jetzt schon länger ob es einen Unterschied gibt zwischen folgenden beiden Code-Teilen (außer dass bei der zweiten Variante die Variable test nur in der for Schleife verfügbar ist):

    int test;
    for (unsigned int i = 0; i < 100; i++) {
        test = 42;
        // Mach irgendwas
    }
    

    oder:

    for (unsigned int i = 0; i < 100; i++) {
        int test = 42;
        // Mach irgendwas
    }
    

    Ich würde nämlich gerne oft die zweite Variante verwenden (da kürzer wenn test nur in der for-Schleife benötigt wird), bin mir aber nicht sicher ob das nicht langsamer ist? Denn das erste ist ja nur eine Zuweisung, das zweite eine Deklaration und eine Zuweisung...

    Oder macht das keinen Unterschied?



  • der generierte assemblercode sieht bestimmt gleich aus. der speicher von variablen auf dem stack wird ja schon während der kompilierung "reserviert".

    damit die beiden codes auch wirklich das selbe ausdrücken darf test innerhalb der schleife nicht verändert werden, womit ich ihren sinn anzweifle.



  • Das erste ist schlicht weg falsch. Variablen werden bei der Deklaration auch initialisiert. Das solltest Du Dir gleich angewöhnen.

    Variablen sollten so lokal wie möglich sein. Also Lösung 2.
    Ich denke der Compiler wird das optimieren und die Zuweisung aus der Schleife rausziehen.

    Edith: Ok Ok. Das oben muss natürlich Definition heissen.

    Wie weiter unten schon steht wird der gleiche Code erzeugt falls "test" in der Schleife NICHT verändert wird.



  • MichelRT schrieb:

    Das erste ist schlicht weg falsch.

    Nein.



  • MichelRT schrieb:

    Das erste ist schlicht weg falsch.

    nö.

    MichelRT schrieb:

    Variablen werden bei der Deklaration auch initialisiert. Das solltest Du Dir gleich angewöhnen.

    nö, das pauschal zu sagen ist falsch.

    MichelRT schrieb:

    und die Zuweisung aus der Schleife rausziehen.

    welche zuweisung? sehe da keine...



  • MichelRT schrieb:

    Variablen werden bei der Deklaration auch initialisiert.

    extern int i;
    

    Womit wird i hier initialisiert?



  • Ok, also in die Schleife damit, richtig?

    Deklarator schrieb:

    Womit wird i hier initialisiert?

    Äh, keine Ahnung, mit was? 😃
    Ich würde ja sagen mit nix? Aber irgendwas steht ja immer drin auch wenn man nichts explizit hinschreibt... Also meistens dann halt ein sehr großer (oder sehr kleiner) Wert.



  • happystudent schrieb:

    Ok, also in die Schleife damit, richtig?

    wie gesagt: wenn beide varianten bei deinem code das selbe bewirken, dann zweifle ich den sinn an. zeig halt den echten code...

    happystudent schrieb:

    Deklarator schrieb:

    Womit wird i hier initialisiert?

    Äh, keine Ahnung, mit was? 😃
    Ich würde ja sagen mit nix? Aber irgendwas steht ja immer drin auch wenn man nichts explizit hinschreibt... Also meistens dann halt ein sehr großer (oder sehr kleiner) Wert.

    der autor wollte eher suggerieren, dass MichelRT von einer deklaration sprach (statt von einer definiton), was so nicht richtig ist.



  • asfdlol schrieb:

    wie gesagt: wenn beide varianten bei deinem code das selbe bewirken, dann zweifle ich den sinn an. zeig halt den echten code...

    // Suche größtes Element in der aktuellen Spalte für Pivotisierung
    for (unsigned int i = 0, ei = matrix.rows(); i != ei; i++) {
        double maxValue = DBL_MIN;
        for (unsigned int j = 0, ej = matrix.cols(); j != ej; j++) {
            if (matrix[i][j] > maxValue) {
                maxValue = matrix[i][j];
            }
        }
    }
    

    macht genau das gleiche wie:

    // Suche größtes Element in der aktuellen Spalte für Pivotisierung
    double maxValue;
    for (unsigned int i = 0, ei = matrix.rows(); i != ei; i++) {
        maxValue = DBL_MIN;
        for (unsigned int j = 0, ej = matrix.cols(); j != ej; j++) {
            if (matrix[i][j] > maxValue) {
                maxValue = matrix[i][j];
            }
        }
    }
    

    Wieso du hier den Sinn anzweifeln willst weiß ich nicht, beide Varianten machen genau das gleiche (Wie gesagt natürlich bis auf den Unterschied dass maxValue dann auch außerhalb der Schleife verfügbar ist)?



  • jo, macht beides genau gleich viel: nix.

    ausserdem seh ich nicht wieso du versucht std::max_element nachzuimplementieren und was das mit DBL_MIN soll:

    for (unsigned int i = 0, ei = matrix.rows(); i != ei; i++)
    { 
        double maxValue = *std::max_element(matrix[i], matrix[i] + matrix.cols());
    }
    


  • asfdlol schrieb:

    ausserdem seh ich nicht wieso du versucht std::max_element nachzuimplementieren und was das mit DBL_MIN soll:

    eveentuell, weil er max_element implementieren will? Sein Name ist kein Hint? Ehrlich nicht? Nicht so ein Bisschen? 🙂

    //edit und ich kenne so auf die schnelle 3 Implementierungen, bei der dein Code so richtig krass seitenweise compilerfehler ausspucken würde, weil du annimmst, dass op[] einen Zeiger zurückgibt 🙂



  • @happystudent
    Bei nem int ist es Wurscht.

    Bei Klassen die teuer zu konstruieren/zerstören sind, ist es nicht wurscht. Weil die ja bei der 2. Variante immer wieder zerstört und neu konstruiert werden.
    (Wobei es natürlich auch da wurscht ist, falls die Zuweisung gleich teuer ist wie Zerstören + neu Konstruieren.)



  • asfdlol schrieb:

    jo, macht beides genau gleich viel: nix.

    ausserdem seh ich nicht wieso du versucht std::max_element nachzuimplementieren und was das mit DBL_MIN soll:

    Nichts? Es findet das größte Element der aktuellen Spalte was wichtig für Pivotisierung beim Lösen eines Linearen Gleichungssystems ist. DBL_MIN ist der kleinste double Wert, daher macht es Sinn eine Variable die am Ende das Maximum beinhalten soll damit zu initialisieren... was gibts da nicht zu verstehen?

    Es war ja auch nur ein Beispiel um das Problem zu verdeutlichen.

    hustbaer schrieb:

    @happystudent
    Bei nem int ist es Wurscht.

    Bei Klassen die teuer zu konstruieren/zerstören sind, ist es nicht wurscht. Weil die ja bei der 2. Variante immer wieder zerstört und neu konstruiert werden.
    (Wobei es natürlich auch da wurscht ist, falls die Zuweisung gleich teuer ist wie Zerstören + neu Konstruieren.)

    Danke, sowas wollte ich hören. 👍



  • Aber das Rausziehen auch nicht übertreiben.
    http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=Declare#Answ

    Selten, daß ich mal aus Performanceüberlegungen was rausziehe.



  • happystudent schrieb:

    asfdlol schrieb:

    jo, macht beides genau gleich viel: nix.

    ausserdem seh ich nicht wieso du versucht std::max_element nachzuimplementieren und was das mit DBL_MIN soll:

    Nichts? Es findet das größte Element der aktuellen Spalte was wichtig für Pivotisierung beim Lösen eines Linearen Gleichungssystems ist. DBL_MIN ist der kleinste double Wert, daher macht es Sinn eine Variable die am Ende das Maximum beinhalten soll damit zu initialisieren... was gibts da nicht zu verstehen?

    Es war ja auch nur ein Beispiel um das Problem zu verdeutlichen.

    und wo speicherst du die maximalen elemente? nirgends. daher machen beide nichts. sonst könntest du ja gleich in den zielspeicher reinschreiben und hast das ganze theater nicht. und statt mit einem unflexiblen minimalwert zu initialisieren kannst du einfach das erste element nehmen...



  • asfdlol schrieb:

    und wo speicherst du die maximalen elemente? nirgends. daher machen beide nichts. sonst könntest du ja gleich in den zielspeicher reinschreiben und hast das ganze theater nicht. und statt mit einem unflexiblen minimalwert zu initialisieren kannst du einfach das erste element nehmen...

    Und wo erstelle ich das Objekt matrix? Und wo include ich überhaupt float.h um auf DBL_MIN zugreifen zu können?

    Natürlich macht der Code alleine nichts (stimmt übrigens auch nicht, er findet das absolut größte Element der Matrix und speichert es in maxValue). Und ja, man kann auch das erste Elemnt nehmen anstatt DBL_MIN. Ändert an der eigentlichen Frage aber überhaupt gar nichts.

    Das war einfach ein minimales Code-Snippet um das Problem zu veranschaulichen. Ich hätt auch den ganzen Code des Gauss-Algorithmus hinklatschen können, das hätte aber keinerlei Mehrwert gebracht.


Anmelden zum Antworten