Kleines Verständnis Problem
-
Hallo,
ich verstehe grade nicht ganz wie in der Konsole die Ergebnisse zustande kommen, der Code kommt aus einer Altklausur. Ich habe noch Kommentare noch hinzugefügt.1.Code
for(int i=1; i<10; i=i<<1){ char a=i+64; cout <<a; }
// i=1 -> a=65->A
Wie kann man hier den Interationsschritt verstehen i=i<<1, bzw. wie kommt man hier auf das Ergebnis ABDH?
2.Code
int d=3,e=4; d+= e++ % 2; // e++ -> e=5; e%2=1; d=d+1->d=4 d= --d*e; // (d-1)*e=3*5=15 cout <<endl<<d;
Wieso ist d=10 welche Reihenfolge wird hier zuerst berechnet?
VG
-
@Florian200 sagte in Kleines Verständnis Problem:
1.Code
for(int i=1; i<10; i=i<<1){ char a=i+64; cout <<a; }
// i=1 -> a=65->A
Wie kann man hier den Interationsschritt verstehen i=i<<1, bzw. wie kommt man hier auf das Ergebnis ABDH?
Mit dem Ausdruck
i << 1
werden alle Bits ini
um eine Stelle nach links verschoben, und das am weitesten rechts stehende Bit auf0
gesetzt. Effektiv ist das eine Multiplikation mit2
, der Basis im Binärsystem. Analog dazu wäre in unserem bekannten 10er-System alle Ziffern um eine Stelle nach links zu verschieben und rechts eine0
aufzufüllen. Das ist dann äquivalent zu einer Multiplikation mit10
, der Basis des Dezimalsystems.i
nimmt in der Schleife also die Werte1
,2
,4
und8
an. Durch Addition von 64 erhält man folglich die ASCII-Werte fürA
,B
,D
undH
, die du entsprechend in der Ausgabe siehst.2.Code
int d=3,e=4; d+= e++ % 2; // e++ -> e=5; e%2=1; d=d+1->d=4 d= --d*e; // (d-1)*e=3*5=15 cout <<endl<<d;
Wieso ist d=10 welche Reihenfolge wird hier zuerst berechnet?
Bei
e++
handelt es sich um ein Post-Inkrement. Der Ausdruck wird zuerst ausgewertet und erst anschliessend wird1
hinzuaddiert. Daher iste++ % 2 = 4 % 2 = 0
und erst nach dieser Zeile erhälte
den Wert5
. Somit ist dann(d - 1) * e = 2 * 5 = 10
. Anders verhielte es sich bei einem Prä-Inkrement++e
, da würde dann tatsächlich15
herauskommen. Wenn du den Code in ausführbarer Form vorliegen hast, kannst du das ja mal ausprobieren.
-
<<
ist der Linksschiebeoperator, der verschiebt einen Wert im Binärsystem um die angegebene Stellenzahl nach links und füllt den Rest mit Nullen auf. Beispielsweise würde aus binär 1001 (=9), wenn man es um 3 nach links verschiebt 1001000 (=36). Und das wird hier halt mit Startwert 1 und einer Verschiebung um 1 gemacht, man bekommt also (binär) 1 (=1), 10 (=2), 100 (=4), 1000 (=8), 10000 (=16). Dabei wird dann bei der 16 abgebrochen, da 16 nicht mehr kleiner als 10 ist. Es gäbe noch viel mehr über den Operator zu erzählen, aber das kannst du selber nachlesen.d= --d*e;
ist undefiniert, und da kann alles mögliche rauskommen. Und zwar wirklich alles. Selbst Freitag, gelb, oder Zöglfrex.
-
@SeppJ sagte in Kleines Verständnis Problem:
d= --d*e;
ist undefiniert, und da kann alles mögliche rauskommen. Und zwar wirklich alles. Selbst Freitag, gelb, oder Zöglfrex.
Oh ja, in der Tat (schäm! )! Auch wenn meine Erklärung durchaus korrekt beschreibt, was dieser spezielle Compiler an der Stelle anstatt
Zöglfrex
macht (also wie die10
zustande kommt), so ist das gemäss Standard tatsächlich UB
-
Sofern man das Pech hat, dass nichts absurdes wie Zöglfrex herauskommt (wodurch man den Fehler hoffentlich bemerken würde), so ist aber immerhin auch 9 ein ebenso vertretbares Ergebnis wie 10. Schließlich kann man die Zeile ebensogut auch als "d = (3-1) * 5, dann Dekrement" verstehen.
-
Okay super, danke habs verstanden
-
@SeppJ sagte in Kleines Verständnis Problem:
Sofern man das Pech hat, dass nichts absurdes wie Zöglfrex herauskommt (wodurch man den Fehler hoffentlich bemerken würde), so ist aber immerhin auch 9 ein ebenso vertretbares Ergebnis wie 10. Schließlich kann man die Zeile ebensogut auch als "d = (3-1) * 5, dann Dekrement" verstehen.
Ich glaube aber auch eher, dass das primäre Verständnisproblem von @Florian200 beim Postinkrement lag und die Frage auch aufgekommen wäre, wenn es in Zeile 3 kein UB gäbe. Insofern ganz gut, das nochmal etwas aufgedröselt zu haben. Dennoch richtig auf das UB hinzuweisen und bei einer Klausur mit fähigen Dozenten sollte "weil UB" ebenfalls eine korrekte Antwort sein
-
Oder vielleicht doch noch was. Wie ist d=--d*e; undefiniert. Die Zahlenwerte sind doch gegeben ?
-
@Florian200 sagte in Kleines Verständnis Problem:
Oder vielleicht doch noch was. Wie ist d=--d*e; undefiniert. Die Zahlenwerte sind doch gegeben ?
Da sind zwei gleichzeitige Änderungen an d, nämlich einerseits "d gleich das was rechts vom = steht" und andererseits "verringere den Wert von d um 1". Die Reihenfolge davon ist nicht definiert, und das Ergebnis ist daher undefiniert. Es ist zwar klar, dass rechrs vom
=
der Wert 10 steht, aber nicht ob das Dekrement vor oder nach der Zuweisung passiert (also ob d hinterher 10 oder 9 ist). Und bei C++ gilt, dass solche undefinierten Dinge dazu führen, dass da kompletter Unfug rauskommen darf, nicht bloß eine der beiden Möglichkeiten, die hier zur Auswahl stehen. Daher darf eben auch Zöglfrex rauskommen. Oder meinetwegen die Festplatte formatiert werden, die Spülmaschine frisst den Hund, oder sonstwas. Praktisch wird es natürlich meistens 9 oder 10 sein, aber das hilft dir ja erstens nix, wenn du es nicht weißt, und zweitens wird dir dann wenn es wirklich drauf ankommt, dass kein kompletter Unsinn herauskommt, doch kompletter Unsinn herauskommen.Was dir vielleicht nicht so klar ist:
--d
ist nicht das gleiche wied-1
. Es mag zwar den gleichen numerischen Wert haben wied-1
aber es bedeutet eben auch zusätzlich den Nebeneffekt, die Variabled
um den Wert 1 zu verringern. Da kann und müsste man jetzt eigentlich noch viel mehr zu schreiben, aber du kannst dir auch die einfache Regel merken, dass du nicht mehrere Änderungen an der gleichen Variable machst zwischen zwei Semikolons. Und halt beachtest, dass die++
und--
Operatoren eben auch eine Änderung sind.
Wenn du mehr lesen möchtest, findest du hier einen Aufsatz: https://stackoverflow.com/a/4176333/11208562
-
Hallo SeppJ,
das dachte ich bisher auch, aber seit C++17 ist das eindeutig definiert: C++ Standard: 7.6.19 Assignment and compound assignment operators
Hier noch der Reddit-Post, wo ich genauso wie du geantwortet hatte: I thought I understood postfix increment operator
-
Ja, das steht ja auch in dem von mir verlinkten Aufsatz. Muss aber zugeben, dass mir das bisher nicht bewusst war -- ich schreibe ja schließlich nicht solche Ausdrücke und werde es auch in Zukunft nicht tun.
-
@SeppJ sagte in Kleines Verständnis Problem:
die Spülmaschine frisst den Hund