Wie wird das berechnet?

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Hi,

    Alsooo ;)

    Ich würde sagen, es kommt 38 raus ;)

    Rechnung:
    12 + [ ((1+12) + 12) +1]

    Klammern dienen natürlich ausschließlich der Veranschaulichung (dank kommutativität).

    ++x und x++ werden i.d.R. bei Schleifen verwendet.

    ++x heißt: Erst hochzählen, dann weitermachen (bzw. schleife durchlaufen)
    x++ heißt: erst einmal durchgehen, danach hochzählen.

    Ist aber bei dir vollkommen egal, selbst wenn du es teilweise andersrum machst, würde bei diesem Beispiel das selbe Ergebnis rauskommen.

    Wenns falsch ist verbessert mich bitte ;) Aber mein Gedächnis drängt mir das gerade auf :P
  • Soweit bin ich auch gekommen. Aber das ganze mit VisualStudio in C++ kompiliert ergibt dann 80 und da komm ich nicht ganz dahinter.

    Was meinst du mit "erst hochzählen, dann weitermachen"? ++ inkrementiert eine Variable, aber scheinbar zu unterschiedlichen Zeitpunkten.
    Ich hätte vermutet, dass ++x den Wert inkrementiert, aber die Variable erst in der nächsten Zeile verändert und x++ das bereits in der aktuellen Zeile macht (oder andersherum) aber selbst dann käme ich auf ein anderes Ergebnis. Vielleicht liegt der Trick auch am += ?
  • F0kus schrieb:

    ++x heißt: Erst hochzählen, dann weitermachen (bzw. schleife durchlaufen)
    x++ heißt: erst einmal durchgehen, danach hochzählen.

    ich kann nur für Java sprechen, aber ich schätz mal, dass es bei c++ ähnlich ist:
    Bei den Schleifen passiert das gleiche wie auch wenn man die Operatoren normal verwendet. ++x bedeutet x wird um 1 erhöht und dann wird der rest der aktuellen Operation durchgeführt. x++ bedeutet hingegen, dass erst die restliche Operationen durchgeführt werden und erst danach wird x um 1 erhöht. Das bedeutet, wenn ich zuweisungen im gleichen Schritt mache, bleibt das x++ völlig ohne Wirkung...
    Beispiel:

    Quellcode

    1. int x = 5;
    2. x = x++;
    3. System.out.println(x);

    hier ist am Ende die Ausgabe trotzdem 5 obwohl zwischendrin ja x++ vorkommt. Das liegt daran, dass in der 2. Zeile dem x der alte x-Wert zugewiesen wird und erst danach das jetzt alte x erhöht wird, was keine auswirkungen mehr hat

    daher hat in
    "x += ++x+x++;" das letzt ++ keine Auswirkung, man kann es also direkt weglassen... Beim Rest würd ich aber trotzdem sagen, dass 38 herauskommt. Denn zu allererst wird durch ++x das x um eins erhöht. Dies gilt aber für beide x auf der rechten Seite. Daher haben wir 13 + 13 und dann nochmal + 12 durch das +=
    Gut um am Ende wird das ergebnis noch verdoppelt, aber das is irgendwie nicht so spannend ;)
    Das deckt sich auch alles mit kurzen Tests, die ich schnell in Java durchgeführt hab... Jetzt muss das nurnoch alles auch auf C/C++ zutreffen ;) (oder um was es hier auch immer geht)

    Edit:
    Soweit bin ich auch gekommen. Aber das ganze mit VisualStudio in C++ kompiliert ergibt dann 80 und da komm ich nicht ganz dahinter.
    Ok, wenn bei dir da 80 rauskommt, ist es wohl wirklich anders in C++
  • Rondrer schrieb:

    Ok, wenn bei dir da 80 rauskommt, ist es wohl wirklich anders in C++
    Sieht so aus. Nur egal wie man es rechnet, es kommt nie 80 bzw. für nur die eine Zeile 40 raus.
    Selbst wenn ich davon ausgehe, dass sowohl ++x als auch x++ die Variable x unmittelbar verändert würde da 14 + (14 + 13) herauskommen.
    Und wenn nur ++x die Variable unmittelbar verändern würde, käme da auch nur 13 + (13 + 12) heraus.
    Gehe ich davon aus, dass x++ (oder alternativ auch ++x) den Wert inkrementiert, die Variable aber nicht unmittelbar verändert: 13 + (13 + 13).

    Aber ich bin ja schon froh, dass es mir da nicht alleine so geht :P
  • ich glaub ich bin der Sache auf der Spur ;) Hab mal mit dem GCC-C++ compiler ein paar tests gemacht...
    erstmal ist ja

    Quellcode

    1. x += ++x+x++;

    nichts anderes als

    Quellcode

    1. x = x ++x+x++;

    ich kanns nur damit besser erklären.
    Es scheint so als würde das eine ++x alle 3 x um eins erhöhen. also sind wir bei 13+13+13.
    dann haben wir nurnoch das x++ was einfach das x nochmal um 1 erhöht, nachdem der komplette ausdruck ausgewertet ist. Dann kommen wir auf die 40 ;)

    bis jetzt hat die theorie auch den verschiedensten Tests standgehalten :D
  • Also ++x heißt pre increment, x++ post increment und sind unäre Operatoren. Der Unterschied von beiden lässt sich am besten durch eine Funktion erklären:

    Quellcode

    1. int postIncrement(int* x) {
    2. x = x+1;
    3. return x-1;
    4. }
    5. int preIncrement(int* x) {
    6. x=x+1;
    7. return x;
    8. }


    Die Operatoren macht also zwei Sachen: Erstens verändert sie den Wert von x und zweitens geben sie einen Wert zurück. preIncrement gibt den neuen Wert von x zurück (also mit dem dazuaddierten) und postIncrement den ursprünglichen Wert (ohne den dazuaddierten).
    Bei deiner Rechnung wird x mit 12 initialisiert. Dann gucken wir uns den Ausdruck mal an:

    x += ++x+x++;
    ist äquivalent zu:
    x =x+ ++x+x++;

    Man kann erkennen dass hier die Auswertungsreihenfolge eine Rolle spielt. Die meisten C-Compiler werten glaube ich von rechts nach links aus (ist soweit ich weiß duch den ANSI-Standard nicht festgelegt und darf von jedem Compiler gemacht werden wie er will).Da die Addition kommutativ ist, ist es aus mathematischen Gesichtspunkten ja auch egal, das Problem hier ist nur das x während der Berechnung verändert wird und deswegen die Reihenfolge nicht egal ist. Von rechts nach links sähe das dann so aus:

    Quellcode

    1. x =x+ ++x+x++; //x ist 12
    2. x =x+ ++x+12; //x ist jetzt 13
    3. x =x+ 14+12; //x ist jetzt 14
    4. x= 14+ 14+12; //Der Ausdruck kann berechnet werden und bekommt den Wert 40


    Wenn der Compiler von Links nach rechts auswertet (ich glaube Java macht das so), kommt folgendes dabei raus:

    Quellcode

    1. x =x+ ++x+x++; //x ist 12
    2. x =12+ ++x+x++; //x hat noch den Wert 12
    3. x =12+ 13+x++; //x ist jetzt 13
    4. x =12+ 13+13; //x ist jetzt 14, ist aber nicht mehr relevant
    5. x =12+ 13+13; //Der Ausdruck kann berechnet werden und bekommt den Wert 38

    Wie man sieht, sollte man mit destruktiven Operatoren in komplexeren Ausdrücken höllisch aufpassen.
    ~ mfg SeBa

    Ich beantworte keine PMs zu Computer-/Programmierproblemen. Bitte wendet euch an das entsprechende Forum.

    [Blockierte Grafik: http://i.creativecommons.org/l/by-sa/3.0/80x15.png]
  • nee, das stimmt so nicht. Die Compiler werten nicht streng der Reihenfolge nach aus (bei unterschiedlichen Operatoren). Sie beherrschen ja auch "Punkt-vor-Strich".
    Von den hier benutzen Operatoren hat der Post-Inrement die niedrigste Priorität, wird also immer als letztes ausgewertet. Das merkt man daran, dass wenn man in dem Ausdruck das "++" am Ende einfach weglässt, kommt als Ergebnis 39 raus. Man kann auch die Reihenfolge komplett verändern, ohne dass sich daran etwas ändert:

    Quellcode

    1. x += x++ + ++x;

    liefert das gleiche Ergebnis wie

    Quellcode

    1. x += ++x+x++;


    und auch hier, kann ich den Post-increment Operator weglassen und es liefert 39

    Quellcode

    1. x += x + ++x;
  • Sagen wir, "nee, das stimmt nicht so ganz". Ich hab nach dem verfassen des Beitrages selber auch nochmal recherchiert, in C haben preInkrement und postInkrement tatsächlich eine unterschiedliche Priorität, die muss der Compiler natürlich berücksichtigen. Mir war das aber entfallen. Bei Java allerdings nicht und er versucht wirklich von Links nach rechts auszuwerten, siehe hier, also stimmt der Teil schonmal (auch die 38, habs ausprobiert :D). In C dachte ich wäre es ebenfalls so, allerdings haben postfix-Operatoren eine höhere Priorität. Dadurch ist der Ausdruck natürlich eindeutig und muss immer so abgearbeitet werden, wie ich es beschrieben habe. Andere Auswertungen würden den C-Standard verletzen und wären illegal.
    Trotzdem bleiben in Ausdrücken mit Operatoren gleicher Priorität dem Compiler manchmal Wahlmöglichkeiten. Beim GCC habe ich es grade ausprobiert, er wertet zumindest bei Funktionsaufrufen wohl von rechts nach links aus:

    Quellcode

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. int main(void) {
    4. int x=1;
    5. printf ("x zum ersten: %d\nx zum zweiten: %d\n", x++, x++);
    6. return EXIT_SUCCESS;
    7. }


    Quellcode

    1. x zum ersten: 2
    2. x zum zweiten: 1
    ~ mfg SeBa

    Ich beantworte keine PMs zu Computer-/Programmierproblemen. Bitte wendet euch an das entsprechende Forum.

    [Blockierte Grafik: http://i.creativecommons.org/l/by-sa/3.0/80x15.png]