Präfix/Postfix - Anfängerproblem



  • So arbeiten nunmal die Prä/Postfix-operatoren:

    x++;
    

    erhöht den Wert von x und liefert den alten Wert zurück.

    ++x;
    

    erhöht den Wert von x und liefert den neuen Wert zurück.

    (und die Zuweisung "y = Ausdruck" speichert jeweils den Wert, den "Ausdruck" zurückliefert, in der Variablen "y")

    Lang ausgeschrieben kannst du es auch auffassen als:

    n2=++n1; => ++n1;n2=n1;
    n3=n1++; => n3=n1;n1++;
    


  • Redhead schrieb:

    // n1 und n2 haben beide den Wert 6
    n1 = 5;
    n2 = ++n1;
    

    Zuerst wird der Wert von n1 inkrementiert (=6). Anschliessend wird der Wert von
    n1 (6) an n2 zugewiesen.

    Wenn der Wert von n1 inkrementiert wird, wird daraus 6. Das ist klar, aber oben ist doch ganz klar angegeben, n1=5!!! Weshalb wird daraus rückwirkend einfach ne 6 gemacht?
    Es heisst doch n2 = ++n1 bwz n2 ist gleich 1+5 --> n2 = 6, aber n1 wird doch dadurch nicht verändert, oder etwa doch?

    Redhead schrieb:

    [cpp]// n1 hat den Wert 6; n3 hat den Wert 5
    n1 = 5;
    n3 = n1++;
    

    Zuerst wird er Wert von n1 (5) an n2 zugewiesen. Anschliessend wird der Wert von
    n1 inkrementiert (=6).

    Das sollte eigenlich in jedem vernünftigen Lehrbuch verständlich erklärt sein.

    Entweder ich bin echt einfach zu blöd, oder in meinem Buch (C++ für Dummies) ist das nicht richtig erklärt...

    Ich sehe einfach nicht ein, weshalb denn n3 den Wert 5 haben sollte und das ist ja vorgegeben:

    // n1 hat den Wert 6; n3 hat den Wert 5
    n1 = 5;
    n3 = n1++;

    Wenn jetzt also zuerst der Wert von n1 an n3 zugewiesen wird (=5) und dann inkrementiert wird, dann würde doch daraus 6 entstehen und oben (bei //) steht ja, n3 hat den Wert 5

    könnt ihr mir nochmsl ein paar Zeilen schriben??

    Ich bin euch für euere Hilfe echt dankbar!!!!!!!



  • Die Kommentare dort geben jeweils an, was unten herauskommen soll(te) 😉

    [cpp]// n1 hat den Wert 6; n3 hat den Wert 5
    n1 = 5;
    n3 = n1++;[/cpp]

    Wenn jetzt also zuerst der Wert von n1 an n3 zugewiesen wird (=5) und dann inkrementiert wird, dann würde doch daraus 6 entstehen und oben (bei //) steht ja, n3 hat den Wert 5

    n1 wird erhöht, n3 nicht.



  • Ach so, die Kommentare haben mich völlig in die Irre geführt^^ Die sollten besser unten stehen...

    Aber ich habe auch ein kleines Problem. Ich dachte immer:

    int a = 5;
    cout << a++;
    // a = 5
    cout << a;
    // a = 6;
    

    dass die Variable beim ersten "benutzen" noch den alten Wert 5 hat und beim 2. "Benutzen" dann erhöht wird. Aber anscheinend hat das auch was mit den Zeilen oder so in der Art zu tun, denn

    int a = 5;
    cout << a++ << endl << a;
    

    ergibt beides 5! 😕
    Erst bei

    int a = 5;
    cout << a++ << endl;
    cout << a;
    

    ist die Ausgabe dann 5 und 6. 😕

    Wie wann genau werden die Variablen denn immer inkrementiert und wann noch nicht?



  • hmmm, so langsam komme ich der ganzen Sache auf die Schliche.

    Ich danke euch jedenfalls ganz herzlich für euere Hilfe!
    Das ist echt super von euch!!!

    Bis bald (bestimmt!!!)



  • milo51 schrieb:

    Ach so, die Kommentare haben mich völlig in die Irre geführt^^ Die sollten besser unten stehen...

    Aber ich habe auch ein kleines Problem. Ich dachte immer:

    int a = 5;
    cout << a++;
    // a = 5
    cout << a;
    // a = 6;
    

    dass die Variable beim ersten "benutzen" noch den alten Wert 5 hat und beim 2. "Benutzen" dann erhöht wird. Aber anscheinend hat das auch was mit den Zeilen oder so in der Art zu tun, denn

    Die wird nicht beim zweiten Benutzen erhöht, sondern direkt nach dem ersten Benutzen.

    Zu deinem Cout-Beispiel: Der Standard legt nicht fest, in welcher Reihenfolge Nebeneffekte auftreten MÜSSEN, er definiert lediglich einige Synchronisationspunkte dazu (an einem Synch-Punkt ist sicher, daß alle vorigen Nebeneffeckte abgearbeitet sind und alle später kommenden Nebeneffekte noch nicht eingetreten sind). Das Semikolon ist ein Synch-Punkt, der Shift-Operator (<<) ist allerdings keiner.



  • Ach so alles klar danke.
    Hmm...

    for(int i = 0; i < 2; i++)
         {
              ;
              cout << i << endl;
              cout << i << endl;
         }
    

    Ausgabe: 0
    0
    1
    1

    Komisch, nach der ersten Ausgabe habe ich doch einen Synch-Punkt, dann müsste doch erst 0 und dann 1 ausgegeben werden.
    Oder wird beim ersten Schleifendurchgang tatsächlich nur die Initialisierung und die Bedingung durchgeführt und erst bei den weiteren Durchläufen auch die Inkrementierung?
    Aber dann müsste der letzte Wert doch eine 2 sein...
    Versteh ich nicht



  • edit: ahh ok das mit dem ; wusst ich noch nicht ( hab den Post oben nicht gelesen )



  • die for-Schleife kannst du in eine while-Schleife umwandeln:

    for( init ; test ; inc )
      command;
    
    init;
    while( test )
    {
      command;
      inc;
    }
    

    d.h. der Erhöhungsschritt erfolgt jeweils am Ende der Schleife. Und wenn die Abbruchbedingung erfüllt ist, geht er nicht wieder rein.

    (btw: Und die Synchronisationspunkte sind nur dann wichtig, wenn in einem Ausdruck mehrere Nebeneffekte auftreten können, z.B. "a = b++ + c--;")



  • Ah stimmt ok. For-Schleife verstanden

    Und was genau meinst du mit Nebeneffekt?
    Und was meinst du mit, die Synch-Punkt sind nur dann "wichtig"? Wichtig zu beachten oder wie?



  • Nebeneffekt ist alles, was den Inhalt einer Variablen beeinflussen kann - das betrifft hauptsächlich Inkrement, Dekrement, Zuweisungsoperatoren und Funktionsaufrufe (letztere sind besonders gemein, wenn die Funktion auf globale Variablen zugreift).
    Und die Synchronisationspunkte sind insofern wichtig, indem sie einschränken, wann und wie welche Nebeneffekte ausgeführt wurden - du solltest zwischen zwei Synch-Punkten nur einmal deine Variable ändern, sonst endest du in undefiniertem Verhalten (z.B. ist nicht definiert, wes bei "a = b++ + b--;" herauskommt, weil hier zwei Nebeneffekte parallel auf b wirken). Und du solltest eine Variable nicht lesen, wenn die Ausführung der Nebeneffekte ungesichert ist (d.h. selbst der Ausdruck "a = b++ * b;" ist schon undefiniert).



  • Ach so jo, k danke.


Anmelden zum Antworten