Ist ++i anders als i++???



  • Original erstellt von JoelH:
    Autsch, dann werd ich mal alle meinen zeitkritischen Programme umstellen 😉
    Wie ist das eigentlich bei forschleifen , das wird doch bestimmt wegoptimiert ?!

    kommt darauf an - bei builtins JA, bei eigenen Typen wohl eher nicht (obwohl es theoretisch moeglich waere, wenn man die beiden operatoren schoen miteinander implementiert)

    warum sollte ich also performance verlust in kauf nehmen (egal wie gering er ist) wenn ichs nicht muss?



  • warum sollte ich also performance verlust in kauf nehmen (egal wie gering er ist) wenn ichs nicht muss?

    Oder: Warum sollte ich einen Informationsverlust in kauf nehmen (egal wie gering er ist), wenn ich's nicht muss?



  • HumeSikkins machst du dadurch nicht die Semantik des fors etwas kaput? das for was in jedem c++ Hirn so eingebrant ist und dadurch auch schneller verstanden werden kann.
    Oder willst du uns was mit "AssocContainer" mit teilen, was ich nicht verstanden habe.



  • Oder willst du uns was mit "AssocContainer" mit teilen, was ich nicht verstanden habe.

    AssocContainer steht für einen der assoziativen Container aus der Standardbibliothek. Nimm z.B. std::map.

    Das erste Beispiel sieht schön aus, ist aber falsch, das zweite ist richtig.
    Die Zeilen sind nur ein Beispiel dafür, dass ++i und i++ nicht das Selbe sind. Und das man beide ihrer Semantik nach einsetzen sollte.



  • vielleicht liegt es zumindestens einfach an meinen verkrusteten Denkstrukturen, ich komme halt von c64 i = i +1 , darauf wird der zusammengesetzte Operator += und daraus resultiert eben i++ und nicht ++i . Das ist einfach eine kürzere Nervenverbindung in meinem Gehirn.

    [ Dieser Beitrag wurde am 28.11.2002 um 12:57 Uhr von JoelH editiert. ]



  • Original erstellt von JoelH:
    **vielleicht liegt es zumindestens einfach an meinen verkrusteten Denkstrukturen, ich komme halt von c64 i = i +1 , darauf wird der zusammengesetzte Operator += und daraus resultiert eben i++ und nicht ++i . Das ist einfach eine kürzere Nervenverbindung in meinem Gehirn.
    **

    aber leider falsch.
    y=(i=i+1);
    ist gleich
    y=(i+=1);
    ist gleich
    y=(++i);
    ist ungleich
    y=(i++);

    ok, jetzt haste kapiert, daß ++i das normale inkrementieren ist, und das ist ab jetzt einfach eine kürzere nervenverbindung in deinem gehirn.
    so gehts mir wenigstens. ich schreib schon alleine deswegen lieber ++i, weils das normale inkrementieren ist, das normale i=i+1.



  • Original erstellt von volkard:
    **
    aber leider falsch.
    **

    Aber auch nur weil du Äpfel mit Birnen vergleichst 😉 Wo kommt bei mir ein y vor ?

    Ich handle nach der Maxime 'Keep it simple and stupid !' sprich wenn schon dann

    i++;
    y=i;
    

    Ich halte wenig von solchen Konstrukten über die man zuerstmal nachdenken muss wenn man sie liest selbst wenn man schon weiss was sie machen. Ich meine genau wegen diesem y = ++i oder y = i++ bricht sich keiner die Zacken aus der Krone, aber dadurch erst enstehen Konstrukte wie y = ++i * v * i++ und das ist schon eher das Problem. Warum nicht einfach

    y = i;
    i++;
    

    bzw.

    i++;
    y = i;
    

    Wem tue ich damit weh ?
    Nehmen wir diese tolle Programm

    #include <iostream>
    using namespace std;
    /* Unterschied Postfix-Präfix */
    
    int main()
    {
            int alter_mann = 20;
            int alter_frau = 20;
            cout << "Der Mann ist:\t" << alter_mann << "\tJahre alt.\n";
            cout << "Die Frau ist:\t" << alter_frau << "\tJahre alt.\n";
    
            alter_mann++;           // Postfix-Inkrement
            ++alter_frau;           // Präfix-Inkrement
            cout << "\nEin Jahr ist vergangen...\n";
            cout << "Der Mann ist:\t" << alter_mann << "\tJahre alt.\n";
            cout << "Die Frau ist:\t" << alter_frau << "\tJahre alt.\n";
    
            cout << "\nEin weiteres Jahr ist vergangen...\n";
            cout << "Der Mann ist:\t" << alter_mann++ << "\tJahre alt.\n";
            cout << "Die Frau ist:\t" << ++alter_frau << "\tJahre alt.\n";
    
            cout << "\nUnd noch einmal das Alter ausgeben.\n";
            cout << "Der Mann ist:\t" << alter_mann << "\tJahre alt.\n";
            cout << "Die Frau ist:\t" << alter_frau << "\tJahre alt.\n\n";
    
            return 0;
    }
    

    Wer so programmiert will eigentlich doch nur verwirren oder ?
    oder nehmen wir dies (Rubycode)

    def zeller(tag, monat, jahr)
        # zellersche formel
            if monat > 2
                monat -= 2
            else
               monat += 10
               jahr -= 1
            end
            @wochentag = (70 + tag +
                    (13 * monat - 1) / 5 + # integer division
                    (jahr % 100) +
                    (jahr % 100) / 4 + # integer division
                    (jahr / 100) / 4 -
                    2 * (jahr / 100)
                   ) % 7
        end
    

    den Zelleralgo zum Wochentagberechnen
    meiner sieht so aus

    def formel (einzelwerte)
        #Zuerst generieren wir die Wochentage und dann die Tage der einzelnen Monate, Februar hat immer 28 Tage da die Schalttage 
        #separat dazu addiert werden
    
        woche = Array["Samstag","Sonntag","Montag","Dienstag","Mittwoch","Donnerstag","Freitag"]
            monate = Array[0,31,59,90,120,151,181,212,243,273,304,334]
    
    # Zuerstmal wird die Jahreszahl mit 365 Tagen multipliziert um alle Tage zu erhalten und die Tage des monats noch mit addiert der angebrochen ist
        wert = einzelwerte[2].to_i*365+einzelwerte[0].to_i
    
        # jetzt kommen noch die Tage der angebrochenen Monate dazu
        wert += monate[einzelwerte[1].to_i-1]
    
        # Jetzt werden die Schaltage hinzugefügt, zuerst werden alle nichtschalkttage subtrahiert, also alle Jahre die durch 100 teilbar sind, das bekommt
        # man sehr leicht raus in dem man das aktuelle Jahr durch 100 dividiert und das integerergebnis davon nimmt
        wert -= (einzelwerte[2].to_i/100).ceil
    
        # aber jetzt müssen alle jahre wieder dazu addiert werden die zwar durch 100 teilbar sind aber auch durch 400, selbest verfahren wie zuvor
        wert += (einzelwerte[2].to_i/400).ceil
    
        # naja und dann müssen wir natürlich noch alle Schaltjahre dazuaddieren
        wert += (einzelwerte[2].to_i/4).ceil
    
        #Jetzt ergibt sich ein Wert den wir mit modulo 7 behandeln, denn die Woche hat 7 Tage, naja und durch den Rest erfahren wir welchen Tag wir haben an 
        # dem Datum, die Idee ist einfach das wir eine unendliche Reihe haben Sa,So,Mo,Di,Mi,Do,Fr,Sa,So,Mo,Di,Do usw. naja also ist jeder siebte Tag ein Samstag
        # durch die Rechnung weiter oben haben wir den 'Tag' ausgerechtet von Null ab naja und durch das Modulo bekommen wir raus welcher Wochentag das ist.
        # Im erklären von Formeln war ich schon immer schlecht 
        #Das geben wir jetzt zurück
    
        return woche[wert.modulo(7)]
    
    end
    

    Der erste ist sicher schneller aber weniger lesbar. Find ich zumindestens.



  • Original erstellt von JoelH:
    Ich handle nach der Maxime 'Keep it simple and stupid !' sprich wenn schon dann
    i++;
    y=i;

    Ich doch auch. Nur hast Du fett behauptet, i++ sei leichter zu raffen, weil es i=i+1 bedeute.

    Ich handle nach der Maxime 'Keep it simple and stupid !' sprich wenn schon dann
    ++i;
    y=i;

    Denn wenn man das y im selben Ausdruck mit ins Spiel bringt (was man natürlich vermeiden sollte), dann ist ++i das gleiche wie i=i+1. Und wenn mans nicht tut, isses egal.
    Auf keinen Fall aber kann Dein Argument mit der Einfachheit begründen, warum Du i++ vorziehst, statt ++i zu nehmen.

    [ Dieser Beitrag wurde am 28.11.2002 um 14:26 Uhr von volkard editiert. ]



  • volkard:
    Auf keinen Fall aber kann Dein Argument mit der Einfachheit begründen, warum Du i++ vorziehst, statt ++i zu nehmen.

    diese Aussage begründete ich eigentlich schon weiter oben
    =>
    i = i + 1
    =>
    i += 1
    =>
    i ++

    das i steht immer an erster Stelle. So meinte ich meinen Satz dort.

    ich schreibe ja nicht
    =>
    1 + i = i
    =>
    gibt kein äquvalent denn 1 += i ist ja quatsch ( in diesem zusammenhang)
    =>
    ++i

    dann hätte wohl eher ++i Eingang gefunden.



  • Original erstellt von JoelH:
    **diese Aussage begründete ich eigentlich schon weiter oben
    =>
    i = i + 1
    =>
    i += 1
    =>
    i ++

    das i steht immer an erster Stelle. So meinte ich meinen Satz dort.

    ich schreibe ja nicht
    =>
    1 + i = i
    =>
    gibt kein äquvalent denn 1 += i ist ja quatsch ( in diesem zusammenhang)
    =>
    ++i

    dann hätte wohl eher ++i Eingang gefunden.**

    heilandsblechle! das ist ja buchstabenmystik. klar, daß ich dem nicht folgen kann.



  • Buchstabenmystik ??

    Cooler Begriff.
    Für mich ist es einfach eine logische Folge der Evolution von Programmiersprachen und der damit einhergehenden Versuch meines Gehirns etwas gelerntes an die neuen Strukturen, relativ einfach und einprägsam, an zu passen.



  • @volkard: Jetzt wär ich doch glatt auf die Idee gekommen deinen Ursprung im Schwarzwald zu vermuten aber dann fiel mir ein, dass die dort Heiligsblechle sagen 😉

    [ Dieser Beitrag wurde am 28.11.2002 um 14:41 Uhr von CengizS editiert. ]



  • Ähh...ich tu mir schwer euren Beiträgen zu folgen daher will ich mal kurz das wiedergeben, was ihr wahrscheinlich eh richtig meint.

    i++ und ++i ist nicht dasselbe.
    ++i ist pre-Increment und i++ ist post-Incremet.

    Postincrement bedeutet, dass zuerst der Wert von i gilt und danach um eins erhöht wird und Preincrement genau das Gegenteil, zuerst 1 dazuaddiert und dann der Wert i zurückgegeben.

    Für den Fall dass die for-Schleife so aus sieht ist es egal:

    for ( i=0; i<10; i++ ) 
    ...  // läuft 10 mal durch
    

    Folgende beiden Beispiele sind aber nicht mehr das selbe:

    for ( i=0; i++<10; )
    ...  // läuft 10 mal durch
    
    for ( i=0; ++i<10; )
    ...  // läuft 9 mal durch
    


  • Original erstellt von ms:
    **
    Folgende beiden Beispiele sind aber nicht mehr das selbe:

    for ( i=0; i++<10; )
    ...  // läuft 10 mal durch
    
    for ( i=0; ++i<10; )
    ...  // läuft 9 mal durch
    

    **

    genau solche Sachen hab ich gemeint !
    Was bringt dir dieses kryptische Geschreibsel ? Dem For Befehl wurden nicht umsonst 3 Parameter geschenkt.

    [ Dieser Beitrag wurde am 28.11.2002 um 15:31 Uhr von JoelH editiert. ]



  • @JoelH: w3IL WIr 933K5 E5 $o L1383n



  • wow, bei Geeks musste ich echt nachdenken.



  • joelh: also diese ignoranz ist ja nicht zu fassen. du solltest mal dein gehirn resetten.
    der zusammenhang zwischen i++ und ++i sieht (zumindest konzeptionell) so aus:

    const T operator++(int){
        T temp(*this);
        ++*this;
        return temp;
    }
    

    wenn in deinem gehirn was anderes ist, kratz es raus und verbrenn es (hehe, nicht das gehirn)

    und dann tu dies in dein gehirn:
    prae - vor - ++ steht vor dem i - es wird erhoeht (++), bevor der wert von i genommen wird
    post - nach - ++ steht nach dem i - es wird erhoeht, nachdem der wert von i genommen wurde

    [ Dieser Beitrag wurde am 28.11.2002 um 15:42 Uhr von PeterTheMaster editiert. ]



  • Original erstellt von PeterTheMaster:
    joelh: also diese ignoranz ist ja nicht zu fassen. du solltest mal dein gehirn resetten.

    der zusammenhang zwischen i++ und ++i sieht (zumindest konzeptionell) so aus:

    const T operator++(int){
        T temp(this);
        ++*this;
        return temp;
    }
    

    wenn in deinem gehirn was anderes ist, kratz es raus und verbrenn es (hehe, nicht das gehirn)

    und dann tu dies in dein gehirn:
    prae - vor - ++ steht vor dem i - es wird erhoeht (++), bevor der wert von i genommen wird
    post - nach - ++ steht nach dem i - es wird erhoeht, nachdem der wert von i genommen wurde[/QB][/QUOTE]

    Wieso ist das ignorant ? Ich mag es einfach nur nicht, aber ich akzeptiere das es da ist und ich weiss auch was Pre und Postfix ist
    Ich habe lediglich aus meiner Sicht geschildert warum ich i++ dem ++i bevorzuge, wie kann man damit so ein Problem haben ??
    /me handelt eben 'Keep it simple and stupid'.



  • Original erstellt von JoelH:
    Was bringt dir dieses kryptische Geschreibsel ?

    <offtopic>C wurde auf Minimalismus hin entwickelt. Damals hat ein Zeichen noch wesentlich Speicher gekostet, besonders wenn man Code irgendwie übers Netz übertragen wollte. Darum hat man überall an Zeichen gespart (Du könntest zum Beispiel das Leerzeichen zwischen 'Geschreibsel' und '?' sparen ;)).
    Aber es hindert dich niemand daran in C Pascal zu Programmieren. </>

    <troll>In C++ darf man, glaub ich, sowieso keine Schleife mehr verwenden, sondern man muss einen Funktor schreiben um dann mit for_each() drüberlaufen zu können. Das hat den Vorteil, dass Code, der logisch zusammengehört physisch getrennt wird. </>



  • Original erstellt von Daniel E.:
    <troll>In C++ darf man, glaub ich, sowieso keine Schleife mehr verwenden, sondern man muss einen Funktor schreiben um dann mit for_each() drüberlaufen zu können. Das hat den Vorteil, dass Code, der logisch zusammengehört physisch getrennt wird. </>

    außerdem darf ich an optimierungen erinern wie z.b. duff device, es ist aufjeden fall komfortabler ein Functor zu schreiben als duff und so jedesmal selbt von hand neu zu schreiben.


Anmelden zum Antworten